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 }