This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: hostname verification fails if hostname starts with literal IPv4
Type: behavior Stage:
Components: SSL Versions: Python 3.10, Python 3.9, Python 3.8
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: christian.heimes Nosy List: Amir, akvadrako, christian.heimes, dnmvisser
Priority: normal Keywords:

Created on 2020-08-15 09:25 by dnmvisser, last changed 2022-04-11 14:59 by admin.

Messages (5)
msg375454 - (view) Author: Dick Visser (dnmvisser) Date: 2020-08-15 09:25
I'm trying to connect to an HTTPS site with ssl.create_default_context, which implies hostname verification is done. This fails when connecting to a hostname that starts with a literal IPv4 address. Reproduce with:


#!/usr/bin/env python3
import socket
import ssl

hostname = '145.100.57.105.surf-hosted.nl'
# hostname = 'python.org'

context = ssl.create_default_context()

with socket.create_connection((hostname, 443)) as sock:
    with context.wrap_socket(sock, server_hostname=hostname) as ssock:
        cert = ssock.getpeercert()
        print(cert)



Running this yeidls:

ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: IP address mismatch, certificate is not valid for '145.100.57.105.surf-hosted.nl'. (_ssl.c:1123)

While the certificate on that host is perfectly fine (is has both CN and a subject alt name).

Since the actual verification is done by OpenSSL, I tried that manually, and that does validate the hostname OK:


dnmvisser@NUC8i5BEK ~$ openssl s_client -connect 145.100.57.105.surf-hosted.nl:443 -verify_hostname 145.100.57.105.surf-hosted.nl
CONNECTED(00000005)
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = 145.100.57.105.surf-hosted.nl
verify return:1
---
Certificate chain
 0 s:CN = 145.100.57.105.surf-hosted.nl
   i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
 1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
   i:O = Digital Signature Trust Co., CN = DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFcTCCBFmgAwIBAgISAxA+MIkEpMc+JZEnhsWHqhSiMA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0yMDA3MjUxNDM2NDdaFw0y
MDEwMjMxNDM2NDdaMCgxJjAkBgNVBAMTHTE0NS4xMDAuNTcuMTA1LnN1cmYtaG9z
dGVkLm5sMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvrpqHQUU2AMF
KD+aF/XP4qdUe02NiZNG20s1YX8o9T8tVpFlaMbC5GouNpUWvchtRk2uwAEjW7xo
//NCBPi5PuT0pfBz5gBhOpMMs3CXUqKCeFK+HxpWQM6h8+TARlWAfUpJ1EDcEK04
L0Oo0hPiq4utQSNouUpLmRMZtiZNH7ct4nht1JUJFr87p+IV9sDqxkZXdqSGvPyq
El3dJq+id9f3eaPiTypHg08KGEaH6Cujuhrs98p0lXqZMG/dlR7AOtjHbJCaX0WI
iodBri3BrhotMKyMNzWj35rlwf0lJO/vyEf0FanbjWwgfAQSQuTWY3Z4Aerl4DoY
0B063LU+EwIDAQABo4ICcTCCAm0wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQG
CCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBR+vf/J
VqaQVTf6YUJvUxh95h3n5TAfBgNVHSMEGDAWgBSoSmpjBH3duubRObemRWXv86js
oTBvBggrBgEFBQcBAQRjMGEwLgYIKwYBBQUHMAGGImh0dHA6Ly9vY3NwLmludC14
My5sZXRzZW5jcnlwdC5vcmcwLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14
My5sZXRzZW5jcnlwdC5vcmcvMCgGA1UdEQQhMB+CHTE0NS4xMDAuNTcuMTA1LnN1
cmYtaG9zdGVkLm5sMEwGA1UdIARFMEMwCAYGZ4EMAQIBMDcGCysGAQQBgt8TAQEB
MCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly9jcHMubGV0c2VuY3J5cHQub3JnMIIBAwYK
KwYBBAHWeQIEAgSB9ASB8QDvAHUAb1N2rDHwMRnYmQCkURX/dxUcEdkCwQApBo2y
CJo32RMAAAFzhp6XvgAABAMARjBEAiARmq5foTaEABWuwX7XEwkVe7bnml98UGLw
xXNG6DOtnwIgYgw+zA5LZICtlFS6QXXxtjUBZ6eNReieBYFHQywZcf4AdgAHt1wb
5X1o//Gwxh0jFce65ld8V5S3au68YToaadOiHAAAAXOGnpfnAAAEAwBHMEUCIFhg
BCwM0ywDEP23WLRSOdSSSEAiTzAWQiDnT/St7FlHAiEAwOH86Z4dfV6HivcCZmEG
MxsOywJC3JNO0ei0nFZXurIwDQYJKoZIhvcNAQELBQADggEBAFZytDjS2R1jwp8q
2qXp2kl9L33jV5tjAk+q08x0QVLdquBu5QsFjzq6ukZIlZsZV/08Jnb8rn0LaOgg
B2nRlbl4Hmwcb4hL3Zpb7yH0nBZiOAI45SbYC/jnjHG2GzKazvtu/Sx8FYQgmRt+
vEGopOKdXrBd0OAJODV/bbv3SwwrQU0Z5cHriqSYz+Mho7aK57bQp2kuyiznNnuP
VVxC+F0HL/z2jFq2cbjzFJS3tD8nS45ZR3i2dt/QRqcWqWaUVwoSA4DwoJMhoHQu
unMnkBlXJpCodRvTNy/FmLJsCmOZbl2R0PH8Xd9qc4qfBnzzMvyI6iiT1Qb0qFAn
HnciWiE=
-----END CERTIFICATE-----
subject=CN = 145.100.57.105.surf-hosted.nl

issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3

---
No client certificate CA names sent
Peer signing digest: SHA512
Peer signature type: RSA
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3085 bytes and written 457 bytes
Verification: OK
Verified peername: 145.100.57.105.surf-hosted.nl
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: FE1915CF13C685CBE0A3B19238967A3F8B16C2322D69212492404DE230339E09
    Session-ID-ctx: 
    Master-Key: 756B52BC2B2823DD8992E7EE5869CFE929107142AE311B68D9245DF3D049C2FEDE931210F5D11B6F6A3A504923D833D1
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1597482694
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
---



I'm guessing that there is some (greedy) IPv4 matching logic that causes the bare literal IPv4 address to be sent to OpenSSL for verification instead of the entire hostname?
Because the error (X509_V_ERR_IP_ADDRESS_MISMATCH, https://github.com/python/cpython/blob/3.8/Modules/_ssl.c#L666-L670) indicates that OpenSSL is doing an IP address verification instead of a hostname verification.
msg375457 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2020-08-15 11:55
Python uses OpenSSL's a2i_IPADDRESS() to check if the hostname is actually an IP address. I'm surprised as you that the function considers a hostname like 145.100.57.105.surf-hosted.nl as a valid IP address.
msg375458 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2020-08-15 12:06
I filed https://github.com/openssl/openssl/issues/12649 with OpenSSL.
msg391400 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2021-04-19 20:03
There is no progress on the OpenSSL bug yet.
msg399213 - (view) Author: Amir Mohamadi (Amir) * Date: 2021-08-08 10:48
Seems to be solved by https://github.com/openssl/openssl/pull/16201.
I guess we can close this issue.
History
Date User Action Args
2022-04-11 14:59:34adminsetgithub: 85728
2021-08-08 10:48:30Amirsetnosy: + Amir
messages: + msg399213
2021-07-22 13:52:07akvadrakosetnosy: + akvadrako
2021-04-19 20:03:55christian.heimessetmessages: + msg391400
versions: + Python 3.9, Python 3.10
2020-08-15 12:06:59christian.heimessetmessages: + msg375458
2020-08-15 11:55:50christian.heimessetmessages: + msg375457
2020-08-15 09:25:03dnmvissercreate