classification
Title: match_hostname treats SAN IP address as DNS name and fails to check CN then
Type: behavior Stage: resolved
Components: SSL Versions: Python 3.7, Python 3.6, Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: christian.heimes Nosy List: Lukasa, alex, christian.heimes, dstufft, janssen, noxxi, raysatiro
Priority: normal Keywords:

Created on 2016-12-11 20:14 by noxxi, last changed 2017-09-05 22:39 by christian.heimes. This issue is now closed.

Messages (5)
msg282940 - (view) Author: Steffen Ullrich (noxxi) Date: 2016-12-11 20:14
from Lib/ssl.py

303        elif key == 'IP Address':
304            if host_ip is not None and _ipaddress_match(value, host_ip):
305                return
306            dnsnames.append(value)
307    if not dnsnames:
308        # The subject is only checked when there is no dNSName entry
309        # in subjectAltName

RFC 2818 and RFC 6125 say that CN should not be used if subjectAltNames contains DNS names. This means CN should still be checked if SAN contains only IP addresses. By appending IP address to dnsnames in line 306 it will not check the CN if there are no DNS names in SAN but only IP address.

See also http://stackoverflow.com/questions/41089539/authentication-issue-with-ssl-certificate-using-python-requests-lib/41090559#41090559
msg282945 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2016-12-11 20:26
Python's implementation of host name verification conforms to RFC 6125, section 6.4.4. The CN check is optional (MAY). Python treats the presence of an IP Address as indicator that CN check should not be performed. 

In fact hostname verification code should be more strict and not fall back to CN when a SRV-ID or URI is present. But the ssl module lacks support to fetch SRV-ID, see #28191. Since public CAs and members of the CAB forum are not yet allowed to issue certificates with SRV-ID, it's not a security issue.


https://tools.ietf.org/html/rfc6125#section-6.4.4

6.4.4.  Checking of Common Names

   As noted, a client MUST NOT seek a match for a reference identifier
   of CN-ID if the presented identifiers include a DNS-ID, SRV-ID,
   URI-ID, or any application-specific identifier types supported by the
   client.

   Therefore, if and only if the presented identifiers do not include a
   DNS-ID, SRV-ID, URI-ID, or any application-specific identifier types
   supported by the client, then the client MAY as a last resort check
   for a string whose form matches that of a fully qualified DNS domain
   name in a Common Name field of the subject field (i.e., a CN-ID).
msg282950 - (view) Author: Steffen Ullrich (noxxi) Date: 2016-12-11 21:39
On Sun, Dec 11, 2016 at 08:26:32PM +0000, Christian Heimes <report@bugs.python.org> wrote:
> 
> Christian Heimes added the comment:
> 
> Python's implementation of host name verification conforms to RFC 6125, section 6.4.4. The CN check is optional (MAY). Python treats the presence of an IP Address as indicator that CN check should not be performed. 

RFC 6125 does not obsolete RFC 2818. In fact it says in section 1.4:

   This document also does not supersede the rules for verifying service
   identity provided in specifications for existing application
   protocols published prior to this document, such as those excerpted
   under Appendix B...

Where Appendix B.2 explicitly cites the relevant parts from RFC 2818 like this
in section 3.1:

  If a subjectAltName extension of type dNSName is present, that MUST
  be used as the identity. Otherwise, the (most specific) Common Name
  field in the Subject field of the certificate MUST be used.

Thus while RFC 6125 might say MAY for checking the CN the more specific RFC
2818 says clearly MUST. Also, the intention of RFC 6125 in 6.4.4 is in my
opinion to distinguish between applications never checking the CN and
applications which check the CN, while addressing the last ones that CN
should not be checked for specific SAN record types. iPAddress is not a type
which is considered for this special treatment.

Regards,
Steffen
msg301387 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2017-09-05 22:34
I don't like to change the behavior of match_hostname(). RFC 2818 is deprecated. Recent browsers are no longer using CN to verify hostnames. Python is going to ignore CN soonish, too.
msg301388 - (view) Author: Alex Gaynor (alex) * (Python committer) Date: 2017-09-05 22:37
+1 Christian, we should not be expanding our usage of CNs at all.
History
Date User Action Args
2017-09-05 22:39:36christian.heimessetstatus: open -> closed
stage: resolved
2017-09-05 22:37:42alexsetstatus: pending -> open

messages: + msg301388
2017-09-05 22:34:52christian.heimessetstatus: open -> pending
type: behavior
messages: + msg301387

versions: + Python 2.7, - Python 3.3, Python 3.4, Python 3.5
2016-12-11 23:50:58raysatirosetnosy: + raysatiro
2016-12-11 21:39:39noxxisetmessages: + msg282950
2016-12-11 20:57:41Lukasasetstatus: pending -> open
nosy: + Lukasa
2016-12-11 20:26:32christian.heimessetstatus: open -> pending
messages: + msg282945

assignee: christian.heimes
components: + SSL
resolution: not a bug
2016-12-11 20:15:32ned.deilysetnosy: + janssen, christian.heimes, alex, dstufft
2016-12-11 20:14:26noxxicreate