Add permitted dns domains to pki (#3164)

This commit is contained in:
Jeff Mitchell
2017-08-15 16:10:36 -04:00
committed by GitHub
parent 542b5da8f2
commit e6b43f7278
4 changed files with 256 additions and 6 deletions

View File

@@ -2264,6 +2264,172 @@ func TestBackend_Root_Idempotentcy(t *testing.T) {
}
}
func TestBackend_Permitted_DNS_Domains(t *testing.T) {
coreConfig := &vault.CoreConfig{
LogicalBackends: map[string]logical.Factory{
"pki": Factory,
},
}
cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
HandlerFunc: vaulthttp.Handler,
})
cluster.Start()
defer cluster.Cleanup()
client := cluster.Cores[0].Client
var err error
err = client.Sys().Mount("root", &api.MountInput{
Type: "pki",
Config: api.MountConfigInput{
DefaultLeaseTTL: "16h",
MaxLeaseTTL: "32h",
},
})
if err != nil {
t.Fatal(err)
}
err = client.Sys().Mount("int", &api.MountInput{
Type: "pki",
Config: api.MountConfigInput{
DefaultLeaseTTL: "4h",
MaxLeaseTTL: "20h",
},
})
if err != nil {
t.Fatal(err)
}
_, err = client.Logical().Write("root/roles/example", map[string]interface{}{
"allowed_domains": "foobar.com,zipzap.com,abc.com,xyz.com",
"allow_bare_domains": true,
"allow_subdomains": true,
"max_ttl": "2h",
})
if err != nil {
t.Fatal(err)
}
_, err = client.Logical().Write("int/roles/example", map[string]interface{}{
"allowed_domains": "foobar.com,zipzap.com,abc.com,xyz.com",
"allow_subdomains": true,
"allow_bare_domains": true,
"max_ttl": "2h",
})
if err != nil {
t.Fatal(err)
}
// Direct issuing from root
_, err = client.Logical().Write("root/root/generate/internal", map[string]interface{}{
"common_name": "myvault.com",
"permitted_dns_domains": []string{"foobar.com", ".zipzap.com"},
})
if err != nil {
t.Fatal(err)
}
clientKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
t.Fatal(err)
}
path := "root/"
checkIssue := func(valid bool, args ...interface{}) {
argMap := map[string]interface{}{}
var currString string
for i, arg := range args {
if i%2 == 0 {
currString = arg.(string)
} else {
argMap[currString] = arg
}
}
_, err = client.Logical().Write(path+"issue/example", argMap)
switch {
case valid && err != nil:
t.Fatal(err)
case !valid && err == nil:
t.Fatal("expected error")
}
csr, err := x509.CreateCertificateRequest(rand.Reader, &x509.CertificateRequest{
Subject: pkix.Name{
CommonName: argMap["common_name"].(string),
},
}, clientKey)
if err != nil {
t.Fatal(err)
}
delete(argMap, "common_name")
argMap["csr"] = string(pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE REQUEST",
Bytes: csr,
}))
_, err = client.Logical().Write(path+"sign/example", argMap)
switch {
case valid && err != nil:
t.Fatal(err)
case !valid && err == nil:
t.Fatal("expected error")
}
}
// Check issuing and signing against root's permitted domains
checkIssue(false, "common_name", "zipzap.com")
checkIssue(false, "common_name", "host.foobar.com")
checkIssue(true, "common_name", "host.zipzap.com")
checkIssue(true, "common_name", "foobar.com")
// Verify that root also won't issue an intermediate outside of its permitted domains
resp, err := client.Logical().Write("int/intermediate/generate/internal", map[string]interface{}{
"common_name": "issuer.abc.com",
})
if err != nil {
t.Fatal(err)
}
_, err = client.Logical().Write("root/root/sign-intermediate", map[string]interface{}{
"common_name": "issuer.abc.com",
"csr": resp.Data["csr"],
"permitted_dns_domains": []string{"abc.com", ".xyz.com"},
"ttl": "5h",
})
if err == nil {
t.Fatal("expected error")
}
_, err = client.Logical().Write("root/root/sign-intermediate", map[string]interface{}{
"use_csr_values": true,
"csr": resp.Data["csr"],
"permitted_dns_domains": []string{"abc.com", ".xyz.com"},
"ttl": "5h",
})
if err == nil {
t.Fatal("expected error")
}
// Sign a valid intermediate
resp, err = client.Logical().Write("root/root/sign-intermediate", map[string]interface{}{
"common_name": "issuer.zipzap.com",
"csr": resp.Data["csr"],
"permitted_dns_domains": []string{"abc.com", ".xyz.com"},
"ttl": "5h",
})
if err != nil {
t.Fatal(err)
}
resp, err = client.Logical().Write("int/intermediate/set-signed", map[string]interface{}{
"certificate": resp.Data["certificate"],
})
if err != nil {
t.Fatal(err)
}
// Check enforcement with the intermediate's set values
path = "int/"
checkIssue(false, "common_name", "host.abc.com")
checkIssue(false, "common_name", "xyz.com")
checkIssue(true, "common_name", "abc.com")
checkIssue(true, "common_name", "host.xyz.com")
}
const (
rsaCAKey string = `-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAmPQlK7xD5p+E8iLQ8XlVmll5uU2NKMxKY3UF5tbh+0vkc+Fy