Howto fix x509: cannot validate certificate for <ip> because it doesn't contain any IP SANs
Asked Answered
L

1

9

I'm using go http client to connect to iot device which has self-signed cert. I already have

    TLSClientConfig: &tls.Config{
        RootCAs:            certPool,
        Certificates:       []tls.Certificate{tlsClientCert},
        InsecureSkipVerify: true,
    },

Nevertheless although InsecureSkipVerify=true go still tries to verify the certificate:

x509: cannot validate certificate for <ip> because it doesn't contain any IP SANs

As I can't change the cert on the device- what part of the TLS client config can I modify to accept it?

UPDATE

The go error can be reproduced running https://github.com/jbardin/gotlsscan/blob/master/main.go against the device:

Testing TLS1.2
    ...
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA            [NOT SUPPORTED]
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256       [NOT SUPPORTED] x509: cannot validate certificate for 192.168.1.145 because it doesn't contain any IP SANs
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256         [NOT SUPPORTED]
    ...
    

This is what openssl says when running openssl s_client -connect <ip:port>:

CONNECTED(00000003)
depth=0 C = DE, O = Bebro, OU = ULK High GEN 1, CN = ICCPD...
verify error:num=18:self signed certificate
verify return:1
depth=0 C = DE, O = Bebro, OU = ULK High GEN 1, CN = ICCPD...
verify return:1
4460842604:error:1401E410:SSL routines:CONNECT_CR_FINISHED:sslv3 alert handshake failure:/AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-47.140.1/libressl-2.8/ssl/ssl_pkt.c:1200:SSL alert number 40
4460842604:error:1401E0E5:SSL routines:CONNECT_CR_FINISHED:ssl handshake failure:/AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-47.140.1/libressl-2.8/ssl/ssl_pkt.c:585:
---
Certificate chain
0 s:/C=DE/O=Bebro/OU=ULK High GEN 1/CN=ICCPD...
  i:/C=DE/O=Bebro/OU=ULK High GEN 1/CN=ICCPD...
---
Server certificate
-----BEGIN CERTIFICATE-----
MII...
-----END CERTIFICATE-----
subject=/C=DE/O=Bebro/OU=ULK High GEN 1/CN=ICCPD...
issuer=/C=DE/O=Bebro/OU=ULK High GEN 1/CN=ICCPD...
---
No client certificate CA names sent
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 969 bytes and written 178 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-ECDSA-AES128-SHA256
Server public key is 256 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-ECDSA-AES128-SHA256
    Session-ID: 9C7D...
    Session-ID-ctx:
    Master-Key: AC9E...
    Start Time: 1600892515
    Timeout   : 7200 (sec)
    Verify return code: 18 (self signed certificate)
---

UPDATE I'm running latest go 1.15.2

Lambertson answered 23/9, 2020 at 20:53 Comment(9)
You could specify a Host in your request that is in the cert's SANs.Rubberneck
All I have is the device's name from DNS-SD. As part of the application I don't even get as far as reading its cert/SAN so not sure how I would do that. Also: the error message contains the remote IP so its the local go client complaining. It shouldn't even try to validate the certificate here?Lambertson
@andig: Setting InsecureSkipVerify ought to be enough, and I suspect the problem lies elsewhere. Can you post a minimal but complete working program that demonstrates the problem, along with the complete error message?Fowling
I've updated example and openssl diagnosis.Lambertson
Can you please provide the go code snippet where you are making the request?Penelope
It‘s exactly the application mentioned above, see github.com/jbardin/gotlsscan/blob/master/main.go#L89. My code is more convoluted but leads to the same error as linked repo.Lambertson
@andig: Thanks for providing that. Which version of Go are you using? A few suggestions to try: (1) output the value of insecure, just to make absolutely sure it's really being set to true - stranger things have happened; (2) you should generally either set ServerName or InsecureSkipVerify, but not both, so try not setting ServerName if insecure is true; (3) you shouldn't modify a tls.Config after it's been passed to a tls package function, so try moving its definition inside your inner loop to create a new config each time.Fowling
@Fowling I'm facing similar issue, I've pykmip server running in one VM(10.20.30.40) and i'm trying to make connection to that server using client certificate, here , my requirement is not to use InsecureSkipVerify to true, but false. After some search some places it mentioned to add SAN in certificate , hence added the same, so certificate will contain one filed called SAN and it will have some value, I configured "ServerName" with the same name but couldn't succeed. Is there any other way to implement this ?Curia
@imaheshwarans: That sounds like a question, not a comment, so I suggest you ask a question, including all the relevant details.Fowling
C
1

This might work,

In certificate there is a field called "SANs", we need to add 'hostname' in this SAN list.

Properties

once this is added the same name should be added in TLS configuration using "ServerName" filed. after this configuration this will be resolved. In SANS property I've added "test.com" so I configured TLS as follows,

        ServerName:   "test.com",
        RootCAs:      pool,
        Certificates: []tls.Certificate{clientCert},
        MinVersion:   tls.VersionTLS12,

Since the certificate you;re using may not contain any SANs, this error is occurred. I'm still exploring on it, If you guys any comments on this ,kindly leave a reply.

Curia answered 20/5, 2021 at 5:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.