ca: add test cases for rotating external trusted CA
This commit is contained in:
parent
aacc40012f
commit
0abaf29c10
|
@ -0,0 +1,3 @@
|
|||
```release-note:feature
|
||||
ca: support using an external root CA with the vault CA provider
|
||||
```
|
|
@ -98,15 +98,26 @@ func TestCAManager_Initialize_Vault_Secondary_SharedVault(t *testing.T) {
|
|||
}
|
||||
|
||||
func verifyLeafCert(t *testing.T, root *structs.CARoot, leafCertPEM string) {
|
||||
t.Helper()
|
||||
roots := structs.IndexedCARoots{
|
||||
ActiveRootID: root.ID,
|
||||
Roots: []*structs.CARoot{root},
|
||||
}
|
||||
verifyLeafCertWithRoots(t, roots, leafCertPEM)
|
||||
}
|
||||
|
||||
func verifyLeafCertWithRoots(t *testing.T, roots structs.IndexedCARoots, leafCertPEM string) {
|
||||
t.Helper()
|
||||
leaf, intermediates, err := connect.ParseLeafCerts(leafCertPEM)
|
||||
require.NoError(t, err)
|
||||
|
||||
pool := x509.NewCertPool()
|
||||
ok := pool.AppendCertsFromPEM([]byte(root.RootCert))
|
||||
for _, r := range roots.Roots {
|
||||
ok := pool.AppendCertsFromPEM([]byte(r.RootCert))
|
||||
if !ok {
|
||||
t.Fatalf("Failed to add root CA PEM to cert pool")
|
||||
}
|
||||
}
|
||||
|
||||
// verify with intermediates from leaf CertPEM
|
||||
_, err = leaf.Verify(x509.VerifyOptions{
|
||||
|
@ -118,11 +129,13 @@ func verifyLeafCert(t *testing.T, root *structs.CARoot, leafCertPEM string) {
|
|||
|
||||
// verify with intermediates from the CARoot
|
||||
intermediates = x509.NewCertPool()
|
||||
for _, intermediate := range root.IntermediateCerts {
|
||||
for _, r := range roots.Roots {
|
||||
for _, intermediate := range r.IntermediateCerts {
|
||||
c, err := connect.ParseCert(intermediate)
|
||||
require.NoError(t, err)
|
||||
intermediates.AddCert(c)
|
||||
}
|
||||
}
|
||||
|
||||
_, err = leaf.Verify(x509.VerifyOptions{
|
||||
Roots: pool,
|
||||
|
@ -628,10 +641,6 @@ func TestCAManager_Initialize_Vault_WithIntermediateAsPrimaryCA(t *testing.T) {
|
|||
"Token": vault.RootToken,
|
||||
"RootPKIPath": meshRootPath,
|
||||
"IntermediatePKIPath": "pki-intermediate/",
|
||||
// TODO: there are failures to init the CA system if these are not set
|
||||
// to the values of the already initialized CA.
|
||||
"PrivateKeyType": "ec",
|
||||
"PrivateKeyBits": 256,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
@ -664,10 +673,6 @@ func TestCAManager_Initialize_Vault_WithIntermediateAsPrimaryCA(t *testing.T) {
|
|||
"Token": vault.RootToken,
|
||||
"RootPKIPath": meshRootPath,
|
||||
"IntermediatePKIPath": "pki-secondary/",
|
||||
// TODO: there are failures to init the CA system if these are not set
|
||||
// to the values of the already initialized CA.
|
||||
"PrivateKeyType": "ec",
|
||||
"PrivateKeyBits": 256,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
@ -727,10 +732,6 @@ func TestCAManager_Initialize_Vault_WithExternalTrustedCA(t *testing.T) {
|
|||
"Token": vault.RootToken,
|
||||
"RootPKIPath": primaryCAPath,
|
||||
"IntermediatePKIPath": "pki-intermediate/",
|
||||
// TODO: there are failures to init the CA system if these are not set
|
||||
// to the values of the already initialized CA.
|
||||
"PrivateKeyType": "ec",
|
||||
"PrivateKeyBits": 256,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
@ -765,15 +766,12 @@ func TestCAManager_Initialize_Vault_WithExternalTrustedCA(t *testing.T) {
|
|||
}
|
||||
})
|
||||
|
||||
// TODO: renew primary leaf signing cert
|
||||
// TODO: rotate root
|
||||
|
||||
runStep(t, "start secondary DC", func(t *testing.T) {
|
||||
joinWAN(t, serverDC2, serverDC1)
|
||||
testrpc.WaitForActiveCARoot(t, serverDC2.RPC, "dc2", nil)
|
||||
|
||||
codec := rpcClient(t, serverDC2)
|
||||
roots := structs.IndexedCARoots{}
|
||||
roots = structs.IndexedCARoots{}
|
||||
err := msgpackrpc.CallWithCodec(codec, "ConnectCA.Roots", &structs.DCSpecificRequest{}, &roots)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, roots.Roots, 1)
|
||||
|
@ -788,6 +786,7 @@ func TestCAManager_Initialize_Vault_WithExternalTrustedCA(t *testing.T) {
|
|||
renewLeafSigningCert(t, serverDC1.caManager, serverDC1.caManager.primaryRenewIntermediate)
|
||||
|
||||
codec := rpcClient(t, serverDC1)
|
||||
roots = structs.IndexedCARoots{}
|
||||
err := msgpackrpc.CallWithCodec(codec, "ConnectCA.Roots", &structs.DCSpecificRequest{}, &roots)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, roots.Roots, 1)
|
||||
|
@ -809,6 +808,7 @@ func TestCAManager_Initialize_Vault_WithExternalTrustedCA(t *testing.T) {
|
|||
renewLeafSigningCert(t, serverDC2.caManager, serverDC2.caManager.secondaryRequestNewSigningCert)
|
||||
|
||||
codec := rpcClient(t, serverDC2)
|
||||
roots = structs.IndexedCARoots{}
|
||||
err := msgpackrpc.CallWithCodec(codec, "ConnectCA.Roots", &structs.DCSpecificRequest{}, &roots)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, roots.Roots, 1)
|
||||
|
@ -824,6 +824,68 @@ func TestCAManager_Initialize_Vault_WithExternalTrustedCA(t *testing.T) {
|
|||
// original certs from old signing cert should still verify
|
||||
verifyLeafCert(t, roots.Roots[0], origLeaf)
|
||||
})
|
||||
|
||||
runStep(t, "rotate root by changing the provider", func(t *testing.T) {
|
||||
codec := rpcClient(t, serverDC1)
|
||||
req := &structs.CARequest{
|
||||
Op: structs.CAOpSetConfig,
|
||||
Config: &structs.CAConfiguration{
|
||||
Provider: "consul",
|
||||
},
|
||||
}
|
||||
var resp error
|
||||
err := msgpackrpc.CallWithCodec(codec, "ConnectCA.ConfigurationSet", req, &resp)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, resp)
|
||||
|
||||
roots = structs.IndexedCARoots{}
|
||||
err = msgpackrpc.CallWithCodec(codec, "ConnectCA.Roots", &structs.DCSpecificRequest{}, &roots)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, roots.Roots, 2)
|
||||
active := roots.Active()
|
||||
require.Len(t, active.IntermediateCerts, 1)
|
||||
|
||||
leafPEM := getLeafCert(t, codec, roots.TrustDomain, "dc1")
|
||||
verifyLeafCert(t, roots.Active(), leafPEM)
|
||||
|
||||
// original certs from old root cert should still verify
|
||||
verifyLeafCertWithRoots(t, roots, origLeaf)
|
||||
})
|
||||
|
||||
runStep(t, "rotate to a different external root", func(t *testing.T) {
|
||||
setupPrimaryCA(t, vclient, "pki-primary-2/", rootPEM)
|
||||
|
||||
codec := rpcClient(t, serverDC1)
|
||||
req := &structs.CARequest{
|
||||
Op: structs.CAOpSetConfig,
|
||||
Config: &structs.CAConfiguration{
|
||||
Provider: "vault",
|
||||
Config: map[string]interface{}{
|
||||
"Address": vault.Addr,
|
||||
"Token": vault.RootToken,
|
||||
"RootPKIPath": "pki-primary-2/",
|
||||
"IntermediatePKIPath": "pki-intermediate-2/",
|
||||
},
|
||||
},
|
||||
}
|
||||
var resp error
|
||||
err := msgpackrpc.CallWithCodec(codec, "ConnectCA.ConfigurationSet", req, &resp)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, resp)
|
||||
|
||||
roots = structs.IndexedCARoots{}
|
||||
err = msgpackrpc.CallWithCodec(codec, "ConnectCA.Roots", &structs.DCSpecificRequest{}, &roots)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, roots.Roots, 3)
|
||||
active := roots.Active()
|
||||
require.Len(t, active.IntermediateCerts, 2)
|
||||
|
||||
leafPEM := getLeafCert(t, codec, roots.TrustDomain, "dc1")
|
||||
verifyLeafCert(t, roots.Active(), leafPEM)
|
||||
|
||||
// original certs from old root cert should still verify
|
||||
verifyLeafCertWithRoots(t, roots, origLeaf)
|
||||
})
|
||||
}
|
||||
|
||||
// renewLeafSigningCert mimics RenewIntermediate. This is unfortunate, but
|
||||
|
|
Loading…
Reference in New Issue