Skip to content

Commit a197f8a

Browse files
[3.7] bpo-38820: OpenSSL 3.0.0 compatibility. (GH-17190) (GH-17500)
test_openssl_version now accepts version 3.0.0. getpeercert() no longer returns IPv6 addresses with a trailing new line. Signed-off-by: Christian Heimes <christian@python.org> https://bugs.python.org/issue38820 (cherry picked from commit 2b7de66) Co-authored-by: Christian Heimes <christian@python.org> https://bugs.python.org/issue38820 Automerge-Triggered-By: @tiran
1 parent a85066d commit a197f8a

File tree

4 files changed

+59
-7
lines changed

4 files changed

+59
-7
lines changed

Doc/library/ssl.rst

+3
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,9 @@ SSL sockets also have the following additional methods and attributes:
12471247
The returned dictionary includes additional X509v3 extension items
12481248
such as ``crlDistributionPoints``, ``caIssuers`` and ``OCSP`` URIs.
12491249

1250+
.. versionchanged:: 3.7.6
1251+
IPv6 address strings no longer have a trailing new line.
1252+
12501253
.. method:: SSLSocket.cipher()
12511254

12521255
Returns a three-value tuple containing the name of the cipher being used, the

Lib/test/test_ssl.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ def test_parse_cert_CVE_2013_4238(self):
500500
('email', 'null@python.org\x00user@example.org'),
501501
('URI', 'http://null.python.org\x00http://example.org'),
502502
('IP Address', '192.0.2.1'),
503-
('IP Address', '2001:DB8:0:0:0:0:0:1\n'))
503+
('IP Address', '2001:DB8:0:0:0:0:0:1'))
504504
else:
505505
# OpenSSL 0.9.7 doesn't support IPv6 addresses in subjectAltName
506506
san = (('DNS', 'altnull.python.org\x00example.com'),
@@ -527,7 +527,7 @@ def test_parse_all_sans(self):
527527
(('commonName', 'dirname example'),))),
528528
('URI', 'https://www.python.org/'),
529529
('IP Address', '127.0.0.1'),
530-
('IP Address', '0:0:0:0:0:0:0:1\n'),
530+
('IP Address', '0:0:0:0:0:0:0:1'),
531531
('Registered ID', '1.2.3.4.5')
532532
)
533533
)
@@ -554,11 +554,11 @@ def test_openssl_version(self):
554554
# Some sanity checks follow
555555
# >= 0.9
556556
self.assertGreaterEqual(n, 0x900000)
557-
# < 3.0
558-
self.assertLess(n, 0x30000000)
557+
# < 4.0
558+
self.assertLess(n, 0x40000000)
559559
major, minor, fix, patch, status = t
560-
self.assertGreaterEqual(major, 0)
561-
self.assertLess(major, 3)
560+
self.assertGreaterEqual(major, 1)
561+
self.assertLess(major, 4)
562562
self.assertGreaterEqual(minor, 0)
563563
self.assertLess(minor, 256)
564564
self.assertGreaterEqual(fix, 0)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Make Python compatible with OpenSSL 3.0.0. :func:`ssl.SSLSocket.getpeercert`
2+
no longer returns IPv6 addresses with a trailing new line.

Modules/_ssl.c

+48-1
Original file line numberDiff line numberDiff line change
@@ -1377,14 +1377,61 @@ _get_peer_alt_names (X509 *certificate) {
13771377
PyTuple_SET_ITEM(t, 1, v);
13781378
break;
13791379

1380+
case GEN_IPADD:
1381+
/* OpenSSL < 3.0.0 adds a trailing \n to IPv6. 3.0.0 removed
1382+
* the trailing newline. Remove it in all versions
1383+
*/
1384+
t = PyTuple_New(2);
1385+
if (t == NULL)
1386+
goto fail;
1387+
1388+
v = PyUnicode_FromString("IP Address");
1389+
if (v == NULL) {
1390+
Py_DECREF(t);
1391+
goto fail;
1392+
}
1393+
PyTuple_SET_ITEM(t, 0, v);
1394+
1395+
if (name->d.ip->length == 4) {
1396+
unsigned char *p = name->d.ip->data;
1397+
v = PyUnicode_FromFormat(
1398+
"%d.%d.%d.%d",
1399+
p[0], p[1], p[2], p[3]
1400+
);
1401+
} else if (name->d.ip->length == 16) {
1402+
/* PyUnicode_FromFormat() does not support %X */
1403+
unsigned char *p = name->d.ip->data;
1404+
len = sprintf(
1405+
buf,
1406+
"%X:%X:%X:%X:%X:%X:%X:%X",
1407+
p[0] << 8 | p[1],
1408+
p[2] << 8 | p[3],
1409+
p[4] << 8 | p[5],
1410+
p[6] << 8 | p[7],
1411+
p[8] << 8 | p[9],
1412+
p[10] << 8 | p[11],
1413+
p[12] << 8 | p[13],
1414+
p[14] << 8 | p[15]
1415+
);
1416+
v = PyUnicode_FromStringAndSize(buf, len);
1417+
} else {
1418+
v = PyUnicode_FromString("<invalid>");
1419+
}
1420+
1421+
if (v == NULL) {
1422+
Py_DECREF(t);
1423+
goto fail;
1424+
}
1425+
PyTuple_SET_ITEM(t, 1, v);
1426+
break;
1427+
13801428
default:
13811429
/* for everything else, we use the OpenSSL print form */
13821430
switch (gntype) {
13831431
/* check for new general name type */
13841432
case GEN_OTHERNAME:
13851433
case GEN_X400:
13861434
case GEN_EDIPARTY:
1387-
case GEN_IPADD:
13881435
case GEN_RID:
13891436
break;
13901437
default:

0 commit comments

Comments
 (0)