From e6e962c15348ee4d155f8f644b293f80b93d171e Mon Sep 17 00:00:00 2001 From: Gabor Tanz Date: Wed, 9 Nov 2022 13:57:34 +0100 Subject: [PATCH 1/4] add custom error type that returns the certificate on verification failure --- api/next/48152.txt | 5 +++++ src/crypto/tls/common.go | 14 ++++++++++++++ src/crypto/tls/handshake_client.go | 2 +- src/crypto/tls/handshake_server.go | 2 +- 4 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 api/next/48152.txt diff --git a/api/next/48152.txt b/api/next/48152.txt new file mode 100644 index 00000000000000..f9dd96e4f06cf0 --- /dev/null +++ b/api/next/48152.txt @@ -0,0 +1,5 @@ +pkg crypto/tls, type CertificateVerificationError struct #48152 +pkg crypto/tls, type CertificateVerificationError, UnverifiedCertificates []*x509.Certificate #48152 +pkg crypto/tls, type CertificateVerificationError, Err error #48152 +pkg crypto/tls, method (*CertificateVerificationError) Error() string #48152 +pkg crypto/tls, method (*CertificateVerificationError) Unwrap() error #48152 \ No newline at end of file diff --git a/src/crypto/tls/common.go b/src/crypto/tls/common.go index 62324de5139b46..72de92f8f42f46 100644 --- a/src/crypto/tls/common.go +++ b/src/crypto/tls/common.go @@ -1493,3 +1493,17 @@ func isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlg } return false } + +// CertificateVerificationError is returned when certificate verification fails during the handshake. +type CertificateVerificationError struct { + UnverifiedCertificates []*x509.Certificate + Err error +} + +func (e *CertificateVerificationError) Error() string { + return fmt.Sprintf("tls: failed to verify certificate: %s", e.Err) +} + +func (e *CertificateVerificationError) Unwrap() error { + return e.Err +} diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go index 2e3b693199620a..7cf906c91d8ee1 100644 --- a/src/crypto/tls/handshake_client.go +++ b/src/crypto/tls/handshake_client.go @@ -876,7 +876,7 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error { c.verifiedChains, err = certs[0].Verify(opts) if err != nil { c.sendAlert(alertBadCertificate) - return err + return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err} } } diff --git a/src/crypto/tls/handshake_server.go b/src/crypto/tls/handshake_server.go index fc0a7ac13d6c8d..682cfc20619f68 100644 --- a/src/crypto/tls/handshake_server.go +++ b/src/crypto/tls/handshake_server.go @@ -831,7 +831,7 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error { chains, err := certs[0].Verify(opts) if err != nil { c.sendAlert(alertBadCertificate) - return errors.New("tls: failed to verify client certificate: " + err.Error()) + return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err} } c.verifiedChains = chains From 0841f68aa8b79cca09aa8a1121f8f59a8500f139 Mon Sep 17 00:00:00 2001 From: Gabor Tanz Date: Wed, 16 Nov 2022 10:42:27 +0100 Subject: [PATCH 2/4] adjust test to check for new error string --- src/net/http/transport_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go index b637e40cb429b7..c0cabccab82b7d 100644 --- a/src/net/http/transport_test.go +++ b/src/net/http/transport_test.go @@ -4818,7 +4818,7 @@ func testTransportEventTraceTLSVerify(t *testing.T, mode testMode) { wantOnce("TLSHandshakeStart") wantOnce("TLSHandshakeDone") - wantOnce("err = x509: certificate is valid for example.com") + wantOnce("err = tls: failed to verify certificate: x509: certificate is valid for example.com") if t.Failed() { t.Errorf("Output:\n%s", got) From fb029bdaeeb69c7488b158b007267cb81e6b73b2 Mon Sep 17 00:00:00 2001 From: Gabor Tanz Date: Wed, 16 Nov 2022 10:44:40 +0100 Subject: [PATCH 3/4] clarify that the contained certificates shouldn't be modified --- src/crypto/tls/common.go | 1 + 1 file changed, 1 insertion(+) diff --git a/src/crypto/tls/common.go b/src/crypto/tls/common.go index 72de92f8f42f46..007f0f47b233c6 100644 --- a/src/crypto/tls/common.go +++ b/src/crypto/tls/common.go @@ -1496,6 +1496,7 @@ func isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlg // CertificateVerificationError is returned when certificate verification fails during the handshake. type CertificateVerificationError struct { + // UnverifiedCertificates and its contents should not be modified. UnverifiedCertificates []*x509.Certificate Err error } From 2b0e982f3f6bca33062b0bbd64ed1804801e2c13 Mon Sep 17 00:00:00 2001 From: Gabor Tanz Date: Fri, 18 Nov 2022 08:55:25 +0100 Subject: [PATCH 4/4] add newline at end of file --- api/next/48152.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/next/48152.txt b/api/next/48152.txt index f9dd96e4f06cf0..41bf99ec3cf1c9 100644 --- a/api/next/48152.txt +++ b/api/next/48152.txt @@ -2,4 +2,4 @@ pkg crypto/tls, type CertificateVerificationError struct #48152 pkg crypto/tls, type CertificateVerificationError, UnverifiedCertificates []*x509.Certificate #48152 pkg crypto/tls, type CertificateVerificationError, Err error #48152 pkg crypto/tls, method (*CertificateVerificationError) Error() string #48152 -pkg crypto/tls, method (*CertificateVerificationError) Unwrap() error #48152 \ No newline at end of file +pkg crypto/tls, method (*CertificateVerificationError) Unwrap() error #48152