Issue #18709: Fix CVE-2013-4238. The SSL module now handles NULL bytes
inside subjectAltName correctly. Formerly the module has used OpenSSL's
GENERAL_NAME_print() function to get the string represention of ASN.1
strings for ``rfc822Name`` (email), ``dNSName`` (DNS) and
``uniformResourceIdentifier`` (URI).
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index 5c8df8b..d90e46d 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -52,6 +52,7 @@
 WRONGCERT = data_file("XXXnonexisting.pem")
 BADKEY = data_file("badkey.pem")
 NOKIACERT = data_file("nokia.pem")
+NULLBYTECERT = data_file("nullbytecert.pem")
 
 
 def handle_error(prefix):
@@ -140,6 +141,27 @@
                           ('DNS', 'projects.forum.nokia.com'))
                         )
 
+    def test_parse_cert_CVE_2013_4073(self):
+        p = ssl._ssl._test_decode_cert(NULLBYTECERT)
+        if support.verbose:
+            sys.stdout.write("\n" + pprint.pformat(p) + "\n")
+        subject = ((('countryName', 'US'),),
+                   (('stateOrProvinceName', 'Oregon'),),
+                   (('localityName', 'Beaverton'),),
+                   (('organizationName', 'Python Software Foundation'),),
+                   (('organizationalUnitName', 'Python Core Development'),),
+                   (('commonName', 'null.python.org\x00example.org'),),
+                   (('emailAddress', 'python-dev@python.org'),))
+        self.assertEqual(p['subject'], subject)
+        self.assertEqual(p['issuer'], subject)
+        self.assertEqual(p['subjectAltName'],
+                         (('DNS', 'altnull.python.org\x00example.com'),
+                         ('email', 'null@python.org\x00user@example.org'),
+                         ('URI', 'http://null.python.org\x00http://example.org'),
+                         ('IP Address', '192.0.2.1'),
+                         ('IP Address', '2001:DB8:0:0:0:0:0:1\n'))
+                        )
+
     def test_DER_to_PEM(self):
         with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
             pem = f.read()
@@ -271,6 +293,13 @@
         fail(cert, 'foo.a.com')
         fail(cert, 'bar.foo.com')
 
+        # NULL bytes are bad, CVE-2013-4073
+        cert = {'subject': ((('commonName',
+                              'null.python.org\x00example.org'),),)}
+        ok(cert, 'null.python.org\x00example.org') # or raise an error?
+        fail(cert, 'example.org')
+        fail(cert, 'null.python.org')
+
         # Slightly fake real-world example
         cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT',
                 'subject': ((('commonName', 'linuxfrz.org'),),),