mirror of
https://github.com/golang/go
synced 2024-11-26 19:51:17 -07:00
crypto/tls: use certificate cache in client
In verifyServerCertificate parse certificates using the global certificate cache. This should signficiantly reduce memory usage in TLS clients which make concurrent connections which reuse certificates (anywhere in the chain) since there will only ever be one copy of the certificate at once. Fixes #46035 Change-Id: Icf5153d0ea3c14a0bdc8b26c794f21153bf95f85 Reviewed-on: https://go-review.googlesource.com/c/go/+/426455 Reviewed-by: Heschi Kreinick <heschi@google.com> Reviewed-by: Bryan Mills <bcmills@google.com> Run-TryBot: Roland Shoemaker <roland@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Filippo Valsorda <filippo@golang.org>
This commit is contained in:
parent
601ad2e457
commit
72ce9ba9cb
@ -39,6 +39,8 @@ type certCache struct {
|
||||
sync.Map
|
||||
}
|
||||
|
||||
var clientCertCache = new(certCache)
|
||||
|
||||
// activeCert is a handle to a certificate held in the cache. Once there are
|
||||
// no alive activeCerts for a given certificate, the certificate is removed
|
||||
// from the cache by a finalizer.
|
||||
|
@ -49,6 +49,9 @@ type Conn struct {
|
||||
ocspResponse []byte // stapled OCSP response
|
||||
scts [][]byte // signed certificate timestamps from server
|
||||
peerCertificates []*x509.Certificate
|
||||
// activeCertHandles contains the cache handles to certificates in
|
||||
// peerCertificates that are used to track active references.
|
||||
activeCertHandles []*activeCert
|
||||
// verifiedChains contains the certificate chains that we built, as
|
||||
// opposed to the ones presented by the server.
|
||||
verifiedChains [][]*x509.Certificate
|
||||
|
@ -849,14 +849,16 @@ func (hs *clientHandshakeState) sendFinished(out []byte) error {
|
||||
// verifyServerCertificate parses and verifies the provided chain, setting
|
||||
// c.verifiedChains and c.peerCertificates or sending the appropriate alert.
|
||||
func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
|
||||
activeHandles := make([]*activeCert, len(certificates))
|
||||
certs := make([]*x509.Certificate, len(certificates))
|
||||
for i, asn1Data := range certificates {
|
||||
cert, err := x509.ParseCertificate(asn1Data)
|
||||
cert, err := clientCertCache.newCert(asn1Data)
|
||||
if err != nil {
|
||||
c.sendAlert(alertBadCertificate)
|
||||
return errors.New("tls: failed to parse certificate from server: " + err.Error())
|
||||
}
|
||||
certs[i] = cert
|
||||
activeHandles[i] = cert
|
||||
certs[i] = cert.cert
|
||||
}
|
||||
|
||||
if !c.config.InsecureSkipVerify {
|
||||
@ -886,6 +888,7 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
|
||||
return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
|
||||
}
|
||||
|
||||
c.activeCertHandles = activeHandles
|
||||
c.peerCertificates = certs
|
||||
|
||||
if c.config.VerifyPeerCertificate != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user