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) {
|
func generatePrivateKey() (string, error) {
|
||||||
var pk *ecdsa.PrivateKey
|
var pk *ecdsa.PrivateKey
|
||||||
|
|
||||||
// If we have no key, then create a new one.
|
|
||||||
pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("error generating private key: %s", err)
|
return "", fmt.Errorf("error generating private key: %s", err)
|
||||||
|
|
|
@ -3,7 +3,9 @@ package consul
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/agent/connect"
|
||||||
"github.com/hashicorp/consul/testrpc"
|
"github.com/hashicorp/consul/testrpc"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
@ -25,8 +27,156 @@ func TestCAProvider_Bootstrap(t *testing.T) {
|
||||||
root, err := provider.ActiveRoot()
|
root, err := provider.ActiveRoot()
|
||||||
assert.NoError(err)
|
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()
|
state := s1.fsm.State()
|
||||||
_, activeRoot, err := state.CARootActive(nil)
|
_, activeRoot, err := state.CARootActive(nil)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
assert.Equal(root, activeRoot.RootCert)
|
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.
|
// looks like several depend on it.
|
||||||
config.RPCHoldTimeout = 5 * time.Second
|
config.RPCHoldTimeout = 5 * time.Second
|
||||||
|
|
||||||
|
config.ConnectEnabled = true
|
||||||
|
|
||||||
return dir, config
|
return dir, config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue