components/python/pyopenssl/patches/1_CVE-2013-4073.patch
changeset 7579 8b703bbe2bba
parent 7578 0d6f61408e89
child 7580 d8438d87f127
equal deleted inserted replaced
7578:0d6f61408e89 7579:8b703bbe2bba
     1 #
       
     2 # This patch contains the fixes for CVE-2013-4073 (NULL bytes in subjectAltName
       
     3 # not correctly interpreted).
       
     4 # The patch was taken from:
       
     5 # https://code.launchpad.net/~heimes/pyopenssl/pyopenssl/+merge/179673 
       
     6 # and modified to fit the the 0.13 release code (original fix was based off tip
       
     7 # code in pyopenssl repo).
       
     8 #
       
     9 --- pyOpenSSL-0.13/ChangeLog	2011-09-02 08:46:13.000000000 -0700
       
    10 +++ pyOpenSSL-0.13/ChangeLog	2013-08-26 14:40:43.941191227 -0700
       
    11 @@ -1,3 +1,9 @@
       
    12 +2013-08-11 Christian Heimes <[email protected]>
       
    13 +
       
    14 +	* OpenSSL/crypto/x509ext.c: Fix handling of NULL bytes inside
       
    15 +	  subjectAltName general names, CVE-2013-4073.
       
    16 +	* OpenSSL/crypto/x509.c: Fix memory leak in get_extension().
       
    17 +
       
    18  2011-09-02  Jean-Paul Calderone  <[email protected]>
       
    19  
       
    20  	* Release 0.13
       
    21 --- pyOpenSSL-0.13/OpenSSL/crypto/x509.c	2011-09-02 08:46:13.000000000 -0700
       
    22 +++ pyOpenSSL-0.13/OpenSSL/crypto/x509.c	2013-08-26 14:41:34.379545946 -0700
       
    23 @@ -756,6 +756,7 @@
       
    24  
       
    25      extobj = PyObject_New(crypto_X509ExtensionObj, &crypto_X509Extension_Type);
       
    26      extobj->x509_extension = X509_EXTENSION_dup(ext);
       
    27 +    extobj->dealloc = 1;
       
    28  
       
    29      return (PyObject*)extobj;
       
    30  }
       
    31 --- pyOpenSSL-0.13/OpenSSL/crypto/x509ext.c	2011-09-02 08:46:13.000000000 -0700
       
    32 +++ pyOpenSSL-0.13/OpenSSL/crypto/x509ext.c	2013-08-26 14:53:08.501972021 -0700
       
    33 @@ -236,6 +236,75 @@
       
    34      PyObject_Del(self);
       
    35  }
       
    36  
       
    37 +
       
    38 +/* Special handling of subjectAltName, see CVE-2013-4073 */
       
    39 +
       
    40 +int
       
    41 +crypto_X509Extension_str_san(crypto_X509ExtensionObj *self, BIO *bio)
       
    42 +{
       
    43 +    GENERAL_NAMES *names;
       
    44 +    const X509V3_EXT_METHOD *method = NULL;
       
    45 +    long i, length, num;
       
    46 +    const unsigned char *p;
       
    47 +
       
    48 +    method = X509V3_EXT_get(self->x509_extension);
       
    49 +    if (method == NULL) {
       
    50 +        return -1;
       
    51 +    }
       
    52 +
       
    53 +    p = self->x509_extension->value->data;
       
    54 +    length = self->x509_extension->value->length;
       
    55 +    if (method->it) {
       
    56 +        names = (GENERAL_NAMES*)(ASN1_item_d2i(NULL, &p, length,
       
    57 +                                               ASN1_ITEM_ptr(method->it)));
       
    58 +    }
       
    59 +    else {
       
    60 +        names = (GENERAL_NAMES*)(method->d2i(NULL, &p, length));
       
    61 +    }
       
    62 +    if (names == NULL) {
       
    63 +        return -1;
       
    64 +    }
       
    65 +
       
    66 +    num = sk_GENERAL_NAME_num(names);
       
    67 +    for (i = 0; i < num; i++) {
       
    68 +            GENERAL_NAME *name;
       
    69 +            ASN1_STRING *as;
       
    70 +            name = sk_GENERAL_NAME_value(names, i);
       
    71 +            switch (name->type) {
       
    72 +                case GEN_EMAIL:
       
    73 +                    BIO_puts(bio, "email:");
       
    74 +                    as = name->d.rfc822Name;
       
    75 +                    BIO_write(bio, ASN1_STRING_data(as),
       
    76 +                              ASN1_STRING_length(as));
       
    77 +                    break;
       
    78 +                case GEN_DNS:
       
    79 +                    BIO_puts(bio, "DNS:");
       
    80 +                    as = name->d.dNSName;
       
    81 +                    BIO_write(bio, ASN1_STRING_data(as),
       
    82 +                              ASN1_STRING_length(as));
       
    83 +                    break;
       
    84 +                case GEN_URI:
       
    85 +                    BIO_puts(bio, "URI:");
       
    86 +                    as = name->d.uniformResourceIdentifier;
       
    87 +                    BIO_write(bio, ASN1_STRING_data(as),
       
    88 +                              ASN1_STRING_length(as));
       
    89 +                    break;
       
    90 +                default:
       
    91 +                    /* use builtin print for GEN_OTHERNAME, GEN_X400,
       
    92 +                     * GEN_EDIPARTY, GEN_DIRNAME, GEN_IPADD and GEN_RID
       
    93 +                     */
       
    94 +                    GENERAL_NAME_print(bio, name);
       
    95 +            }
       
    96 +            /* trailing ', ' except for last element */
       
    97 +            if (i < (num - 1)) {
       
    98 +                BIO_puts(bio, ", ");
       
    99 +            }
       
   100 +    }
       
   101 +    sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
       
   102 +
       
   103 +    return 0;
       
   104 +}
       
   105 +
       
   106  /*
       
   107   * Print a nice text representation of the certificate request.
       
   108   */
       
   109 @@ -247,7 +316,14 @@
       
   110      PyObject *str;
       
   111      BIO *bio = BIO_new(BIO_s_mem());
       
   112  
       
   113 -    if (!X509V3_EXT_print(bio, self->x509_extension, 0, 0))
       
   114 +    if (OBJ_obj2nid(self->x509_extension->object) == NID_subject_alt_name) {
       
   115 +        if (crypto_X509Extension_str_san(self, bio) == -1) {
       
   116 +            BIO_free(bio);
       
   117 +            exception_from_error_queue(crypto_Error);
       
   118 +            return NULL;
       
   119 +        }
       
   120 +    }
       
   121 +    else if (!X509V3_EXT_print(bio, self->x509_extension, 0, 0))
       
   122      {
       
   123          BIO_free(bio);
       
   124          exception_from_error_queue(crypto_Error);
       
   125 --- pyOpenSSL-0.13/OpenSSL/test/test_crypto.py	2011-09-02 08:46:13.000000000 -0700
       
   126 +++ pyOpenSSL-0.13/OpenSSL/test/test_crypto.py	2013-08-26 14:57:06.933614387 -0700
       
   127 @@ -265,6 +265,37 @@
       
   128  -----END RSA PRIVATE KEY-----
       
   129  """)
       
   130  
       
   131 +# certificate with NULL bytes in subjectAltName and common name
       
   132 +
       
   133 +nullbyte_san_PEM = b("""-----BEGIN CERTIFICATE-----
       
   134 +MIIE2DCCA8CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBxTELMAkGA1UEBhMCVVMx
       
   135 +DzANBgNVBAgMBk9yZWdvbjESMBAGA1UEBwwJQmVhdmVydG9uMSMwIQYDVQQKDBpQ
       
   136 +eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEgMB4GA1UECwwXUHl0aG9uIENvcmUg
       
   137 +RGV2ZWxvcG1lbnQxJDAiBgNVBAMMG251bGwucHl0aG9uLm9yZwBleGFtcGxlLm9y
       
   138 +ZzEkMCIGCSqGSIb3DQEJARYVcHl0aG9uLWRldkBweXRob24ub3JnMB4XDTEzMDgw
       
   139 +NzEzMTE1MloXDTEzMDgwNzEzMTI1MlowgcUxCzAJBgNVBAYTAlVTMQ8wDQYDVQQI
       
   140 +DAZPcmVnb24xEjAQBgNVBAcMCUJlYXZlcnRvbjEjMCEGA1UECgwaUHl0aG9uIFNv
       
   141 +ZnR3YXJlIEZvdW5kYXRpb24xIDAeBgNVBAsMF1B5dGhvbiBDb3JlIERldmVsb3Bt
       
   142 +ZW50MSQwIgYDVQQDDBtudWxsLnB5dGhvbi5vcmcAZXhhbXBsZS5vcmcxJDAiBgkq
       
   143 +hkiG9w0BCQEWFXB5dGhvbi1kZXZAcHl0aG9uLm9yZzCCASIwDQYJKoZIhvcNAQEB
       
   144 +BQADggEPADCCAQoCggEBALXq7cn7Rn1vO3aA3TrzA5QLp6bb7B3f/yN0CJ2XFj+j
       
   145 +pHs+Gw6WWSUDpybiiKnPec33BFawq3kyblnBMjBU61ioy5HwQqVkJ8vUVjGIUq3P
       
   146 +vX/wBmQfzCe4o4uM89gpHyUL9UYGG8oCRa17dgqcv7u5rg0Wq2B1rgY+nHwx3JIv
       
   147 +KRrgSwyRkGzpN8WQ1yrXlxWjgI9de0mPVDDUlywcWze1q2kwaEPTM3hLAmD1PESA
       
   148 +oY/n8A/RXoeeRs9i/Pm/DGUS8ZPINXk/yOzsR/XvvkTVroIeLZqfmFpnZeF0cHzL
       
   149 +08LODkVJJ9zjLdT7SA4vnne4FEbAxDbKAq5qkYzaL4UCAwEAAaOB0DCBzTAMBgNV
       
   150 +HRMBAf8EAjAAMB0GA1UdDgQWBBSIWlXAUv9hzVKjNQ/qWpwkOCL3XDALBgNVHQ8E
       
   151 +BAMCBeAwgZAGA1UdEQSBiDCBhYIeYWx0bnVsbC5weXRob24ub3JnAGV4YW1wbGUu
       
   152 +Y29tgSBudWxsQHB5dGhvbi5vcmcAdXNlckBleGFtcGxlLm9yZ4YpaHR0cDovL251
       
   153 +bGwucHl0aG9uLm9yZwBodHRwOi8vZXhhbXBsZS5vcmeHBMAAAgGHECABDbgAAAAA
       
   154 +AAAAAAAAAAEwDQYJKoZIhvcNAQEFBQADggEBAKxPRe99SaghcI6IWT7UNkJw9aO9
       
   155 +i9eo0Fj2MUqxpKbdb9noRDy2CnHWf7EIYZ1gznXPdwzSN4YCjV5d+Q9xtBaowT0j
       
   156 +HPERs1ZuytCNNJTmhyqZ8q6uzMLoht4IqH/FBfpvgaeC5tBTnTT0rD5A/olXeimk
       
   157 +kX4LxlEx5RAvpGB2zZVRGr6LobD9rVK91xuHYNIxxxfEGE8tCCWjp0+3ksri9SXx
       
   158 +VHWBnbM9YaL32u3hxm8sYB/Yb8WSBavJCWJJqRStVRHM1koZlJmXNx2BX4vPo6iW
       
   159 +RFEIPQsFZRLrtnCAiEhyT8bC2s/Njlu6ly9gtJZWSV46Q3ZjBL4q9sHKqZQ=
       
   160 +-----END CERTIFICATE-----""")
       
   161 +
       
   162  
       
   163  class X509ExtTests(TestCase):
       
   164      """
       
   165 @@ -1382,6 +1413,36 @@
       
   166          self.assertRaises(TypeError, cert.get_extension, "hello")
       
   167  
       
   168  
       
   169 +    def test_nullbyte_san(self):
       
   170 +        """
       
   171 +        Test correct handling of CN and SAN with NULL bytes
       
   172 +
       
   173 +        see CVE-2013-4073
       
   174 +        """
       
   175 +        cert = load_certificate(FILETYPE_PEM, nullbyte_san_PEM)
       
   176 +        subject = cert.get_subject()
       
   177 +        self.assertEqual(subject.CN, 'null.python.org\x00example.org')
       
   178 +        issuer = cert.get_issuer()
       
   179 +        self.assertEqual(issuer.CN, 'null.python.org\x00example.org')
       
   180 +
       
   181 +        ext = cert.get_extension(0)
       
   182 +        self.assertEqual(ext.get_short_name(), b('basicConstraints'))
       
   183 +
       
   184 +        ext = cert.get_extension(1)
       
   185 +        self.assertEqual(ext.get_short_name(), b('subjectKeyIdentifier'))
       
   186 +
       
   187 +        ext = cert.get_extension(2)
       
   188 +        self.assertEqual(ext.get_short_name(), b('keyUsage'))
       
   189 +
       
   190 +        ext = cert.get_extension(3)
       
   191 +        self.assertEqual(ext.get_short_name(), b('subjectAltName'))
       
   192 +        self.assertEqual(str(ext), 
       
   193 +            'DNS:altnull.python.org\x00example.com, '
       
   194 +            'email:[email protected]\[email protected], '
       
   195 +            'URI:http://null.python.org\x00http://example.org, '
       
   196 +            'IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n')
       
   197 +
       
   198 +
       
   199      def test_invalid_digest_algorithm(self):
       
   200          """
       
   201          L{X509.digest} raises L{ValueError} if called with an unrecognized hash