github.com/emmansun/gmsm@v0.29.1/smx509/root.go (about)

     1  package smx509
     2  
     3  import (
     4  	"sync"
     5  
     6  	"github.com/emmansun/gmsm/internal/godebug"
     7  )
     8  
     9  var (
    10  	once           sync.Once
    11  	systemRootsMu  sync.RWMutex
    12  	systemRoots    *CertPool
    13  	systemRootsErr error
    14  	fallbacksSet   bool
    15  )
    16  
    17  func systemRootsPool() *CertPool {
    18  	once.Do(initSystemRoots)
    19  	systemRootsMu.RLock()
    20  	defer systemRootsMu.RUnlock()
    21  	return systemRoots
    22  }
    23  
    24  func initSystemRoots() {
    25  	systemRootsMu.Lock()
    26  	defer systemRootsMu.Unlock()
    27  	systemRoots, systemRootsErr = loadSystemRoots()
    28  	if systemRootsErr != nil {
    29  		systemRoots = nil
    30  	}
    31  }
    32  
    33  // SetFallbackRoots sets the roots to use during certificate verification, if no
    34  // custom roots are specified and a platform verifier or a system certificate
    35  // pool is not available (for instance in a container which does not have a root
    36  // certificate bundle). SetFallbackRoots will panic if roots is nil.
    37  //
    38  // SetFallbackRoots may only be called once, if called multiple times it will
    39  // panic.
    40  //
    41  // The fallback behavior can be forced on all platforms, even when there is a
    42  // system certificate pool, by setting GODEBUG=x509usefallbackroots=1 (note that
    43  // on Windows and macOS this will disable usage of the platform verification
    44  // APIs and cause the pure Go verifier to be used). Setting
    45  // x509usefallbackroots=1 without calling SetFallbackRoots has no effect.
    46  func SetFallbackRoots(roots *CertPool) {
    47  	if roots == nil {
    48  		panic("roots must be non-nil")
    49  	}
    50  
    51  	// trigger initSystemRoots if it hasn't already been called before we
    52  	// take the lock
    53  	_ = systemRootsPool()
    54  
    55  	systemRootsMu.Lock()
    56  	defer systemRootsMu.Unlock()
    57  
    58  	if fallbacksSet {
    59  		panic("SetFallbackRoots has already been called")
    60  	}
    61  	fallbacksSet = true
    62  	if systemRoots != nil && (systemRoots.len() > 0 || systemRoots.systemPool) && (godebug.Get("x509usefallbackroots") != "1") {
    63  		return
    64  	}
    65  	systemRoots, systemRootsErr = roots, nil
    66  }