mirror of
https://github.com/status-im/consul.git
synced 2025-02-02 08:56:43 +00:00
ca: add a test for Vault in secondary DC
This commit is contained in:
parent
a5d9b1d322
commit
a4ba1f348d
@ -11,9 +11,11 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"net/rpc"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
msgpackrpc "github.com/hashicorp/net-rpc-msgpackrpc"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
@ -31,6 +33,107 @@ import (
|
|||||||
// TODO(kyhavlov): replace with t.Deadline()
|
// TODO(kyhavlov): replace with t.Deadline()
|
||||||
const CATestTimeout = 7 * time.Second
|
const CATestTimeout = 7 * time.Second
|
||||||
|
|
||||||
|
func TestCAManager_Initialize_Vault_Secondary_SharedVault(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("too slow for testing.Short")
|
||||||
|
}
|
||||||
|
ca.SkipIfVaultNotPresent(t)
|
||||||
|
|
||||||
|
vault := ca.NewTestVaultServer(t)
|
||||||
|
|
||||||
|
_, serverDC1 := testServerWithConfig(t, func(c *Config) {
|
||||||
|
c.CAConfig = &structs.CAConfiguration{
|
||||||
|
Provider: "vault",
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"Address": vault.Addr,
|
||||||
|
"Token": vault.RootToken,
|
||||||
|
"RootPKIPath": "pki-root/",
|
||||||
|
"IntermediatePKIPath": "pki-primary/",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
runStep(t, "check primary DC", func(t *testing.T) {
|
||||||
|
testrpc.WaitForTestAgent(t, serverDC1.RPC, "dc1")
|
||||||
|
|
||||||
|
codec := rpcClient(t, serverDC1)
|
||||||
|
defer codec.Close()
|
||||||
|
|
||||||
|
roots := structs.IndexedCARoots{}
|
||||||
|
err := msgpackrpc.CallWithCodec(codec, "ConnectCA.Roots", &structs.DCSpecificRequest{}, &roots)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, roots.Roots, 1)
|
||||||
|
|
||||||
|
leafPEM := getLeafCert(t, codec, roots.TrustDomain, "dc1")
|
||||||
|
verifyLeafCert(t, roots.Roots[0], leafPEM)
|
||||||
|
})
|
||||||
|
|
||||||
|
runStep(t, "start secondary DC", func(t *testing.T) {
|
||||||
|
_, serverDC2 := testServerWithConfig(t, func(c *Config) {
|
||||||
|
c.Datacenter = "dc2"
|
||||||
|
c.PrimaryDatacenter = "dc1"
|
||||||
|
c.CAConfig = &structs.CAConfiguration{
|
||||||
|
Provider: "vault",
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"Address": vault.Addr,
|
||||||
|
"Token": vault.RootToken,
|
||||||
|
"RootPKIPath": "pki-root/",
|
||||||
|
"IntermediatePKIPath": "pki-secondary/",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
defer serverDC2.Shutdown()
|
||||||
|
joinWAN(t, serverDC2, serverDC1)
|
||||||
|
testrpc.WaitForActiveCARoot(t, serverDC2.RPC, "dc2", nil)
|
||||||
|
|
||||||
|
codec := rpcClient(t, serverDC2)
|
||||||
|
defer codec.Close()
|
||||||
|
|
||||||
|
roots := structs.IndexedCARoots{}
|
||||||
|
err := msgpackrpc.CallWithCodec(codec, "ConnectCA.Roots", &structs.DCSpecificRequest{}, &roots)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, roots.Roots, 1)
|
||||||
|
|
||||||
|
leafPEM := getLeafCert(t, codec, roots.TrustDomain, "dc2")
|
||||||
|
verifyLeafCert(t, roots.Roots[0], leafPEM)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyLeafCert(t *testing.T, root *structs.CARoot, leafCertPEM string) {
|
||||||
|
t.Helper()
|
||||||
|
leaf, intermediates, err := connect.ParseLeafCerts(leafCertPEM)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
pool := x509.NewCertPool()
|
||||||
|
ok := pool.AppendCertsFromPEM([]byte(root.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{
|
||||||
|
Roots: pool,
|
||||||
|
Intermediates: intermediates,
|
||||||
|
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||||
|
})
|
||||||
|
require.NoError(t, err, "failed to verify using intermediates from leaf cert PEM")
|
||||||
|
|
||||||
|
// verify with intermediates from the CARoot
|
||||||
|
intermediates = x509.NewCertPool()
|
||||||
|
for _, intermediate := range root.IntermediateCerts {
|
||||||
|
c, err := connect.ParseCert(intermediate)
|
||||||
|
require.NoError(t, err)
|
||||||
|
intermediates.AddCert(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = leaf.Verify(x509.VerifyOptions{
|
||||||
|
Roots: pool,
|
||||||
|
Intermediates: intermediates,
|
||||||
|
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||||
|
})
|
||||||
|
require.NoError(t, err, "failed to verify using intermediates from CARoot list")
|
||||||
|
}
|
||||||
|
|
||||||
type mockCAServerDelegate struct {
|
type mockCAServerDelegate struct {
|
||||||
t *testing.T
|
t *testing.T
|
||||||
config *Config
|
config *Config
|
||||||
@ -515,3 +618,22 @@ func TestCAManager_UpdateConfiguration_Vault_Primary(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, connect.HexString(cert.SubjectKeyId), newRoot.SigningKeyID)
|
require.Equal(t, connect.HexString(cert.SubjectKeyId), newRoot.SigningKeyID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getLeafCert(t *testing.T, codec rpc.ClientCodec, trustDomain string, dc string) string {
|
||||||
|
pk, _, err := connect.GeneratePrivateKey()
|
||||||
|
require.NoError(t, err)
|
||||||
|
spiffeID := &connect.SpiffeIDService{
|
||||||
|
Host: trustDomain,
|
||||||
|
Service: "srv1",
|
||||||
|
Datacenter: dc,
|
||||||
|
}
|
||||||
|
csr, err := connect.CreateCSR(spiffeID, pk, nil, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
req := structs.CASignRequest{CSR: csr}
|
||||||
|
cert := structs.IssuedCert{}
|
||||||
|
err = msgpackrpc.CallWithCodec(codec, "ConnectCA.Sign", &req, &cert)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
return cert.CertPEM
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user