183 lines
4.7 KiB
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)
|
|
}
|