diff options
author | Christian Heimes <christian@cheimes.de> | 2013-08-16 22:54:47 (GMT) |
---|---|---|
committer | Christian Heimes <christian@cheimes.de> | 2013-08-16 22:54:47 (GMT) |
commit | 824f7f366d1b54d2d3100c3130c04cf1dfb4b47c (patch) | |
tree | 7ad3483f5c37f77f2d0aa79772c0d07e2c5394dd /Modules/_ssl.c | |
parent | 29c3fc5d8f9e14e10783ab0ecc1bd15e1144cd07 (diff) | |
download | cpython-824f7f366d1b54d2d3100c3130c04cf1dfb4b47c.zip cpython-824f7f366d1b54d2d3100c3130c04cf1dfb4b47c.tar.gz cpython-824f7f366d1b54d2d3100c3130c04cf1dfb4b47c.tar.bz2 |
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).
Diffstat (limited to 'Modules/_ssl.c')
-rw-r--r-- | Modules/_ssl.c | 64 |
1 files changed, 59 insertions, 5 deletions
diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 848b962..4a72342 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -771,12 +771,14 @@ _get_peer_alt_names (X509 *certificate) { ext->value->length)); for(j = 0; j < sk_GENERAL_NAME_num(names); j++) { - /* get a rendering of each name in the set of names */ + int gntype; + ASN1_STRING *as = NULL; name = sk_GENERAL_NAME_value(names, j); - if (name->type == GEN_DIRNAME) { - + gntype = name-> type; + switch (gntype) { + case GEN_DIRNAME: /* we special-case DirName as a tuple of tuples of attributes */ @@ -798,11 +800,62 @@ _get_peer_alt_names (X509 *certificate) { goto fail; } PyTuple_SET_ITEM(t, 1, v); + break; - } else { + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + /* GENERAL_NAME_print() doesn't handle NULL bytes in ASN1_string + correctly, CVE-2013-4238 */ + t = PyTuple_New(2); + if (t == NULL) + goto fail; + switch (gntype) { + case GEN_EMAIL: + v = PyUnicode_FromString("email"); + as = name->d.rfc822Name; + break; + case GEN_DNS: + v = PyUnicode_FromString("DNS"); + as = name->d.dNSName; + break; + case GEN_URI: + v = PyUnicode_FromString("URI"); + as = name->d.uniformResourceIdentifier; + break; + } + if (v == NULL) { + Py_DECREF(t); + goto fail; + } + PyTuple_SET_ITEM(t, 0, v); + v = PyUnicode_FromStringAndSize((char *)ASN1_STRING_data(as), + ASN1_STRING_length(as)); + if (v == NULL) { + Py_DECREF(t); + goto fail; + } + PyTuple_SET_ITEM(t, 1, v); + break; + default: /* for everything else, we use the OpenSSL print form */ - + switch (gntype) { + /* check for new general name type */ + case GEN_OTHERNAME: + case GEN_X400: + case GEN_EDIPARTY: + case GEN_IPADD: + case GEN_RID: + break; + default: + if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, + "Unknown general name type %d", + gntype) == -1) { + goto fail; + } + break; + } (void) BIO_reset(biobuf); GENERAL_NAME_print(biobuf, name); len = BIO_gets(biobuf, buf, sizeof(buf)-1); @@ -829,6 +882,7 @@ _get_peer_alt_names (X509 *certificate) { goto fail; } PyTuple_SET_ITEM(t, 1, v); + break; } /* and add that rendering to the list */ |