Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fe3c9c1

Browse files
committed
Issue #27691: Fix ssl module's parsing of GEN_RID subject alternative name fields in X.509 certs.
2 parents 87bf0fe + 1c03abd commit fe3c9c1

5 files changed

Lines changed: 142 additions & 5 deletions

File tree

Lib/test/allsans.pem

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOoy7/QOtTjQ0niE
3+
6uDcTwtkC0R2Tvy1AjVnXohCntZfdzbTGDoYTgXSOLsP8A697jUiJ8VCePGH50xG
4+
Z4DKnAF3a9O3a9nr2pLXb0iY3XOMv+YEBii7CfI+3oxFYgCl0sMgHzDD2ZTVYAsm
5+
DWgLUVsE2gHEccRwrM2tPf2EgR+FAgMBAAECgYEA3qyfyYVSeTrTYxO93x6ZaVMu
6+
A2IZp9zSxMQL9bKiI2GRj+cV2ebSCGbg2btFnD6qBor7FWsmYz+8g6FNN/9sY4az
7+
61rMqMtQvLBe+7L8w70FeTze4qQ4Y1oQri0qD6tBWhDVlpnbI5Py9bkZKD67yVUk
8+
elcEA/5x4PrYXkuqsAECQQD80NjT0mDvaY0JOOaQFSEpMv6QiUA8GGX8Xli7IoKb
9+
tAolPG8rQBa+qSpcWfDMTrWw/aWHuMEEQoP/bVDH9W4FAkEA7SYQbBAKnojZ5A3G
10+
kOHdV7aeivRQxQk/JN8Fb8oKB9Csvpv/BsuGxPKXHdhFa6CBTTsNRtHQw/szPo4l
11+
xMIjgQJAPoMxqibR+0EBM6+TKzteSL6oPXsCnBl4Vk/J5vPgkbmR7KUl4+7j8N8J
12+
b2554TrxKEN/w7CGYZRE6UrRd7ATNQJAWD7Yz41sli+wfPdPU2xo1BHljyl4wMk/
13+
EPZYbI/PCbdyAH/F935WyQTIjNeEhZc1Zkq6FwdOWw8ns3hrv3rKgQJAHXv1BqUa
14+
czGPIFxX2TNoqtcl6/En4vrxVB1wzsfzkkDAg98kBl7qsF+S3qujSzKikjeaVbI2
15+
/CyWR2P3yLtOmA==
16+
-----END PRIVATE KEY-----
17+
-----BEGIN CERTIFICATE-----
18+
MIIDcjCCAtugAwIBAgIJAN5dc9TOWjB7MA0GCSqGSIb3DQEBCwUAMF0xCzAJBgNV
19+
BAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9u
20+
IFNvZnR3YXJlIEZvdW5kYXRpb24xEDAOBgNVBAMMB2FsbHNhbnMwHhcNMTYwODA1
21+
MTAyMTExWhcNMjYwODAzMTAyMTExWjBdMQswCQYDVQQGEwJYWTEXMBUGA1UEBwwO
22+
Q2FzdGxlIEFudGhyYXgxIzAhBgNVBAoMGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0
23+
aW9uMRAwDgYDVQQDDAdhbGxzYW5zMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
24+
gQDqMu/0DrU40NJ4hOrg3E8LZAtEdk78tQI1Z16IQp7WX3c20xg6GE4F0ji7D/AO
25+
ve41IifFQnjxh+dMRmeAypwBd2vTt2vZ69qS129ImN1zjL/mBAYouwnyPt6MRWIA
26+
pdLDIB8ww9mU1WALJg1oC1FbBNoBxHHEcKzNrT39hIEfhQIDAQABo4IBODCCATQw
27+
ggEwBgNVHREEggEnMIIBI4IHYWxsc2Fuc6AeBgMqAwSgFwwVc29tZSBvdGhlciBp
28+
ZGVudGlmaWVyoDUGBisGAQUCAqArMCmgEBsOS0VSQkVST1MuUkVBTE2hFTAToAMC
29+
AQGhDDAKGwh1c2VybmFtZYEQdXNlckBleGFtcGxlLm9yZ4IPd3d3LmV4YW1wbGUu
30+
b3JnpGcwZTELMAkGA1UEBhMCWFkxFzAVBgNVBAcMDkNhc3RsZSBBbnRocmF4MSMw
31+
IQYDVQQKDBpQeXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEYMBYGA1UEAwwPZGly
32+
bmFtZSBleGFtcGxlhhdodHRwczovL3d3dy5weXRob24ub3JnL4cEfwAAAYcQAAAA
33+
AAAAAAAAAAAAAAAAAYgEKgMEBTANBgkqhkiG9w0BAQsFAAOBgQAy16h+F+nOmeiT
34+
VWR0fc8F/j6FcadbLseAUaogcC15OGxCl4UYpLV88HBkABOoGCpP155qwWTwOrdG
35+
iYPGJSusf1OnJEbvzFejZf6u078bPd9/ZL4VWLjv+FPGkjd+N+/OaqMvgj8Lu99f
36+
3Y/C4S7YbHxxwff6C6l2Xli+q6gnuQ==
37+
-----END CERTIFICATE-----

Lib/test/make_ssl_certs.py

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,28 @@
1919
CN = {hostname}
2020
2121
[req_x509_extensions]
22-
subjectAltName = DNS:{hostname}
22+
subjectAltName = @san
23+
24+
[san]
25+
DNS.1 = {hostname}
26+
{extra_san}
27+
28+
[dir_sect]
29+
C = XY
30+
L = Castle Anthrax
31+
O = Python Software Foundation
32+
CN = dirname example
33+
34+
[princ_name]
35+
realm = EXP:0, GeneralString:KERBEROS.REALM
36+
principal_name = EXP:1, SEQUENCE:principal_seq
37+
38+
[principal_seq]
39+
name_type = EXP:0, INTEGER:1
40+
name_string = EXP:1, SEQUENCE:principals
41+
42+
[principals]
43+
princ1 = GeneralString:username
2344
2445
[ ca ]
2546
default_ca = CA_default
@@ -66,16 +87,17 @@
6687

6788
here = os.path.abspath(os.path.dirname(__file__))
6889

69-
def make_cert_key(hostname, sign=False):
90+
def make_cert_key(hostname, sign=False, extra_san=''):
7091
print("creating cert for " + hostname)
7192
tempnames = []
7293
for i in range(3):
7394
with tempfile.NamedTemporaryFile(delete=False) as f:
7495
tempnames.append(f.name)
7596
req_file, cert_file, key_file = tempnames
7697
try:
98+
req = req_template.format(hostname=hostname, extra_san=extra_san)
7799
with open(req_file, 'w') as f:
78-
f.write(req_template.format(hostname=hostname))
100+
f.write(req)
79101
args = ['req', '-new', '-days', '3650', '-nodes',
80102
'-newkey', 'rsa:1024', '-keyout', key_file,
81103
'-config', req_file]
@@ -119,7 +141,7 @@ def make_ca():
119141
f.write('unique_subject = no')
120142

121143
with tempfile.NamedTemporaryFile("w") as t:
122-
t.write(req_template.format(hostname='our-ca-server'))
144+
t.write(req_template.format(hostname='our-ca-server', extra_san=''))
123145
t.flush()
124146
with tempfile.NamedTemporaryFile() as f:
125147
args = ['req', '-new', '-days', '3650', '-extensions', 'v3_ca', '-nodes',
@@ -170,6 +192,25 @@ def make_ca():
170192
f.write(key)
171193
f.write(cert)
172194

195+
extra_san = [
196+
'otherName.1 = 1.2.3.4;UTF8:some other identifier',
197+
'otherName.2 = 1.3.6.1.5.2.2;SEQUENCE:princ_name',
198+
'email.1 = [email protected]',
199+
'DNS.2 = www.example.org',
200+
# GEN_X400
201+
'dirName.1 = dir_sect',
202+
# GEN_EDIPARTY
203+
'URI.1 = https://www.python.org/',
204+
'IP.1 = 127.0.0.1',
205+
'IP.2 = ::1',
206+
'RID.1 = 1.2.3.4.5',
207+
]
208+
209+
cert, key = make_cert_key('allsans', extra_san='\n'.join(extra_san))
210+
with open('allsans.pem', 'w') as f:
211+
f.write(key)
212+
f.write(cert)
213+
173214
unmake_ca()
174215
print("\n\nPlease change the values in test_ssl.py, test_parse_cert function related to notAfter,notBefore and serialNumber")
175216
check_call(['openssl','x509','-in','keycert.pem','-dates','-serial','-noout'])

Lib/test/test_ssl.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ def data_file(*name):
6565
SIGNED_CERTFILE2 = data_file("keycert4.pem")
6666
# Same certificate as pycacert.pem, but without extra text in file
6767
SIGNING_CA = data_file("capath", "ceff1710.0")
68+
# cert with all kinds of subject alt names
69+
ALLSANFILE = data_file("allsans.pem")
6870

6971
REMOTE_HOST = "self-signed.pythontest.net"
7072

@@ -286,6 +288,27 @@ def test_parse_cert_CVE_2013_4238(self):
286288

287289
self.assertEqual(p['subjectAltName'], san)
288290

291+
def test_parse_all_sans(self):
292+
p = ssl._ssl._test_decode_cert(ALLSANFILE)
293+
self.assertEqual(p['subjectAltName'],
294+
(
295+
('DNS', 'allsans'),
296+
('othername', '<unsupported>'),
297+
('othername', '<unsupported>'),
298+
('email', '[email protected]'),
299+
('DNS', 'www.example.org'),
300+
('DirName',
301+
((('countryName', 'XY'),),
302+
(('localityName', 'Castle Anthrax'),),
303+
(('organizationName', 'Python Software Foundation'),),
304+
(('commonName', 'dirname example'),))),
305+
('URI', 'https://www.python.org/'),
306+
('IP Address', '127.0.0.1'),
307+
('IP Address', '0:0:0:0:0:0:0:1\n'),
308+
('Registered ID', '1.2.3.4.5')
309+
)
310+
)
311+
289312
def test_DER_to_PEM(self):
290313
with open(CAFILE_CACERT, 'r') as f:
291314
pem = f.read()

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ Core and Builtins
8989
Library
9090
-------
9191

92+
- Issue #27691: Fix ssl module's parsing of GEN_RID subject alternative name
93+
fields in X.509 certs.
94+
9295
- Issue #25761: Improved error reporting about truncated pickle data in
9396
C implementation of unpickler. UnpicklingError is now raised instead of
9497
AttributeError and ValueError in some cases.

Modules/_ssl.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,35 @@ _get_peer_alt_names (X509 *certificate) {
10071007
PyTuple_SET_ITEM(t, 1, v);
10081008
break;
10091009

1010+
case GEN_RID:
1011+
t = PyTuple_New(2);
1012+
if (t == NULL)
1013+
goto fail;
1014+
1015+
v = PyUnicode_FromString("Registered ID");
1016+
if (v == NULL) {
1017+
Py_DECREF(t);
1018+
goto fail;
1019+
}
1020+
PyTuple_SET_ITEM(t, 0, v);
1021+
1022+
len = i2t_ASN1_OBJECT(buf, sizeof(buf)-1, name->d.rid);
1023+
if (len < 0) {
1024+
Py_DECREF(t);
1025+
_setSSLError(NULL, 0, __FILE__, __LINE__);
1026+
goto fail;
1027+
} else if (len >= (int)sizeof(buf)) {
1028+
v = PyUnicode_FromString("<INVALID>");
1029+
} else {
1030+
v = PyUnicode_FromStringAndSize(buf, len);
1031+
}
1032+
if (v == NULL) {
1033+
Py_DECREF(t);
1034+
goto fail;
1035+
}
1036+
PyTuple_SET_ITEM(t, 1, v);
1037+
break;
1038+
10101039
default:
10111040
/* for everything else, we use the OpenSSL print form */
10121041
switch (gntype) {
@@ -1033,8 +1062,12 @@ _get_peer_alt_names (X509 *certificate) {
10331062
goto fail;
10341063
}
10351064
vptr = strchr(buf, ':');
1036-
if (vptr == NULL)
1065+
if (vptr == NULL) {
1066+
PyErr_Format(PyExc_ValueError,
1067+
"Invalid value %.200s",
1068+
buf);
10371069
goto fail;
1070+
}
10381071
t = PyTuple_New(2);
10391072
if (t == NULL)
10401073
goto fail;

0 commit comments

Comments
 (0)