Skip to content

Commit e503ca5

Browse files
serhiy-storchakatiran
authored andcommitted
bpo-30502: Fix handling of long oids in ssl. (#2909)
1 parent f801322 commit e503ca5

File tree

2 files changed

+48
-43
lines changed

2 files changed

+48
-43
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix handling of long oids in ssl. Based on patch by Christian Heimes.

Modules/_ssl.c

Lines changed: 47 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -787,49 +787,64 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self)
787787
}
788788

789789
static PyObject *
790-
_create_tuple_for_attribute (ASN1_OBJECT *name, ASN1_STRING *value) {
791-
792-
char namebuf[X509_NAME_MAXLEN];
790+
_asn1obj2py(const ASN1_OBJECT *name, int no_name)
791+
{
792+
char buf[X509_NAME_MAXLEN];
793+
char *namebuf = buf;
793794
int buflen;
794-
PyObject *name_obj;
795-
PyObject *value_obj;
796-
PyObject *attr;
797-
unsigned char *valuebuf = NULL;
795+
PyObject *name_obj = NULL;
798796

799-
buflen = OBJ_obj2txt(namebuf, sizeof(namebuf), name, 0);
797+
buflen = OBJ_obj2txt(namebuf, X509_NAME_MAXLEN, name, no_name);
800798
if (buflen < 0) {
801799
_setSSLError(NULL, 0, __FILE__, __LINE__);
802-
goto fail;
800+
return NULL;
803801
}
804-
name_obj = PyUnicode_FromStringAndSize(namebuf, buflen);
805-
if (name_obj == NULL)
806-
goto fail;
802+
/* initial buffer is too small for oid + terminating null byte */
803+
if (buflen > X509_NAME_MAXLEN - 1) {
804+
/* make OBJ_obj2txt() calculate the required buflen */
805+
buflen = OBJ_obj2txt(NULL, 0, name, no_name);
806+
/* allocate len + 1 for terminating NULL byte */
807+
namebuf = PyMem_Malloc(buflen + 1);
808+
if (namebuf == NULL) {
809+
PyErr_NoMemory();
810+
return NULL;
811+
}
812+
buflen = OBJ_obj2txt(namebuf, buflen + 1, name, no_name);
813+
if (buflen < 0) {
814+
_setSSLError(NULL, 0, __FILE__, __LINE__);
815+
goto done;
816+
}
817+
}
818+
if (!buflen && no_name) {
819+
Py_INCREF(Py_None);
820+
name_obj = Py_None;
821+
}
822+
else {
823+
name_obj = PyUnicode_FromStringAndSize(namebuf, buflen);
824+
}
825+
826+
done:
827+
if (buf != namebuf) {
828+
PyMem_Free(namebuf);
829+
}
830+
return name_obj;
831+
}
832+
833+
static PyObject *
834+
_create_tuple_for_attribute(ASN1_OBJECT *name, ASN1_STRING *value)
835+
{
836+
Py_ssize_t buflen;
837+
unsigned char *valuebuf = NULL;
838+
PyObject *attr;
807839

808840
buflen = ASN1_STRING_to_UTF8(&valuebuf, value);
809841
if (buflen < 0) {
810842
_setSSLError(NULL, 0, __FILE__, __LINE__);
811-
Py_DECREF(name_obj);
812-
goto fail;
843+
return NULL;
813844
}
814-
value_obj = PyUnicode_DecodeUTF8((char *) valuebuf,
815-
buflen, "strict");
845+
attr = Py_BuildValue("Ns#", _asn1obj2py(name, 0), valuebuf, buflen);
816846
OPENSSL_free(valuebuf);
817-
if (value_obj == NULL) {
818-
Py_DECREF(name_obj);
819-
goto fail;
820-
}
821-
attr = PyTuple_New(2);
822-
if (attr == NULL) {
823-
Py_DECREF(name_obj);
824-
Py_DECREF(value_obj);
825-
goto fail;
826-
}
827-
PyTuple_SET_ITEM(attr, 0, name_obj);
828-
PyTuple_SET_ITEM(attr, 1, value_obj);
829847
return attr;
830-
831-
fail:
832-
return NULL;
833848
}
834849

835850
static PyObject *
@@ -4676,8 +4691,6 @@ asn1obj2py(ASN1_OBJECT *obj)
46764691
{
46774692
int nid;
46784693
const char *ln, *sn;
4679-
char buf[100];
4680-
Py_ssize_t buflen;
46814694

46824695
nid = OBJ_obj2nid(obj);
46834696
if (nid == NID_undef) {
@@ -4686,16 +4699,7 @@ asn1obj2py(ASN1_OBJECT *obj)
46864699
}
46874700
sn = OBJ_nid2sn(nid);
46884701
ln = OBJ_nid2ln(nid);
4689-
buflen = OBJ_obj2txt(buf, sizeof(buf), obj, 1);
4690-
if (buflen < 0) {
4691-
_setSSLError(NULL, 0, __FILE__, __LINE__);
4692-
return NULL;
4693-
}
4694-
if (buflen) {
4695-
return Py_BuildValue("isss#", nid, sn, ln, buf, buflen);
4696-
} else {
4697-
return Py_BuildValue("issO", nid, sn, ln, Py_None);
4698-
}
4702+
return Py_BuildValue("issN", nid, sn, ln, _asn1obj2py(obj, 1));
46994703
}
47004704

47014705
/*[clinic input]

0 commit comments

Comments
 (0)