blob: d6b07a18dcf5321141d201bb5d9bbbb94cef284e [file] [log] [blame]
// 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 (
var (
once sync.Once
systemRootsMu sync.RWMutex
systemRoots *CertPool
systemRootsErr error
fallbacksSet bool
func systemRootsPool() *CertPool {
defer systemRootsMu.RUnlock()
return systemRoots
func initSystemRoots() {
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()
defer systemRootsMu.Unlock()
if fallbacksSet {
panic("SetFallbackRoots has already been called")
fallbacksSet = true
if systemRoots != nil && (systemRoots.len() > 0 || systemRoots.systemPool) && forceFallback.Value() != "1" {
systemRoots, systemRootsErr = roots, nil