open-consul/agent/consul/connect_ca_provider_test.go

183 lines
4.7 KiB
Go

package consul
import (
"os"
"testing"
"time"
"github.com/hashicorp/consul/agent/connect"
"github.com/hashicorp/consul/testrpc"
"github.com/stretchr/testify/assert"
)
func TestCAProvider_Bootstrap(t *testing.T) {
t.Parallel()
assert := assert.New(t)
dir1, s1 := testServer(t)
defer os.RemoveAll(dir1)
defer s1.Shutdown()
codec := rpcClient(t, s1)
defer codec.Close()
testrpc.WaitForLeader(t, s1.RPC, "dc1")
provider := s1.getCAProvider()
root, err := provider.ActiveRoot()
assert.NoError(err)
// Intermediate should be the same cert.
inter, err := provider.ActiveIntermediate()
assert.NoError(err)
// Make sure we initialize without errors and that the
// root cert gets set to the active cert.
state := s1.fsm.State()
_, activeRoot, err := state.CARootActive(nil)
assert.NoError(err)
assert.Equal(root, activeRoot.RootCert)
assert.Equal(inter, activeRoot.RootCert)
}
func TestCAProvider_Bootstrap_WithCert(t *testing.T) {
t.Parallel()
// Make sure setting a custom private key/root cert works.
assert := assert.New(t)
rootCA := connect.TestCA(t, nil)
dir1, s1 := testServerWithConfig(t, func(c *Config) {
c.CAConfig.Config["PrivateKey"] = rootCA.SigningKey
c.CAConfig.Config["RootCert"] = rootCA.RootCert
})
defer os.RemoveAll(dir1)
defer s1.Shutdown()
codec := rpcClient(t, s1)
defer codec.Close()
testrpc.WaitForLeader(t, s1.RPC, "dc1")
provider := s1.getCAProvider()
root, err := provider.ActiveRoot()
assert.NoError(err)
// Make sure we initialize without errors and that the
// root cert we provided gets set to the active cert.
state := s1.fsm.State()
_, activeRoot, err := state.CARootActive(nil)
assert.NoError(err)
assert.Equal(root, activeRoot.RootCert)
assert.Equal(rootCA.RootCert, activeRoot.RootCert)
}
func TestCAProvider_SignLeaf(t *testing.T) {
t.Parallel()
assert := assert.New(t)
dir1, s1 := testServer(t)
defer os.RemoveAll(dir1)
defer s1.Shutdown()
codec := rpcClient(t, s1)
defer codec.Close()
testrpc.WaitForLeader(t, s1.RPC, "dc1")
provider := s1.getCAProvider()
spiffeService := &connect.SpiffeIDService{
Host: s1.config.NodeName,
Namespace: "default",
Datacenter: s1.config.Datacenter,
Service: "foo",
}
// Generate a leaf cert for the service.
{
raw, _ := connect.TestCSR(t, spiffeService)
csr, err := connect.ParseCSR(raw)
assert.NoError(err)
cert, err := provider.Sign(csr)
assert.NoError(err)
parsed, err := connect.ParseCert(cert)
assert.NoError(err)
assert.Equal(parsed.URIs[0], spiffeService.URI())
assert.Equal(parsed.Subject.CommonName, "foo")
assert.Equal(parsed.SerialNumber.Uint64(), uint64(1))
// Ensure the cert is valid now and expires within the correct limit.
assert.True(parsed.NotAfter.Sub(time.Now()) < 3*24*time.Hour)
assert.True(parsed.NotBefore.Before(time.Now()))
}
// Generate a new cert for another service and make sure
// the serial number is incremented.
spiffeService.Service = "bar"
{
raw, _ := connect.TestCSR(t, spiffeService)
csr, err := connect.ParseCSR(raw)
assert.NoError(err)
cert, err := provider.Sign(csr)
assert.NoError(err)
parsed, err := connect.ParseCert(cert)
assert.NoError(err)
assert.Equal(parsed.URIs[0], spiffeService.URI())
assert.Equal(parsed.Subject.CommonName, "bar")
assert.Equal(parsed.SerialNumber.Uint64(), uint64(2))
// Ensure the cert is valid now and expires within the correct limit.
assert.True(parsed.NotAfter.Sub(time.Now()) < 3*24*time.Hour)
assert.True(parsed.NotBefore.Before(time.Now()))
}
}
func TestCAProvider_CrossSignCA(t *testing.T) {
t.Parallel()
assert := assert.New(t)
// Make sure setting a custom private key/root cert works.
dir1, s1 := testServer(t)
defer os.RemoveAll(dir1)
defer s1.Shutdown()
codec := rpcClient(t, s1)
defer codec.Close()
testrpc.WaitForLeader(t, s1.RPC, "dc1")
provider := s1.getCAProvider()
rootCA := connect.TestCA(t, nil)
rootPEM, err := provider.ActiveRoot()
assert.NoError(err)
root, err := connect.ParseCert(rootPEM)
assert.NoError(err)
// Have the provider cross sign our new CA cert.
cert, err := connect.ParseCert(rootCA.RootCert)
assert.NoError(err)
oldSubject := cert.Subject.CommonName
xcPEM, err := provider.CrossSignCA(cert)
assert.NoError(err)
xc, err := connect.ParseCert(xcPEM)
assert.NoError(err)
// AuthorityKeyID and SubjectKeyID should be the signing root's.
assert.Equal(root.AuthorityKeyId, xc.AuthorityKeyId)
assert.Equal(root.SubjectKeyId, xc.SubjectKeyId)
// Subject name should not have changed.
assert.NotEqual(root.Subject.CommonName, xc.Subject.CommonName)
assert.Equal(oldSubject, xc.Subject.CommonName)
// Issuer should be the signing root.
assert.Equal(root.Issuer.CommonName, xc.Issuer.CommonName)
}