X509Ext str/unicode fixes
diff --git a/OpenSSL/crypto/pkcs12.c b/OpenSSL/crypto/pkcs12.c
index adb0c8d..81d6074 100644
--- a/OpenSSL/crypto/pkcs12.c
+++ b/OpenSSL/crypto/pkcs12.c
@@ -367,7 +367,7 @@
          *  certificate. */
         alias_str = X509_alias_get0(cert, &alias_len);
         if (alias_str) {
-            self->friendlyname = Py_BuildValue(FMT("#"), alias_str, alias_len);
+            self->friendlyname = Py_BuildValue(BYTESTRING_FMT "#", alias_str, alias_len);
             if (!self->friendlyname) {
                 /*
                  * XXX Untested
diff --git a/OpenSSL/crypto/revoked.c b/OpenSSL/crypto/revoked.c
index e043330..5a9e713 100644
--- a/OpenSSL/crypto/revoked.c
+++ b/OpenSSL/crypto/revoked.c
@@ -231,7 +231,7 @@
 static PyObject*
 crypto_Revoked_set_rev_date(crypto_RevokedObj *self, PyObject *args) {
     return _set_asn1_time(
-        FMT(":set_rev_date"), self->revoked->revocationDate, args);
+        BYTESTRING_FMT ":set_rev_date", self->revoked->revocationDate, args);
 }
 
 /* The integer is converted to an upper-case hex string
@@ -307,7 +307,7 @@
     BIGNUM *serial = NULL;
     ASN1_INTEGER *tmpser = NULL;
 
-    if (!PyArg_ParseTupleAndKeywords(args, keywds, FMT(":set_serial"),
+    if (!PyArg_ParseTupleAndKeywords(args, keywds, BYTESTRING_FMT ":set_serial",
                                      kwlist, &hex_str)) {
         return NULL;
     }
diff --git a/OpenSSL/crypto/x509.c b/OpenSSL/crypto/x509.c
index 3cd3145..b00ad3c 100644
--- a/OpenSSL/crypto/x509.c
+++ b/OpenSSL/crypto/x509.c
@@ -369,7 +369,8 @@
 crypto_X509_set_notBefore(crypto_X509Obj *self, PyObject *args)
 {
 	return _set_asn1_time(
-            FMT(":set_notBefore"), X509_get_notBefore(self->x509), args);
+            BYTESTRING_FMT ":set_notBefore",
+            X509_get_notBefore(self->x509), args);
 }
 
 static char crypto_X509_set_notAfter_doc[] = "\n\
@@ -388,7 +389,8 @@
 crypto_X509_set_notAfter(crypto_X509Obj *self, PyObject *args)
 {
 	return _set_asn1_time(
-            FMT(":set_notAfter"), X509_get_notAfter(self->x509), args);
+            BYTESTRING_FMT ":set_notAfter",
+            X509_get_notAfter(self->x509), args);
 }
 
 PyObject*
diff --git a/OpenSSL/crypto/x509ext.c b/OpenSSL/crypto/x509ext.c
index 28e8805..d629732 100644
--- a/OpenSSL/crypto/x509ext.c
+++ b/OpenSSL/crypto/x509ext.c
@@ -186,10 +186,12 @@
     static char *kwlist[] = {"type_name", "critical", "value", "subject",
                              "issuer", NULL};
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sis|O!O!:X509Extension",
-                                     kwlist, &type_name, &critical, &value,
-                                     &crypto_X509_Type, &subject,
-                                     &crypto_X509_Type, &issuer )) {
+    if (!PyArg_ParseTupleAndKeywords(
+            args, kwargs,
+            BYTESTRING_FMT "i" BYTESTRING_FMT "|O!O!:X509Extension",
+            kwlist, &type_name, &critical, &value,
+            &crypto_X509_Type, &subject,
+            &crypto_X509_Type, &issuer )) {
         return NULL;
     }
 
diff --git a/OpenSSL/py3k.h b/OpenSSL/py3k.h
index 2827f1f..d64817d 100644
--- a/OpenSSL/py3k.h
+++ b/OpenSSL/py3k.h
@@ -19,7 +19,7 @@
 
 #define PyOpenSSL_MODRETURN(module) { return module; }
 
-#define FMT(name) ("y" name)
+#define BYTESTRING_FMT "y"
 
 #else /* (PY_VERSION_HEX >= 0x03000000) */
 
@@ -47,7 +47,7 @@
 void \
 init##name(void)
 
-#define FMT(name) ("s" name)
+#define BYTESTRING_FMT "s"
 
 #endif /* (PY_VERSION_HEX >= 0x03000000) */
 
diff --git a/OpenSSL/test/test_crypto.py b/OpenSSL/test/test_crypto.py
index d2a8c1e..facc305 100644
--- a/OpenSSL/test/test_crypto.py
+++ b/OpenSSL/test/test_crypto.py
@@ -273,8 +273,8 @@
         self.subject.commonName = self.req.get_subject().commonName
         self.x509.set_issuer(self.subject)
         self.x509.set_pubkey(self.pkey)
-        now = datetime.now().strftime("%Y%m%d%H%M%SZ")
-        expire  = (datetime.now() + timedelta(days=100)).strftime("%Y%m%d%H%M%SZ")
+        now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
+        expire  = b((datetime.now() + timedelta(days=100)).strftime("%Y%m%d%H%M%SZ"))
         self.x509.set_notBefore(now)
         self.x509.set_notAfter(expire)
 
@@ -287,7 +287,7 @@
         # This isn't necessarily the best string representation.  Perhaps it
         # will be changed/improved in the future.
         self.assertEquals(
-            str(X509Extension('basicConstraints', True, 'CA:false')),
+            str(X509Extension(b('basicConstraints'), True, b('CA:false'))),
             'CA:FALSE')
 
 
@@ -298,7 +298,8 @@
         """
         self.assertIdentical(X509Extension, X509ExtensionType)
         self.assertConsistentType(
-            X509Extension, 'X509Extension', 'basicConstraints', True, 'CA:true')
+            X509Extension,
+            'X509Extension', b('basicConstraints'), True, b('CA:true'))
 
 
     def test_construction(self):
@@ -306,13 +307,14 @@
         L{X509Extension} accepts an extension type name, a critical flag,
         and an extension value and returns an L{X509ExtensionType} instance.
         """
-        basic = X509Extension('basicConstraints', True, 'CA:true')
+        basic = X509Extension(b('basicConstraints'), True, b('CA:true'))
         self.assertTrue(
             isinstance(basic, X509ExtensionType),
             "%r is of type %r, should be %r" % (
                 basic, type(basic), X509ExtensionType))
 
-        comment = X509Extension('nsComment', False, 'pyOpenSSL unit test')
+        comment = X509Extension(
+            b('nsComment'), False, b('pyOpenSSL unit test'))
         self.assertTrue(
             isinstance(comment, X509ExtensionType),
             "%r is of type %r, should be %r" % (
@@ -325,17 +327,17 @@
         name or value.
         """
         self.assertRaises(
-            Error, X509Extension, 'thisIsMadeUp', False, 'hi')
+            Error, X509Extension, b('thisIsMadeUp'), False, b('hi'))
         self.assertRaises(
-            Error, X509Extension, 'basicConstraints', False, 'blah blah')
+            Error, X509Extension, b('basicConstraints'), False, b('blah blah'))
 
         # Exercise a weird one (an extension which uses the r2i method).  This
         # exercises the codepath that requires a non-NULL ctx to be passed to
         # X509V3_EXT_nconf.  It can't work now because we provide no
         # configuration database.  It might be made to work in the future.
         self.assertRaises(
-            Error, X509Extension, 'proxyCertInfo', True,
-            'language:id-ppl-anyLanguage,pathlen:1,policy:text:AB')
+            Error, X509Extension, b('proxyCertInfo'), True,
+            b('language:id-ppl-anyLanguage,pathlen:1,policy:text:AB'))
 
 
     def test_get_critical(self):
@@ -343,9 +345,9 @@
         L{X509ExtensionType.get_critical} returns the value of the
         extension's critical flag.
         """
-        ext = X509Extension('basicConstraints', True, 'CA:true')
+        ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
         self.assertTrue(ext.get_critical())
-        ext = X509Extension('basicConstraints', False, 'CA:true')
+        ext = X509Extension(b('basicConstraints'), False, b('CA:true'))
         self.assertFalse(ext.get_critical())
 
 
@@ -354,10 +356,10 @@
         L{X509ExtensionType.get_short_name} returns a string giving the short
         type name of the extension.
         """
-        ext = X509Extension('basicConstraints', True, 'CA:true')
-        self.assertEqual(ext.get_short_name(), 'basicConstraints')
-        ext = X509Extension('nsComment', True, 'foo bar')
-        self.assertEqual(ext.get_short_name(), 'nsComment')
+        ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
+        self.assertEqual(ext.get_short_name(), b('basicConstraints'))
+        ext = X509Extension(b('nsComment'), True, b('foo bar'))
+        self.assertEqual(ext.get_short_name(), b('nsComment'))
 
 
     def test_unused_subject(self):
@@ -365,13 +367,14 @@
         The C{subject} parameter to L{X509Extension} may be provided for an
         extension which does not use it and is ignored in this case.
         """
-        ext1 = X509Extension('basicConstraints', False, 'CA:TRUE', subject=self.x509)
+        ext1 = X509Extension(
+            b('basicConstraints'), False, b('CA:TRUE'), subject=self.x509)
         self.x509.add_extensions([ext1])
         self.x509.sign(self.pkey, 'sha1')
         # This is a little lame.  Can we think of a better way?
         text = dump_certificate(FILETYPE_TEXT, self.x509)
-        self.assertTrue('X509v3 Basic Constraints:' in text)
-        self.assertTrue('CA:TRUE' in text)
+        self.assertTrue(b('X509v3 Basic Constraints:') in text)
+        self.assertTrue(b('CA:TRUE') in text)
 
 
     def test_subject(self):
@@ -379,11 +382,12 @@
         If an extension requires a subject, the C{subject} parameter to
         L{X509Extension} provides its value.
         """
-        ext3 = X509Extension('subjectKeyIdentifier', False, 'hash', subject=self.x509)
+        ext3 = X509Extension(
+            b('subjectKeyIdentifier'), False, b('hash'), subject=self.x509)
         self.x509.add_extensions([ext3])
         self.x509.sign(self.pkey, 'sha1')
         text = dump_certificate(FILETYPE_TEXT, self.x509)
-        self.assertTrue('X509v3 Subject Key Identifier:' in text)
+        self.assertTrue(b('X509v3 Subject Key Identifier:') in text)
 
 
     def test_missing_subject(self):
@@ -392,7 +396,7 @@
         given no value, something happens.
         """
         self.assertRaises(
-            Error, X509Extension, 'subjectKeyIdentifier', False, 'hash')
+            Error, X509Extension, b('subjectKeyIdentifier'), False, b('hash'))
 
 
     def test_invalid_subject(self):
@@ -412,12 +416,13 @@
         The C{issuer} parameter to L{X509Extension} may be provided for an
         extension which does not use it and is ignored in this case.
         """
-        ext1 = X509Extension('basicConstraints', False, 'CA:TRUE', issuer=self.x509)
+        ext1 = X509Extension(
+            b('basicConstraints'), False, b('CA:TRUE'), issuer=self.x509)
         self.x509.add_extensions([ext1])
         self.x509.sign(self.pkey, 'sha1')
         text = dump_certificate(FILETYPE_TEXT, self.x509)
-        self.assertTrue('X509v3 Basic Constraints:' in text)
-        self.assertTrue('CA:TRUE' in text)
+        self.assertTrue(b('X509v3 Basic Constraints:') in text)
+        self.assertTrue(b('CA:TRUE') in text)
 
 
     def test_issuer(self):
@@ -426,13 +431,13 @@
         L{X509Extension} provides its value.
         """
         ext2 = X509Extension(
-            'authorityKeyIdentifier', False, 'issuer:always',
+            b('authorityKeyIdentifier'), False, b('issuer:always'),
             issuer=self.x509)
         self.x509.add_extensions([ext2])
         self.x509.sign(self.pkey, 'sha1')
         text = dump_certificate(FILETYPE_TEXT, self.x509)
-        self.assertTrue('X509v3 Authority Key Identifier:' in text)
-        self.assertTrue('DirName:/CN=Yoda root CA' in text)
+        self.assertTrue(b('X509v3 Authority Key Identifier:') in text)
+        self.assertTrue(b('DirName:/CN=Yoda root CA') in text)
 
 
     def test_missing_issuer(self):
@@ -443,7 +448,8 @@
         self.assertRaises(
             Error,
             X509Extension,
-            'authorityKeyIdentifier', False, 'keyid:always,issuer:always')
+            b('authorityKeyIdentifier'), False,
+            b('keyid:always,issuer:always'))
 
 
     def test_invalid_issuer(self):
@@ -576,11 +582,11 @@
     def _x509name(self, **attrs):
         # XXX There's no other way to get a new X509Name yet.
         name = X509().get_subject()
-        attrs = attrs.items()
+        attrs = list(attrs.items())
         # Make the order stable - order matters!
-        def compare(attr1, attr2):
-            return cmp(attr1[1], attr2[1])
-        attrs.sort(compare)
+        def key(attr):
+            return attr[1]
+        attrs.sort(key=key)
         for k, v in attrs:
             setattr(name, k, v)
         return name