mirror of https://go.googlesource.com/go
86 lines
2.3 KiB
Go
86 lines
2.3 KiB
Go
// 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"
|
|
_ "unsafe" // for linkname
|
|
)
|
|
|
|
// systemRoots should be an internal detail,
|
|
// but widely used packages access it using linkname.
|
|
// Notable members of the hall of shame include:
|
|
// - github.com/breml/rootcerts
|
|
//
|
|
// Do not remove or change the type signature.
|
|
// See go.dev/issue/67401.
|
|
//
|
|
//go:linkname systemRoots
|
|
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 x509usefallbackroots = 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) {
|
|
if x509usefallbackroots.Value() != "1" {
|
|
return
|
|
}
|
|
x509usefallbackroots.IncNonDefault()
|
|
}
|
|
systemRoots, systemRootsErr = roots, nil
|
|
}
|