summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorBarry Warsaw <barry@python.org>2013-08-23 17:26:49 (GMT)
committerBarry Warsaw <barry@python.org>2013-08-23 17:26:49 (GMT)
commit82f88283171933127f20f866a7f98694b29cca56 (patch)
tree85f872fa42b336a9f739035e25007978d777f9ba /Modules
parentf880e5d5eaef3233fb1cd2f747c8f0ba59c7f086 (diff)
downloadcpython-82f88283171933127f20f866a7f98694b29cca56.zip
cpython-82f88283171933127f20f866a7f98694b29cca56.tar.gz
cpython-82f88283171933127f20f866a7f98694b29cca56.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')
-rw-r--r--Modules/_ssl.c64
1 files changed, 61 insertions, 3 deletions
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index 46f71e8..a045be4 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -302,8 +302,10 @@ newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file,
self->ctx = SSL_CTX_new(TLSv1_method()); /* Set up context */
else if (proto_version == PY_SSL_VERSION_SSL3)
self->ctx = SSL_CTX_new(SSLv3_method()); /* Set up context */
+#ifndef OPENSSL_NO_SSL2
else if (proto_version == PY_SSL_VERSION_SSL2)
self->ctx = SSL_CTX_new(SSLv2_method()); /* Set up context */
+#endif
else if (proto_version == PY_SSL_VERSION_SSL23)
self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */
PySSL_END_ALLOW_THREADS
@@ -718,8 +720,13 @@ _get_peer_alt_names (X509 *certificate) {
/* 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 */
@@ -741,11 +748,61 @@ _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 NUL bytes in ASN1_string
+ correctly. */
+ 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 = PyString_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_Warn(PyExc_RuntimeWarning,
+ "Unknown general name type") == -1) {
+ goto fail;
+ }
+ break;
+ }
(void) BIO_reset(biobuf);
GENERAL_NAME_print(biobuf, name);
len = BIO_gets(biobuf, buf, sizeof(buf)-1);
@@ -771,6 +828,7 @@ _get_peer_alt_names (X509 *certificate) {
goto fail;
}
PyTuple_SET_ITEM(t, 1, v);
+ break;
}
/* and add that rendering to the list */