summaryrefslogtreecommitdiffstats
path: root/src/crypto/x509/root.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/x509/root.go')
-rw-r--r--src/crypto/x509/root.go72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/crypto/x509/root.go b/src/crypto/x509/root.go
new file mode 100644
index 0000000..d6b07a1
--- /dev/null
+++ b/src/crypto/x509/root.go
@@ -0,0 +1,72 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package x509
+
+import (
+ "internal/godebug"
+ "sync"
+)
+
+var (
+ once sync.Once
+ systemRootsMu sync.RWMutex
+ systemRoots *CertPool
+ systemRootsErr error
+ fallbacksSet bool
+)
+
+func systemRootsPool() *CertPool {
+ once.Do(initSystemRoots)
+ systemRootsMu.RLock()
+ defer systemRootsMu.RUnlock()
+ return systemRoots
+}
+
+func initSystemRoots() {
+ systemRootsMu.Lock()
+ defer systemRootsMu.Unlock()
+ systemRoots, systemRootsErr = loadSystemRoots()
+ if systemRootsErr != nil {
+ systemRoots = nil
+ }
+}
+
+var forceFallback = godebug.New("x509usefallbackroots")
+
+// SetFallbackRoots sets the roots to use during certificate verification, if no
+// custom roots are specified and a platform verifier or a system certificate
+// pool is not available (for instance in a container which does not have a root
+// certificate bundle). SetFallbackRoots will panic if roots is nil.
+//
+// SetFallbackRoots may only be called once, if called multiple times it will
+// panic.
+//
+// The fallback behavior can be forced on all platforms, even when there is a
+// system certificate pool, by setting GODEBUG=x509usefallbackroots=1 (note that
+// on Windows and macOS this will disable usage of the platform verification
+// APIs and cause the pure Go verifier to be used). Setting
+// x509usefallbackroots=1 without calling SetFallbackRoots has no effect.
+func SetFallbackRoots(roots *CertPool) {
+ if roots == nil {
+ panic("roots must be non-nil")
+ }
+
+ // trigger initSystemRoots if it hasn't already been called before we
+ // take the lock
+ _ = systemRootsPool()
+
+ systemRootsMu.Lock()
+ defer systemRootsMu.Unlock()
+
+ if fallbacksSet {
+ panic("SetFallbackRoots has already been called")
+ }
+ fallbacksSet = true
+
+ if systemRoots != nil && (systemRoots.len() > 0 || systemRoots.systemPool) && forceFallback.Value() != "1" {
+ return
+ }
+ systemRoots, systemRootsErr = roots, nil
+}