Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
c481bfb3
Commit
c481bfb3
authored
Feb 15, 2015
by
Antoine Pitrou
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #23239: ssl.match_hostname() now supports matching of IP addresses.
parent
2d07b855
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
55 additions
and
5 deletions
+55
-5
Doc/library/ssl.rst
Doc/library/ssl.rst
+7
-4
Lib/ssl.py
Lib/ssl.py
+22
-1
Lib/test/test_ssl.py
Lib/test/test_ssl.py
+24
-0
Misc/NEWS
Misc/NEWS
+2
-0
No files found.
Doc/library/ssl.rst
View file @
c481bfb3
...
...
@@ -344,10 +344,9 @@ Certificate handling
Verify that *cert* (in decoded format as returned by
:meth:`SSLSocket.getpeercert`) matches the given *hostname*. The rules
applied are those for checking the identity of HTTPS servers as outlined
in :rfc:`2818` and :rfc:`6125`, except that IP addresses are not currently
supported. In addition to HTTPS, this function should be suitable for
checking the identity of servers in various SSL-based protocols such as
FTPS, IMAPS, POPS and others.
in :rfc:`2818` and :rfc:`6125`. In addition to HTTPS, this function
should be suitable for checking the identity of servers in various
SSL-based protocols such as FTPS, IMAPS, POPS and others.
:exc:`CertificateError` is raised on failure. On success, the function
returns nothing::
...
...
@@ -369,6 +368,10 @@ Certificate handling
IDN A-labels such as ``www*.xn--pthon-kva.org`` are still supported,
but ``x*.python.org`` no longer matches ``xn--tda.python.org``.
.. versionchanged:: 3.5
Matching of IP addresses, when present in the subjectAltName field
of the certificate, is now supported.
.. function:: cert_time_to_seconds(cert_time)
Return the time in seconds since the Epoch, given the ``cert_time``
...
...
Lib/ssl.py
View file @
c481bfb3
...
...
@@ -87,6 +87,7 @@ ALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE
ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY
"""
import
ipaddress
import
textwrap
import
re
import
sys
...
...
@@ -242,6 +243,17 @@ def _dnsname_match(dn, hostname, max_wildcards=1):
return pat.match(hostname)
def _ipaddress_match(ipname, host_ip):
"""Exact matching of IP addresses.
RFC 6125 explicitly doesn'
t
define
an
algorithm
for
this
(
section
1.7
.
2
-
"Out of Scope"
).
"""
# OpenSSL may add a trailing newline to a subjectAltName's IP address
ip = ipaddress.ip_address(ipname.rstrip())
return ip == host_ip
def match_hostname(cert, hostname):
"""
Verify
that
*
cert
*
(
in
decoded
format
as
returned
by
SSLSocket
.
getpeercert
())
matches
the
*
hostname
*
.
RFC
2818
and
RFC
6125
...
...
@@ -254,11 +266,20 @@ def match_hostname(cert, hostname):
raise ValueError("empty or no certificate, match_hostname needs a "
"SSL socket or SSL context with either "
"CERT_OPTIONAL or CERT_REQUIRED")
try:
host_ip = ipaddress.ip_address(hostname)
except ValueError:
# Not an IP address (common case)
host_ip = None
dnsnames = []
san = cert.get('subjectAltName', ())
for key, value in san:
if key == 'DNS':
if _dnsname_match(value, hostname):
if host_ip is None and _dnsname_match(value, hostname):
return
dnsnames.append(value)
elif key == 'IP Address':
if host_ip is not None and _ipaddress_match(value, host_ip):
return
dnsnames.append(value)
if not dnsnames:
...
...
Lib/test/test_ssl.py
View file @
c481bfb3
...
...
@@ -383,6 +383,8 @@ class BasicSocketTests(unittest.TestCase):
self
.
assertRaises
(
ssl
.
CertificateError
,
ssl
.
match_hostname
,
cert
,
hostname
)
# -- Hostname matching --
cert
=
{
'subject'
:
(((
'commonName'
,
'example.com'
),),)}
ok
(
cert
,
'example.com'
)
ok
(
cert
,
'ExAmple.cOm'
)
...
...
@@ -468,6 +470,28 @@ class BasicSocketTests(unittest.TestCase):
# Only commonName is considered
fail
(
cert
,
'California'
)
# -- IPv4 matching --
cert
=
{
'subject'
:
(((
'commonName'
,
'example.com'
),),),
'subjectAltName'
:
((
'DNS'
,
'example.com'
),
(
'IP Address'
,
'10.11.12.13'
),
(
'IP Address'
,
'14.15.16.17'
))}
ok
(
cert
,
'10.11.12.13'
)
ok
(
cert
,
'14.15.16.17'
)
fail
(
cert
,
'14.15.16.18'
)
fail
(
cert
,
'example.net'
)
# -- IPv6 matching --
cert
=
{
'subject'
:
(((
'commonName'
,
'example.com'
),),),
'subjectAltName'
:
((
'DNS'
,
'example.com'
),
(
'IP Address'
,
'2001:0:0:0:0:0:0:CAFE
\
n
'
),
(
'IP Address'
,
'2003:0:0:0:0:0:0:BABA
\
n
'
))}
ok
(
cert
,
'2001::cafe'
)
ok
(
cert
,
'2003::baba'
)
fail
(
cert
,
'2003::bebe'
)
fail
(
cert
,
'example.net'
)
# -- Miscellaneous --
# Neither commonName nor subjectAltName
cert
=
{
'notAfter'
:
'Dec 18 23:59:59 2011 GMT'
,
'subject'
:
(((
'countryName'
,
'US'
),),
...
...
Misc/NEWS
View file @
c481bfb3
...
...
@@ -13,6 +13,8 @@ Core and Builtins
Library
-------
- Issue #23239: ssl.match_hostname() now supports matching of IP addresses.
- Issue #23146: Fix mishandling of absolute Windows paths with forward
slashes in pathlib.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment