mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-02 03:27:54 +00:00
Add permitted dns domains to pki (#3164)
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user