mirror of
https://github.com/docker/docs.git
synced 2026-11-05 00:14:17 +03:00
Use most specific CA prefix for pinning
Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
This commit is contained in:
@@ -219,7 +219,7 @@ func TestValidateRootWithoutTOFUS(t *testing.T) {
|
||||
// Temporary directory where test files will be created
|
||||
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
||||
defer os.RemoveAll(tempBaseDir)
|
||||
assert.NoError(t, err, "failed to create a temporary directory: %s", err)
|
||||
require.NoError(t, err, "failed to create a temporary directory: %s", err)
|
||||
|
||||
// Create a X509Store
|
||||
trustPath := filepath.Join(tempBaseDir, notary.TrustedCertsDir)
|
||||
@@ -227,7 +227,7 @@ func TestValidateRootWithoutTOFUS(t *testing.T) {
|
||||
trustPath,
|
||||
trustmanager.FilterCertsExpiredSha1,
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("SignedRSARootTemplate").Parse(signedRSARootTemplate)
|
||||
@@ -238,7 +238,7 @@ func TestValidateRootWithoutTOFUS(t *testing.T) {
|
||||
|
||||
// This call to ValidateRoot will fail since we are explicitly disabling TOFU and have no local certs
|
||||
err = ValidateRoot(certStore, &testSignedRoot, "docker.com/notary", notary.TrustPinConfig{TOFU: false})
|
||||
assert.Error(t, err)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestValidateRootWithPinnedCert(t *testing.T) {
|
||||
@@ -248,7 +248,7 @@ func TestValidateRootWithPinnedCert(t *testing.T) {
|
||||
// Temporary directory where test files will be created
|
||||
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
||||
defer os.RemoveAll(tempBaseDir)
|
||||
assert.NoError(t, err, "failed to create a temporary directory: %s", err)
|
||||
require.NoError(t, err, "failed to create a temporary directory: %s", err)
|
||||
|
||||
// Create a X509Store
|
||||
trustPath := filepath.Join(tempBaseDir, notary.TrustedCertsDir)
|
||||
@@ -256,7 +256,7 @@ func TestValidateRootWithPinnedCert(t *testing.T) {
|
||||
trustPath,
|
||||
trustmanager.FilterCertsExpiredSha1,
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("SignedRSARootTemplate").Parse(signedRSARootTemplate)
|
||||
@@ -267,7 +267,7 @@ func TestValidateRootWithPinnedCert(t *testing.T) {
|
||||
|
||||
// This call to ValidateRoot should succeed with the correct Cert ID (same as root public key ID)
|
||||
err = ValidateRoot(certStore, &testSignedRoot, "docker.com/notary", notary.TrustPinConfig{Certs: map[string]string{"docker.com/notary": rootPubKeyID}})
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestValidateRootFailuresWithPinnedCert(t *testing.T) {
|
||||
@@ -277,7 +277,7 @@ func TestValidateRootFailuresWithPinnedCert(t *testing.T) {
|
||||
// Temporary directory where test files will be created
|
||||
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
||||
defer os.RemoveAll(tempBaseDir)
|
||||
assert.NoError(t, err, "failed to create a temporary directory: %s", err)
|
||||
require.NoError(t, err, "failed to create a temporary directory: %s", err)
|
||||
|
||||
// Create a X509Store
|
||||
trustPath := filepath.Join(tempBaseDir, notary.TrustedCertsDir)
|
||||
@@ -285,7 +285,7 @@ func TestValidateRootFailuresWithPinnedCert(t *testing.T) {
|
||||
trustPath,
|
||||
trustmanager.FilterCertsExpiredSha1,
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("SignedRSARootTemplate").Parse(signedRSARootTemplate)
|
||||
@@ -296,23 +296,23 @@ func TestValidateRootFailuresWithPinnedCert(t *testing.T) {
|
||||
|
||||
// This call to ValidateRoot should fail due to an incorrect cert ID
|
||||
err = ValidateRoot(certStore, &testSignedRoot, "docker.com/notary", notary.TrustPinConfig{Certs: map[string]string{"docker.com/notary": "ABSOLUTELY NOT A CERT ID"}})
|
||||
assert.Error(t, err)
|
||||
require.Error(t, err)
|
||||
|
||||
// This call to ValidateRoot should fail due to an empty cert ID
|
||||
err = ValidateRoot(certStore, &testSignedRoot, "docker.com/notary", notary.TrustPinConfig{Certs: map[string]string{"docker.com/notary": ""}})
|
||||
assert.Error(t, err)
|
||||
require.Error(t, err)
|
||||
|
||||
// This call to ValidateRoot should fail due to an invalid GUN (even though the cert ID is correct), and TOFUS defaults to false
|
||||
err = ValidateRoot(certStore, &testSignedRoot, "docker.com/notary", notary.TrustPinConfig{Certs: map[string]string{"not_a_gun": rootPubKeyID}, TOFU: false})
|
||||
assert.Error(t, err)
|
||||
require.Error(t, err)
|
||||
|
||||
// This call to ValidateRoot should fail due to an invalid cert ID, even though it's a valid key ID for targets
|
||||
err = ValidateRoot(certStore, &testSignedRoot, "docker.com/notary", notary.TrustPinConfig{Certs: map[string]string{"docker.com/notary": targetsPubKeyID}})
|
||||
assert.Error(t, err)
|
||||
require.Error(t, err)
|
||||
|
||||
// This call to ValidateRoot should succeed because we fall through to TOFUS even though we have no matching GUNs under Certs
|
||||
err = ValidateRoot(certStore, &testSignedRoot, "docker.com/notary", notary.TrustPinConfig{Certs: map[string]string{"not_a_gun": rootPubKeyID}, TOFU: true})
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestValidateRootWithPinnedCA(t *testing.T) {
|
||||
@@ -322,7 +322,7 @@ func TestValidateRootWithPinnedCA(t *testing.T) {
|
||||
// Temporary directory where test files will be created
|
||||
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
||||
defer os.RemoveAll(tempBaseDir)
|
||||
assert.NoError(t, err, "failed to create a temporary directory: %s", err)
|
||||
require.NoError(t, err, "failed to create a temporary directory: %s", err)
|
||||
|
||||
// Create a X509Store
|
||||
trustPath := filepath.Join(tempBaseDir, notary.TrustedCertsDir)
|
||||
@@ -330,7 +330,7 @@ func TestValidateRootWithPinnedCA(t *testing.T) {
|
||||
trustPath,
|
||||
trustmanager.FilterCertsExpiredSha1,
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
templ, _ := template.New("SignedRSARootTemplate").Parse(signedRSARootTemplate)
|
||||
templ.Execute(&signedRootBytes, SignedRSARootTemplate{RootPem: validPEMEncodedRSARoot})
|
||||
@@ -339,42 +339,42 @@ func TestValidateRootWithPinnedCA(t *testing.T) {
|
||||
|
||||
// This call to ValidateRoot will fail because we have an invalid path for the CA
|
||||
err = ValidateRoot(certStore, &testSignedRoot, "docker.com/notary", notary.TrustPinConfig{CA: map[string]string{"docker.com/notary": filepath.Join(tempBaseDir, "nonexistent")}})
|
||||
assert.Error(t, err)
|
||||
require.Error(t, err)
|
||||
|
||||
// This call to ValidateRoot will fail because we have no valid GUNs to use, and TOFUS is disabled
|
||||
err = ValidateRoot(certStore, &testSignedRoot, "docker.com/notary", notary.TrustPinConfig{CA: map[string]string{"othergun": filepath.Join(tempBaseDir, "nonexistent")}, TOFU: false})
|
||||
assert.Error(t, err)
|
||||
require.Error(t, err)
|
||||
|
||||
// Write an invalid CA cert (not even a PEM) to the tempDir and ensure validation fails when using it
|
||||
invalidCAFilepath := filepath.Join(tempBaseDir, "invalid.ca")
|
||||
assert.NoError(t, ioutil.WriteFile(invalidCAFilepath, []byte("ABSOLUTELY NOT A PEM"), 0644))
|
||||
require.NoError(t, ioutil.WriteFile(invalidCAFilepath, []byte("ABSOLUTELY NOT A PEM"), 0644))
|
||||
|
||||
// Using this invalid CA cert should fail on ValidateRoot
|
||||
err = ValidateRoot(certStore, &testSignedRoot, "docker.com/notary", notary.TrustPinConfig{CA: map[string]string{"docker.com/notary": invalidCAFilepath}, TOFU: false})
|
||||
assert.Error(t, err)
|
||||
require.Error(t, err)
|
||||
|
||||
validCAFilepath := "../fixtures/root-ca.crt"
|
||||
|
||||
// If we pass an invalid Certs entry in addition to this valid CA entry, since Certs has priority for pinning we will fail
|
||||
err = ValidateRoot(certStore, &testSignedRoot, "docker.com/notary", notary.TrustPinConfig{Certs: map[string]string{"docker.com/notary": "invalidID"}, CA: map[string]string{"docker.com/notary": validCAFilepath}, TOFU: false})
|
||||
assert.Error(t, err)
|
||||
require.Error(t, err)
|
||||
|
||||
// Now construct a new root with a valid cert chain, such that signatures are correct over the 'notary-signer' GUN. Pin the root-ca and validate
|
||||
leafCert, err := trustmanager.LoadCertFromFile("../fixtures/notary-signer.crt")
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
pemLeafBytes := trustmanager.CertToPEM(leafCert)
|
||||
newRootLeafKey := data.NewPublicKey(data.RSAx509Key, pemLeafBytes)
|
||||
|
||||
intermediateCert, err := trustmanager.LoadCertFromFile("../fixtures/intermediate-ca.crt")
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
pemChainBytes, err := trustmanager.CertChainToPEM([]*x509.Certificate{leafCert, intermediateCert})
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
newRootKey := data.NewPublicKey(data.RSAx509Key, pemChainBytes)
|
||||
|
||||
rootRole, err := data.NewRole(data.CanonicalRootRole, 1, []string{newRootKey.ID()}, nil)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
testRoot, err := data.NewRoot(
|
||||
map[string]data.PublicKey{newRootKey.ID(): newRootKey},
|
||||
@@ -385,31 +385,31 @@ func TestValidateRootWithPinnedCA(t *testing.T) {
|
||||
data.CanonicalSnapshotRole: &rootRole.RootRole},
|
||||
false,
|
||||
)
|
||||
assert.NoError(t, err, "Failed to create new root")
|
||||
require.NoError(t, err, "Failed to create new root")
|
||||
|
||||
keyReader, err := os.Open("../fixtures/notary-signer.key")
|
||||
assert.NoError(t, err, "could not open key file")
|
||||
require.NoError(t, err, "could not open key file")
|
||||
pemBytes, err := ioutil.ReadAll(keyReader)
|
||||
assert.NoError(t, err, "could not read key file")
|
||||
require.NoError(t, err, "could not read key file")
|
||||
privKey, err := trustmanager.ParsePEMPrivateKey(pemBytes, "")
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
store, err := trustmanager.NewKeyFileStore(tempBaseDir, passphraseRetriever)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
cs := cryptoservice.NewCryptoService(store)
|
||||
|
||||
err = store.AddKey(trustmanager.KeyInfo{Role: data.CanonicalRootRole, Gun: "notary-signer"}, privKey)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
newTestSignedRoot, err := testRoot.ToSigned()
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = signed.Sign(cs, newTestSignedRoot, newRootLeafKey)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Check that we validate correctly against a pinned CA and provided bundle
|
||||
err = ValidateRoot(certStore, newTestSignedRoot, "notary-signer", notary.TrustPinConfig{CA: map[string]string{"notary-signer": validCAFilepath}, TOFU: false})
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// TestValidateSuccessfulRootRotation runs through a full root certificate rotation
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"fmt"
|
||||
"github.com/docker/notary"
|
||||
"github.com/docker/notary/trustmanager"
|
||||
"github.com/docker/notary/tuf/utils"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -32,36 +31,35 @@ func NewTrustPinChecker(trustPinConfig notary.TrustPinConfig, gun string) (Trust
|
||||
// Determine the mode, and if it's even valid
|
||||
if _, ok := trustPinConfig.Certs[gun]; ok {
|
||||
trustPinChecker.mode = certs
|
||||
} else if utils.ContainsKeyPrefix(trustPinConfig.CA, gun) {
|
||||
trustPinChecker.mode = ca
|
||||
for caGunPrefix, caFilepath := range trustPinConfig.CA {
|
||||
if strings.HasPrefix(gun, caGunPrefix) {
|
||||
// Try to add the CA cert to our certificate store,
|
||||
// and use it to validate certs in the root.json later
|
||||
caCert, err := trustmanager.LoadCertFromFile(caFilepath)
|
||||
if err != nil {
|
||||
return TrustPinChecker{}, fmt.Errorf("could not load root cert from CA path")
|
||||
}
|
||||
if err = trustmanager.ValidateCertificate(caCert); err != nil {
|
||||
return TrustPinChecker{}, fmt.Errorf("invalid CA cert provided")
|
||||
}
|
||||
// Now only consider certificates that are direct children from this CA cert, overwriting allValidCerts
|
||||
caRootPool := x509.NewCertPool()
|
||||
caRootPool.AddCert(caCert)
|
||||
if err != nil {
|
||||
return TrustPinChecker{}, fmt.Errorf("unable to initialize CA cert pool")
|
||||
}
|
||||
trustPinChecker.pinnedCAPool = caRootPool
|
||||
return trustPinChecker, nil
|
||||
}
|
||||
}
|
||||
|
||||
} else if trustPinConfig.TOFU {
|
||||
trustPinChecker.mode = tofus
|
||||
} else {
|
||||
return TrustPinChecker{}, fmt.Errorf("no trust pinning specified")
|
||||
return trustPinChecker, nil
|
||||
}
|
||||
return trustPinChecker, nil
|
||||
|
||||
if caFilepath, err := trustPinChecker.getCAFilepathByPrefix(gun); err == nil {
|
||||
trustPinChecker.mode = ca
|
||||
// Try to add the CA certs from its bundle file to our certificate store,
|
||||
// and use it to validate certs in the root.json later
|
||||
caCerts, err := trustmanager.LoadCertBundleFromFile(caFilepath)
|
||||
if err != nil {
|
||||
return TrustPinChecker{}, fmt.Errorf("could not load root cert from CA path")
|
||||
}
|
||||
if err = trustmanager.ValidateCertificate(caCerts); err != nil {
|
||||
return TrustPinChecker{}, fmt.Errorf("invalid CA cert provided")
|
||||
}
|
||||
// Now only consider certificates that are direct children from this CA cert, overwriting allValidCerts
|
||||
caRootPool := x509.NewCertPool()
|
||||
caRootPool.AddCert(caCerts)
|
||||
if err != nil {
|
||||
return TrustPinChecker{}, fmt.Errorf("unable to initialize CA cert pool")
|
||||
}
|
||||
trustPinChecker.pinnedCAPool = caRootPool
|
||||
return trustPinChecker, nil
|
||||
}
|
||||
|
||||
if trustPinConfig.TOFU {
|
||||
trustPinChecker.mode = tofus
|
||||
return trustPinChecker, nil
|
||||
}
|
||||
return TrustPinChecker{}, fmt.Errorf("invalid trust pinning specified")
|
||||
}
|
||||
|
||||
func (t TrustPinChecker) checkCert(leafCert *x509.Certificate, intCerts []*x509.Certificate) bool {
|
||||
@@ -88,3 +86,22 @@ func (t TrustPinChecker) checkCert(leafCert *x509.Certificate, intCerts []*x509.
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Will return the CA filepath corresponding to the most specific (longest) entry in the map that is still a prefix
|
||||
// of the provided gun. Returns an error if no entry matches this GUN as a prefix.
|
||||
func (t TrustPinChecker) getCAFilepathByPrefix(gun string) (string, error) {
|
||||
specificGUN := ""
|
||||
specificCAFilepath := ""
|
||||
foundCA := false
|
||||
for gunPrefix, caFilepath := range t.config.CA {
|
||||
if strings.HasPrefix(gun, gunPrefix) && len(gunPrefix) >= len(specificGUN) {
|
||||
specificGUN = gunPrefix
|
||||
specificCAFilepath = caFilepath
|
||||
foundCA = true
|
||||
}
|
||||
}
|
||||
if !foundCA {
|
||||
return "", fmt.Errorf("could not find pinned CA for GUN: %s\n", gun)
|
||||
}
|
||||
return specificCAFilepath, nil
|
||||
}
|
||||
|
||||
@@ -384,7 +384,7 @@ func TestConfigFileTrustPinning(t *testing.T) {
|
||||
CAFile: "../../fixtures/root-ca.crt",
|
||||
ClientAuth: tls.RequireAndVerifyClientCert,
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
s.StartTLS()
|
||||
defer s.Close()
|
||||
|
||||
@@ -406,7 +406,7 @@ func TestConfigFileTrustPinning(t *testing.T) {
|
||||
// set a config file, so it doesn't check ~/.notary/config.json by default,
|
||||
// and execute a random command so that the flags are parsed
|
||||
cwd, err := os.Getwd()
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
cmd := commander.GetCommand()
|
||||
cmd.SetArgs([]string{
|
||||
@@ -416,17 +416,17 @@ func TestConfigFileTrustPinning(t *testing.T) {
|
||||
"--tlskey", "../../fixtures/notary-server.key"})
|
||||
cmd.SetOutput(new(bytes.Buffer)) // eat the output
|
||||
err = cmd.Execute()
|
||||
assert.Error(t, err, "there was no repository, so list should have failed")
|
||||
assert.NotContains(t, err.Error(), "TLS", "there was no TLS error though!")
|
||||
require.Error(t, err, "there was no repository, so list should have failed")
|
||||
require.NotContains(t, err.Error(), "TLS", "there was no TLS error though!")
|
||||
|
||||
// Check that tofu was set correctly
|
||||
config, err := commander.parseConfig()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, true, config.GetBool("trust_pinning.tofu"))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, true, config.GetBool("trust_pinning.tofu"))
|
||||
|
||||
// validate that we actually managed to connect and attempted to download the root though
|
||||
assert.Len(t, m.gotten, 1)
|
||||
assert.Equal(t, m.gotten[0], "repo.root")
|
||||
require.Len(t, m.gotten, 1)
|
||||
require.Equal(t, m.gotten[0], "repo.root")
|
||||
|
||||
tempDir2 := tempDirWithConfig(t, fmt.Sprintf(`{
|
||||
"remote_server": {
|
||||
@@ -447,15 +447,15 @@ func TestConfigFileTrustPinning(t *testing.T) {
|
||||
"--tlskey", "../../fixtures/notary-server.key"})
|
||||
cmd.SetOutput(new(bytes.Buffer)) // eat the output
|
||||
err = cmd.Execute()
|
||||
assert.Error(t, err, "there was no repository, so list should have failed")
|
||||
assert.NotContains(t, err.Error(), "TLS", "there was no TLS error though!")
|
||||
require.Error(t, err, "there was no repository, so list should have failed")
|
||||
require.NotContains(t, err.Error(), "TLS", "there was no TLS error though!")
|
||||
|
||||
config, err = commander.parseConfig()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, false, config.GetBool("trust_pinning.tofu"))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, false, config.GetBool("trust_pinning.tofu"))
|
||||
|
||||
// Even though TOFUS will fail, we'll have successfully parsed the config and attempted to retrieve the root
|
||||
assert.Len(t, m.gotten, 2)
|
||||
require.Len(t, m.gotten, 2)
|
||||
|
||||
tempDir = tempDirWithConfig(t, fmt.Sprintf(`{
|
||||
"remote_server": {
|
||||
@@ -478,15 +478,15 @@ func TestConfigFileTrustPinning(t *testing.T) {
|
||||
"--tlskey", "../../fixtures/notary-server.key"})
|
||||
cmd.SetOutput(new(bytes.Buffer)) // eat the output
|
||||
err = cmd.Execute()
|
||||
assert.Error(t, err, "there was no repository, so list should have failed")
|
||||
assert.NotContains(t, err.Error(), "TLS", "there was no TLS error though!")
|
||||
require.Error(t, err, "there was no repository, so list should have failed")
|
||||
require.NotContains(t, err.Error(), "TLS", "there was no TLS error though!")
|
||||
|
||||
config, err = commander.parseConfig()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, strings.Repeat("x", notary.Sha256HexSize), config.GetStringMap("trust_pinning.certs")["repo3"])
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, strings.Repeat("x", notary.Sha256HexSize), config.GetStringMap("trust_pinning.certs")["repo3"])
|
||||
|
||||
// Even though specified certs will fail, we'll have successfully parsed the config and attempted to retrieve the root
|
||||
assert.Len(t, m.gotten, 3)
|
||||
require.Len(t, m.gotten, 3)
|
||||
|
||||
tempDir = tempDirWithConfig(t, fmt.Sprintf(`{
|
||||
"remote_server": {
|
||||
@@ -509,13 +509,13 @@ func TestConfigFileTrustPinning(t *testing.T) {
|
||||
"--tlskey", "../../fixtures/notary-server.key"})
|
||||
cmd.SetOutput(new(bytes.Buffer)) // eat the output
|
||||
err = cmd.Execute()
|
||||
assert.Error(t, err, "there was no repository, so list should have failed")
|
||||
assert.NotContains(t, err.Error(), "TLS", "there was no TLS error though!")
|
||||
require.Error(t, err, "there was no repository, so list should have failed")
|
||||
require.NotContains(t, err.Error(), "TLS", "there was no TLS error though!")
|
||||
|
||||
config, err = commander.parseConfig()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "root-ca.crt", config.GetStringMap("trust_pinning.ca")["repo4"])
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "root-ca.crt", config.GetStringMap("trust_pinning.ca")["repo4"])
|
||||
|
||||
// Even though specified ca will fail, we'll have successfully parsed the config and attempted to retrieve the root
|
||||
assert.Len(t, m.gotten, 4)
|
||||
require.Len(t, m.gotten, 4)
|
||||
}
|
||||
|
||||
@@ -154,7 +154,9 @@ bootstrapping of the repo.
|
||||
<td valign="top"><code>ca</code></td>
|
||||
<td valign="top">no</td>
|
||||
<td valign="top"><p>Mapping of GUN prefixes to filepaths containing
|
||||
the root CA with which to verify the certificates in the root file.
|
||||
the root CA file with which to verify the certificates in the root file.
|
||||
This file can contain multiple root certificates, bundled in separate
|
||||
PEM blocks.
|
||||
The path is relative to the directory of the configuration file.</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -67,16 +67,6 @@ func StrSliceContainsI(ss []string, s string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ContainsKeyPrefix checks if the given string map contains a key that prefixes the desired key
|
||||
func ContainsKeyPrefix(smap map[string]string, s string) bool {
|
||||
for k := range smap {
|
||||
if strings.HasPrefix(s, k) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// FileExists returns true if a file (or dir) exists at the given path,
|
||||
// false otherwise
|
||||
func FileExists(path string) bool {
|
||||
|
||||
Reference in New Issue
Block a user