Python's SSL module (built on OpenSSL) would improperly handle null bytes in 
the SubjectAltName field domain name, deferring the validation code to other 
fields. This has been patched on their end, but may be indicative of a bug in 
OpenSSL. The unpatched code used OpenSSL's GENERAL_NAME_print() to retrieve the 
SubjectAltName, which would truncate the domain name in the event of a null 
byte. The function certainly shouldn't truncate the domain name (perhaps the 
BIO_printf()'s with %s should be replaced with something more robust?). 
However, I'm uncertain as to how appropriate is this use of 
GENERAL_NAME_print(). Is the intent of this function to be used for purposes 
like this, or is it intended more for human-readable output, or something else 
entirely?

This issue has also appeared in other uses, including several Mozilla products.

Thanks,
Andrew Felsher
[email protected]


http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-4238
CVE-2013-4238: The ssl.match_hostname function in the SSL module in Python 2.6 
through 3.4 does not properly handle a '\0' character in a domain name in the 
Subject Alternative Name field of an X.509 certificate, which allows 
man-in-the-middle attackers to spoof arbitrary SSL servers via a crafted 
certificate issued by a legitimate Certification Authority, a related issue to 
CVE-2009-2408.


http://bugs.python.org/issue18709
Python Issue18709: SSL module fails to handle NULL bytes inside subjectAltNames 
general names (CVE-2013-4238)


GENERAL_NAME_print() is identical in 0.9.8 and 1.0.1:
               int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
               {
                              unsigned char *p;
                              int i;
                              switch (gen->type)
                              {
                                             case GEN_OTHERNAME:
                                             BIO_printf(out, 
"othername:<unsupported>");
                                             break;

                                             case GEN_X400:
                                             BIO_printf(out, 
"X400Name:<unsupported>");
                                             break;

                                             case GEN_EDIPARTY:
                                             /* Maybe fix this: it is supported 
now */
                                             BIO_printf(out, 
"EdiPartyName:<unsupported>");
                                             break;

                                             case GEN_EMAIL:
                                             BIO_printf(out, 
"email:%s",gen->d.ia5->data);
                                             break;

                                             case GEN_DNS:
                                             BIO_printf(out, 
"DNS:%s",gen->d.ia5->data);
                                             break;

                                             case GEN_URI:
                                             BIO_printf(out, 
"URI:%s",gen->d.ia5->data);
                                             break;

                                             case GEN_DIRNAME:
                                             BIO_printf(out, "DirName: ");
                                             X509_NAME_print_ex(out, 
gen->d.dirn, 0, XN_FLAG_ONELINE);
                                             break;

                                             case GEN_IPADD:
                                             p = gen->d.ip->data;
                                             if(gen->d.ip->length == 4)
                                                            BIO_printf(out, "IP 
Address:%d.%d.%d.%d",
                                                                                
                         p[0], p[1], p[2], p[3]);
                                             else if(gen->d.ip->length == 16)
                                                            {
                                                            BIO_printf(out, "IP 
Address");
                                                            for (i = 0; i < 8; 
i++)
                                                                           {
                                                                           
BIO_printf(out, ":%X", p[0] << 8 | p[1]);
                                                                           p += 
2;
                                                                           }
                                                            BIO_puts(out, "\n");
                                                            }
                                             else
                                                            {
                                                            BIO_printf(out,"IP 
Address:<invalid>");
                                                            break;
                                                            }
                                             break;

                                             case GEN_RID:
                                             BIO_printf(out, "Registered ID");
                                             i2a_ASN1_OBJECT(out, gen->d.rid);
                                             break;
                              }
                              return 1;
               }

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [email protected]
Automated List Manager                           [email protected]

Reply via email to