Skip to content

Commit ede2ac9

Browse files
daxlabMariatta
authored andcommitted
bpo-23033: Improve SSL Certificate handling (GH-937)
Wildcard is now supported in hostname when it is one and only character in the leftmost segment.
1 parent 0cd2e81 commit ede2ac9

File tree

5 files changed

+22
-8
lines changed

5 files changed

+22
-8
lines changed

Doc/library/ssl.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,10 @@ Certificate handling
429429
Matching of IP addresses, when present in the subjectAltName field
430430
of the certificate, is now supported.
431431

432+
.. versionchanged:: 3.7
433+
Allow wildcard when it is the leftmost and the only character
434+
in that segment.
435+
432436
.. function:: cert_time_to_seconds(cert_time)
433437

434438
Return the time in seconds since the Epoch, given the ``cert_time``

Lib/ssl.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ class CertificateError(ValueError):
221221
pass
222222

223223

224-
def _dnsname_match(dn, hostname, max_wildcards=1):
224+
def _dnsname_match(dn, hostname):
225225
"""Matching according to RFC 6125, section 6.4.3
226226
227227
http://tools.ietf.org/html/rfc6125#section-6.4.3
@@ -233,7 +233,12 @@ def _dnsname_match(dn, hostname, max_wildcards=1):
233233
leftmost, *remainder = dn.split(r'.')
234234

235235
wildcards = leftmost.count('*')
236-
if wildcards > max_wildcards:
236+
if wildcards == 1 and len(leftmost) > 1:
237+
# Only match wildcard in leftmost segment.
238+
raise CertificateError(
239+
"wildcard can only be present in the leftmost segment: " + repr(dn))
240+
241+
if wildcards > 1:
237242
# Issue #17980: avoid denials of service by refusing more
238243
# than one wildcard per fragment. A survey of established
239244
# policy among SSL implementations showed it to be a

Lib/test/test_ssl.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -512,10 +512,11 @@ def fail(cert, hostname):
512512
fail(cert, 'Xa.com')
513513
fail(cert, '.a.com')
514514

515-
# only match one left-most wildcard
515+
# only match wildcards when they are the only thing
516+
# in left-most segment
516517
cert = {'subject': ((('commonName', 'f*.com'),),)}
517-
ok(cert, 'foo.com')
518-
ok(cert, 'f.com')
518+
fail(cert, 'foo.com')
519+
fail(cert, 'f.com')
519520
fail(cert, 'bar.com')
520521
fail(cert, 'foo.a.com')
521522
fail(cert, 'bar.foo.com')
@@ -552,8 +553,8 @@ def fail(cert, hostname):
552553
# are supported.
553554
idna = 'www*.pythön.org'.encode("idna").decode("ascii")
554555
cert = {'subject': ((('commonName', idna),),)}
555-
ok(cert, 'www.pythön.org'.encode("idna").decode("ascii"))
556-
ok(cert, 'www1.pythön.org'.encode("idna").decode("ascii"))
556+
fail(cert, 'www.pythön.org'.encode("idna").decode("ascii"))
557+
fail(cert, 'www1.pythön.org'.encode("idna").decode("ascii"))
557558
fail(cert, 'ftp.pythön.org'.encode("idna").decode("ascii"))
558559
fail(cert, 'pythön.org'.encode("idna").decode("ascii"))
559560

@@ -637,7 +638,7 @@ def fail(cert, hostname):
637638
# Issue #17980: avoid denials of service by refusing more than one
638639
# wildcard per fragment.
639640
cert = {'subject': ((('commonName', 'a*b.com'),),)}
640-
ok(cert, 'axxb.com')
641+
fail(cert, 'axxb.com')
641642
cert = {'subject': ((('commonName', 'a*b.co*'),),)}
642643
fail(cert, 'axxb.com')
643644
cert = {'subject': ((('commonName', 'a*b*.com'),),)}

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1467,6 +1467,7 @@ Nathan Paul Simons
14671467
Guilherme Simões
14681468
Adam Simpkins
14691469
Ravi Sinha
1470+
Mandeep Singh
14701471
Janne Sinkkonen
14711472
Ng Pheng Siong
14721473
Yann Sionneau
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Wildcard is now supported in hostname when it is one and only character in
2+
the left most segment of hostname in second argument of
3+
:meth:`ssl.match_hostname`. Patch by Mandeep Singh.

0 commit comments

Comments
 (0)