mirror of https://github.com/hashicorp/consul
Add more tests for built-in provider
parent
edcfdb37af
commit
15fbc2fd97
|
@ -341,7 +341,6 @@ func (c *ConsulCAProvider) incrementSerialIndex(providerState *structs.CAConsulP
|
|||
func generatePrivateKey() (string, error) {
|
||||
var pk *ecdsa.PrivateKey
|
||||
|
||||
// If we have no key, then create a new one.
|
||||
pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error generating private key: %s", err)
|
||||
|
|
|
@ -3,7 +3,9 @@ package consul
|
|||
import (
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/consul/agent/connect"
|
||||
"github.com/hashicorp/consul/testrpc"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
@ -25,8 +27,156 @@ func TestCAProvider_Bootstrap(t *testing.T) {
|
|||
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)
|
||||
}
|
||||
|
|
|
@ -91,6 +91,8 @@ func testServerConfig(t *testing.T) (string, *Config) {
|
|||
// looks like several depend on it.
|
||||
config.RPCHoldTimeout = 5 * time.Second
|
||||
|
||||
config.ConnectEnabled = true
|
||||
|
||||
return dir, config
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue