Как исправить x509: не удается проверить сертификат для , потому что он не содержит никаких IP-адресов

#go #tls1.2 #x509

#Вперед #tls1.2 #x509

Вопрос:

Я использую http-клиент go для подключения к устройству iot, у которого есть самозаверяющий сертификат. У меня уже есть

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

Тем не менее, хотя InsecureSkipVerify=true go все еще пытается проверить сертификат:

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

Поскольку я не могу изменить сертификат на устройстве — какую часть конфигурации клиента TLS я могу изменить, чтобы принять его?

Обновить

Ошибка go может быть воспроизведена при запуске https://github.com/jbardin/gotlsscan/blob/master/main.go против устройства:

 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]
    ...
    
  

Это то, что говорит openssl при запуске 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)
---
  

ОБНОВЛЕНИЕ Я использую последнюю версию go 1.15.2

Комментарии:

1. Вы могли бы указать a Host в своем запросе, который находится в SANS сертификата.

2. Все, что у меня есть, это имя устройства из DNS-SD. Как часть приложения, я даже не могу прочитать его cert / SAN, поэтому не уверен, как я это сделаю. Также: сообщение об ошибке содержит удаленный IP-адрес, поэтому жалуется локальный клиент go. Он даже не должен пытаться проверить сертификат здесь?

3. @andig: настройки InsecureSkipVerify должно быть достаточно, и я подозреваю, что проблема кроется в другом. Можете ли вы опубликовать минимальную, но полную рабочую программу, которая демонстрирует проблему, вместе с полным сообщением об ошибке?

4. Я обновил пример и диагностику openssl.

5. @andig: Спасибо за предоставление этого. Какую версию Go вы используете? Несколько советов, которые можно попробовать: (1) выведите значение insecure , просто чтобы убедиться, что оно действительно установлено true — произошли странные вещи; (2) обычно вы должны либо установить ServerName или InsecureSkipVerify , но не оба, поэтому попробуйте не устанавливать ServerName if insecure is true ; (3) вы не должны изменять a tls.Config после его передачи в tls функцию пакета, поэтому попробуйте переместить его определение внутри вашего внутреннего цикла, чтобы каждый раз создавать новую конфигурацию.

Ответ №1:

Это может сработать,

В сертификате есть поле с именем «SANs», нам нужно добавить «имя хоста» в этот список SAN.

Свойства

после добавления этого в конфигурацию TLS следует добавить то же имя, используя файл «ServerName». после этой настройки эта проблема будет решена. В свойстве SANS я добавил «test.com » итак, я настроил TLS следующим образом,

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

Поскольку используемый вами сертификат может не содержать никаких SANS, возникает эта ошибка. Я все еще изучаю это, если у вас, ребята, есть какие-либо комментарии по этому поводу, пожалуйста, оставьте ответ.