Skip to content

Commit 3faaab8

Browse files
committed
bpo-30502: Fix handling of long oids
Signed-off-by: Christian Heimes <christian@python.org>
1 parent 2e6bb44 commit 3faaab8

File tree

1 file changed

+49
-12
lines changed

1 file changed

+49
-12
lines changed

Modules/_ssl.c

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -753,19 +753,35 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self)
753753

754754
static PyObject *
755755
_create_tuple_for_attribute (ASN1_OBJECT *name, ASN1_STRING *value) {
756-
757-
char namebuf[X509_NAME_MAXLEN];
756+
char buf[X509_NAME_MAXLEN];
757+
char *namebuf = buf;
758758
int buflen;
759759
PyObject *name_obj;
760760
PyObject *value_obj;
761-
PyObject *attr;
761+
PyObject *attr = NULL;
762762
unsigned char *valuebuf = NULL;
763763

764-
buflen = OBJ_obj2txt(namebuf, sizeof(namebuf), name, 0);
764+
buflen = OBJ_obj2txt(namebuf, X509_NAME_MAXLEN, name, 0);
765765
if (buflen < 0) {
766766
_setSSLError(NULL, 0, __FILE__, __LINE__);
767767
goto fail;
768768
}
769+
/* initial buffer is too small for oid + terminating NULL byte */
770+
if (buflen > X509_NAME_MAXLEN - 1) {
771+
/* make OBJ_obj2txt() calculate the required buflen */
772+
buflen = OBJ_obj2txt(NULL, 0, name, 0);
773+
/* allocate len + 1 for terminating NULL byte */
774+
namebuf = PyMem_Malloc(buflen + 1);
775+
if (namebuf == NULL) {
776+
PyErr_NoMemory();
777+
goto fail;
778+
}
779+
buflen = OBJ_obj2txt(namebuf, buflen + 1, name, 0);
780+
if (buflen < 0) {
781+
_setSSLError(NULL, 0, __FILE__, __LINE__);
782+
goto fail;
783+
}
784+
}
769785
name_obj = PyUnicode_FromStringAndSize(namebuf, buflen);
770786
if (name_obj == NULL)
771787
goto fail;
@@ -791,10 +807,11 @@ _create_tuple_for_attribute (ASN1_OBJECT *name, ASN1_STRING *value) {
791807
}
792808
PyTuple_SET_ITEM(attr, 0, name_obj);
793809
PyTuple_SET_ITEM(attr, 1, value_obj);
794-
return attr;
795810

796811
fail:
797-
return NULL;
812+
if (buf != namebuf)
813+
PyMem_Free(namebuf);
814+
return attr;
798815
}
799816

800817
static PyObject *
@@ -4655,26 +4672,46 @@ asn1obj2py(ASN1_OBJECT *obj)
46554672
{
46564673
int nid;
46574674
const char *ln, *sn;
4658-
char buf[100];
4675+
char buf[X509_NAME_MAXLEN];
4676+
char *namebuf = buf;
46594677
Py_ssize_t buflen;
4678+
PyObject *result = NULL;
46604679

46614680
nid = OBJ_obj2nid(obj);
46624681
if (nid == NID_undef) {
46634682
PyErr_Format(PyExc_ValueError, "Unknown object");
4664-
return NULL;
4683+
goto fail;
46654684
}
46664685
sn = OBJ_nid2sn(nid);
46674686
ln = OBJ_nid2ln(nid);
4668-
buflen = OBJ_obj2txt(buf, sizeof(buf), obj, 1);
4687+
buflen = OBJ_obj2txt(namebuf, X509_NAME_MAXLEN, obj, 1);
46694688
if (buflen < 0) {
46704689
_setSSLError(NULL, 0, __FILE__, __LINE__);
4671-
return NULL;
4690+
goto fail;
4691+
}
4692+
/* initial buffer is too small for oid + terminating NULL byte */
4693+
if (buflen > X509_NAME_MAXLEN - 1) {
4694+
/* make OBJ_obj2txt() calculate the required buflen */
4695+
buflen = OBJ_obj2txt(NULL, 0, obj, 1);
4696+
/* allocate len + 1 for terminating NULL byte */
4697+
namebuf = PyMem_Malloc(buflen + 1);
4698+
if (namebuf == NULL)
4699+
return PyErr_NoMemory();
4700+
buflen = OBJ_obj2txt(namebuf, buflen + 1, obj, 1);
4701+
if (buflen < 0) {
4702+
_setSSLError(NULL, 0, __FILE__, __LINE__);
4703+
goto fail;
4704+
}
46724705
}
46734706
if (buflen) {
4674-
return Py_BuildValue("isss#", nid, sn, ln, buf, buflen);
4707+
result = Py_BuildValue("isss#", nid, sn, ln, namebuf, buflen);
46754708
} else {
4676-
return Py_BuildValue("issO", nid, sn, ln, Py_None);
4709+
result = Py_BuildValue("issO", nid, sn, ln, Py_None);
46774710
}
4711+
fail:
4712+
if (buf != namebuf)
4713+
PyMem_Free(namebuf);
4714+
return result;
46784715
}
46794716

46804717
/*[clinic input]

0 commit comments

Comments
 (0)