[Python-checkins] [2.7] bpo-30502: Fix handling of long oids in ssl. (GH-2909). (#3322)

Christian Heimes webhook-mailer at python.org
Tue Sep 5 13:13:10 EDT 2017


https://github.com/python/cpython/commit/c9d668c0d8a6f3e8e72345e53d1dd34be172f16e
commit: c9d668c0d8a6f3e8e72345e53d1dd34be172f16e
branch: 2.7
author: Christian Heimes <christian at python.org>
committer: GitHub <noreply at github.com>
date: 2017-09-05T19:13:07+02:00
summary:

[2.7] bpo-30502: Fix handling of long oids in ssl. (GH-2909). (#3322)

(cherry picked from commit e503ca52889bf66ac502702569e726caa7970299)

files:
A Misc/NEWS.d/next/Library/2017-07-27-11-33-58.bpo-30502.GJlfU8.rst
M Modules/_ssl.c

diff --git a/Misc/NEWS.d/next/Library/2017-07-27-11-33-58.bpo-30502.GJlfU8.rst b/Misc/NEWS.d/next/Library/2017-07-27-11-33-58.bpo-30502.GJlfU8.rst
new file mode 100644
index 00000000000..522bdf669e9
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2017-07-27-11-33-58.bpo-30502.GJlfU8.rst
@@ -0,0 +1 @@
+Fix handling of long oids in ssl.  Based on patch by Christian Heimes.
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index 2bc981f6091..761554a7827 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -676,49 +676,67 @@ static PyObject *PySSL_SSLdo_handshake(PySSLSocket *self)
 }
 
 static PyObject *
-_create_tuple_for_attribute (ASN1_OBJECT *name, ASN1_STRING *value) {
-
-    char namebuf[X509_NAME_MAXLEN];
+_asn1obj2py(const ASN1_OBJECT *name, int no_name)
+{
+    char buf[X509_NAME_MAXLEN];
+    char *namebuf = buf;
     int buflen;
-    PyObject *name_obj;
-    PyObject *value_obj;
-    PyObject *attr;
-    unsigned char *valuebuf = NULL;
+    PyObject *name_obj = NULL;
 
-    buflen = OBJ_obj2txt(namebuf, sizeof(namebuf), name, 0);
+    buflen = OBJ_obj2txt(namebuf, X509_NAME_MAXLEN, name, no_name);
     if (buflen < 0) {
         _setSSLError(NULL, 0, __FILE__, __LINE__);
-        goto fail;
+        return NULL;
+    }
+    /* initial buffer is too small for oid + terminating null byte */
+    if (buflen > X509_NAME_MAXLEN - 1) {
+        /* make OBJ_obj2txt() calculate the required buflen */
+        buflen = OBJ_obj2txt(NULL, 0, name, no_name);
+        /* allocate len + 1 for terminating NULL byte */
+        namebuf = PyMem_Malloc(buflen + 1);
+        if (namebuf == NULL) {
+            PyErr_NoMemory();
+            return NULL;
+        }
+        buflen = OBJ_obj2txt(namebuf, buflen + 1, name, no_name);
+        if (buflen < 0) {
+            _setSSLError(NULL, 0, __FILE__, __LINE__);
+            goto done;
+        }
+    }
+    if (!buflen && no_name) {
+        Py_INCREF(Py_None);
+        name_obj = Py_None;
+    }
+    else {
+        name_obj = PyString_FromStringAndSize(namebuf, buflen);
     }
-    name_obj = PyString_FromStringAndSize(namebuf, buflen);
-    if (name_obj == NULL)
-        goto fail;
+
+  done:
+    if (buf != namebuf) {
+        PyMem_Free(namebuf);
+    }
+    return name_obj;
+}
+
+static PyObject *
+_create_tuple_for_attribute(ASN1_OBJECT *name, ASN1_STRING *value)
+{
+    Py_ssize_t buflen;
+    unsigned char *valuebuf = NULL;
+    PyObject *attr, *value_obj;
 
     buflen = ASN1_STRING_to_UTF8(&valuebuf, value);
     if (buflen < 0) {
         _setSSLError(NULL, 0, __FILE__, __LINE__);
-        Py_DECREF(name_obj);
-        goto fail;
+        return NULL;
     }
     value_obj = PyUnicode_DecodeUTF8((char *) valuebuf,
                                      buflen, "strict");
+
+    attr = Py_BuildValue("NN", _asn1obj2py(name, 0), value_obj);
     OPENSSL_free(valuebuf);
-    if (value_obj == NULL) {
-        Py_DECREF(name_obj);
-        goto fail;
-    }
-    attr = PyTuple_New(2);
-    if (attr == NULL) {
-        Py_DECREF(name_obj);
-        Py_DECREF(value_obj);
-        goto fail;
-    }
-    PyTuple_SET_ITEM(attr, 0, name_obj);
-    PyTuple_SET_ITEM(attr, 1, value_obj);
     return attr;
-
-  fail:
-    return NULL;
 }
 
 static PyObject *
@@ -3576,8 +3594,6 @@ asn1obj2py(ASN1_OBJECT *obj)
 {
     int nid;
     const char *ln, *sn;
-    char buf[100];
-    Py_ssize_t buflen;
 
     nid = OBJ_obj2nid(obj);
     if (nid == NID_undef) {
@@ -3586,16 +3602,7 @@ asn1obj2py(ASN1_OBJECT *obj)
     }
     sn = OBJ_nid2sn(nid);
     ln = OBJ_nid2ln(nid);
-    buflen = OBJ_obj2txt(buf, sizeof(buf), obj, 1);
-    if (buflen < 0) {
-        _setSSLError(NULL, 0, __FILE__, __LINE__);
-        return NULL;
-    }
-    if (buflen) {
-        return Py_BuildValue("isss#", nid, sn, ln, buf, buflen);
-    } else {
-        return Py_BuildValue("issO", nid, sn, ln, Py_None);
-    }
+    return Py_BuildValue("issN", nid, sn, ln, _asn1obj2py(obj, 1));
 }
 
 PyDoc_STRVAR(PySSL_txt2obj_doc,



More information about the Python-checkins mailing list