Понимание взаимного TLS, конфиг клиента с именем сервера. - PullRequest
0 голосов
/ 13 ноября 2018

Я пытаюсь понять, как работает взаимный TLS, у меня есть следующий пример:

У меня есть клиент, который хочет подключиться к серверу "svc1.example.com"

но у сервера есть

сертификат сервера с общим именем "svc1.example.cloud" и SAN как "svc.example.test.cloud".

Теперь, когда я делаю GET-запрос, я получаю следующее:

x509: сертификат действителен для svc.example.test.cloud, а не svc1.example.com.

Итак, мой вопрос: нужно ли внести изменения в TLS clientConfig, чтобы включить имя сервера?или я должен добавить пользовательскую функцию verifyPeerCertificate в конфигурацию клиента TLS, что-то вроде ниже?

Пожалуйста, дайте мне знать, что должно быть Servername и что я должен проверять в функции verifyPeerCertificate.

func customverify(customCName func(*x509.Certificate) bool) func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
    if customCName == nil {
        return nil
    }
    return func(_ [][]byte, verifiedChains [][]*x509.Certificate) error {
        for _, certs := range verifiedChains {
            leaf := certs[0]
            if customCName(leaf) {
                return nil
            }
        }
        return fmt.Errorf("client identity verification failed")
    }
}




func configureClient(certFile, keyFile string) (*http.Client, error) {
    certpool, err := addRootCA()
    if err != nil {
        return nil, err
    }

cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
    return nil, err
}
transport := ytls.NewClientTransport()
transport.TLSClientConfig.Certificates = []tls.Certificate{cert}
transport.TLSClientConfig.RootCAs = certpool
//transport.TLSClientConfig.ServerName = expectedCName
transport.TLSClientConfig.VerifyPeerCertificate = customverify(func(cert *x509.Certificate) bool {
    return cert.Subject.CommonName == "svc1.example.cloud"
})

httpClient := &http.Client{Transport: transport}
return httpClient, nil

}

1 Ответ

0 голосов
/ 13 ноября 2018

Начиная с x509: сертификат действителен для svc.example.test.cloud , поэтому transport.TLSClientConfig.ServerName = "svc.example.test.cloud"

С https://golang.org/pkg/crypto/tls/#Config

VerifyPeerCertificate, если не ноль, вызывается после обычного
проверка сертификата клиентом или сервером TLS. Он
получает необработанные сертификаты ASN.1, предоставленные узлом, а также
любые проверенные цепочки, найденные обычной обработкой. Если он возвращает
ошибка, отличная от нуля, квитирование отменяется, и эта ошибка приводит к.

Если обычная проверка не пройдена, рукопожатие будет прервано до
учитывая этот обратный звонок. Если нормальная проверка отключена
установка InsecureSkipVerify или (для сервера), когда ClientAuth равен
RequestClientCert или RequireAnyClientCert, тогда этот обратный вызов будет
следует учитывать, но аргумент validChains всегда будет равен нулю.

Ошибка функции VerifyPeerCertificate (байт rawCerts [] [], VerifiedChains [] [] * x509.Certificate)

То есть, если обычная проверка не удалась, VerifyPeerCertificate не будет вызвано. Также, если обычная проверка пройдена, я не думаю, что вам нужна дополнительная проверка VerifyPeerCertificate.

...