Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connection fails via https when certificate contains IPv6 address in SAN #1269

Closed
jharbott opened this issue Sep 19, 2017 · 6 comments
Closed

Connection fails via https when certificate contains IPv6 address in SAN #1269

jharbott opened this issue Sep 19, 2017 · 6 comments
Assignees
Labels
TLS

Comments

@jharbott
Copy link

@jharbott jharbott commented Sep 19, 2017

The URL is https://[2001:db8::17]/, the server is running with a certificate that includes both DNS:2001:db8::17 and IP:2001:db8::17 as alt_names. Accessing that URL with e.g. curl works just fine, when using urllib3 I am seeing this error instead:

A problem was encountered with the certificate that prevented urllib3 from finding the SubjectAlternativeName field. This can affect certificate validation. The error was Codepoint U+003A at position 5 of u'2001:db8::17' not allowed
@Lukasa
Copy link
Contributor

@Lukasa Lukasa commented Sep 19, 2017

Can you please try installing the ipaddress module to see if that resolves your issue?

@jharbott
Copy link
Author

@jharbott jharbott commented Sep 20, 2017

That module is installed. Actually this seems to be an issue with the cryptography module that can be avoided by omitting the DNS:2001:db8::17 part and is fixed in master there otherwise.

@jharbott jharbott closed this Sep 20, 2017
@jharbott
Copy link
Author

@jharbott jharbott commented Sep 27, 2017

Reopening since even after fixing pyca/cryptography#3943 I'm still seeing another traceback within urllib3 now:

  File "/usr/local/lib/python2.7/dist-packages/urllib3/connection.py", line 337, in connect
    cert = self.sock.getpeercert()
  File "/usr/local/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.py", line 348, in getpeercert
    'subjectAltName': get_subj_alt_name(x509)
  File "/usr/local/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.py", line 222, in get_subj_alt_name
    for name in ext.get_values_for_type(x509.DNSName)
  File "/usr/local/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.py", line 175, in _dnsname_to_stdlib
    name = idna_encode(name)
  File "/usr/local/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.py", line 173, in idna_encode
    return idna.encode(name)
  File "/usr/local/lib/python2.7/dist-packages/idna/core.py", line 355, in encode
    result.append(alabel(label))
  File "/usr/local/lib/python2.7/dist-packages/idna/core.py", line 265, in alabel
    raise IDNAError('The label {0} is not a valid A-label'.format(label))
IDNAError: The label 2001:db8::17 is not a valid A-label
@jharbott jharbott reopened this Sep 27, 2017
@nateprewitt
Copy link
Contributor

@nateprewitt nateprewitt commented Sep 27, 2017

This looks like it's in the same vein as our idna issues in Requests. Running IP addresses through the encoder is going to cause issues. That's why we ended up only running the idna portion on names that contained Unicode characters. It's possible a minor tweak to idna_encode in the pyopenssl module is necessary for IPv6 IPs in the Subject Alt Name field.

@jharbott
Copy link
Author

@jharbott jharbott commented Sep 27, 2017

This is a crude hack, but enough to get things working for me with py27 at least. Feel free to reuse/improve.

diff --git a/urllib3/contrib/pyopenssl.py b/urllib3/contrib/pyopenssl.py
index 2762bca..df9946a 100644
--- a/urllib3/contrib/pyopenssl.py
+++ b/urllib3/contrib/pyopenssl.py
@@ -172,6 +172,8 @@ def _dnsname_to_stdlib(name):
                 return prefix.encode('ascii') + idna.encode(name)
         return idna.encode(name)
 
+    if ':' in name:
+        return name
     name = idna_encode(name)
     if sys.version_info >= (3, 0):
         name = name.decode('utf-8')
@JanZerebecki
Copy link

@JanZerebecki JanZerebecki commented Sep 28, 2018

Until https://bugs.python.org/issue23239 is fixed correct certificates with SAN IP Addresses won't work on Python 2.7.

shazow added a commit that referenced this issue Apr 17, 2019
* Don't load system certificates by default when any other ``ca_certs``, ``ca_certs_dir`` or ``ssl_context`` parameters are specified.
* Remove Authorization header regardless of case when redirecting to cross-site. (Issue #1510)
* Add support for IPv6 addresses in subjectAltName section of certificates. (Issue #1269)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.