Source file src/crypto/tls/cache.go

     1  // Copyright 2022 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package tls
     6  
     7  import (
     8  	"crypto/x509"
     9  	"runtime"
    10  	"sync"
    11  	"weak"
    12  )
    13  
    14  // weakCertCache provides a cache of *x509.Certificates, allowing multiple
    15  // connections to reuse parsed certificates, instead of re-parsing the
    16  // certificate for every connection, which is an expensive operation.
    17  type weakCertCache struct{ sync.Map }
    18  
    19  func (wcc *weakCertCache) newCert(der []byte) (*x509.Certificate, error) {
    20  	if entry, ok := wcc.Load(string(der)); ok {
    21  		if v := entry.(weak.Pointer[x509.Certificate]).Value(); v != nil {
    22  			return v, nil
    23  		}
    24  	}
    25  
    26  	cert, err := x509.ParseCertificate(der)
    27  	if err != nil {
    28  		return nil, err
    29  	}
    30  
    31  	wp := weak.Make(cert)
    32  	if entry, loaded := wcc.LoadOrStore(string(der), wp); !loaded {
    33  		runtime.AddCleanup(cert, func(_ any) { wcc.CompareAndDelete(string(der), entry) }, any(string(der)))
    34  	} else if v := entry.(weak.Pointer[x509.Certificate]).Value(); v != nil {
    35  		return v, nil
    36  	} else {
    37  		if wcc.CompareAndSwap(string(der), entry, wp) {
    38  			runtime.AddCleanup(cert, func(_ any) { wcc.CompareAndDelete(string(der), wp) }, any(string(der)))
    39  		}
    40  	}
    41  	return cert, nil
    42  }
    43  
    44  var globalCertCache = new(weakCertCache)
    45  

View as plain text