mirror of https://github.com/hashicorp/consul
add subject names to issued certs
parent
7f36a5b676
commit
9b1ac4e7ef
|
@ -28,6 +28,8 @@ type ConsulProvider struct {
|
||||||
config *structs.ConsulCAProviderConfig
|
config *structs.ConsulCAProviderConfig
|
||||||
id string
|
id string
|
||||||
clusterID string
|
clusterID string
|
||||||
|
dcName string
|
||||||
|
domain string
|
||||||
isRoot bool
|
isRoot bool
|
||||||
spiffeID *connect.SpiffeIDSigning
|
spiffeID *connect.SpiffeIDSigning
|
||||||
|
|
||||||
|
@ -40,7 +42,8 @@ type ConsulProviderStateDelegate interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure sets up the provider using the given configuration.
|
// Configure sets up the provider using the given configuration.
|
||||||
func (c *ConsulProvider) Configure(clusterID string, isRoot bool, rawConfig map[string]interface{}) error {
|
func (c *ConsulProvider) Configure(clusterID string, datacenterName string, dnsDomain string,
|
||||||
|
isRoot bool, rawConfig map[string]interface{}) error {
|
||||||
// Parse the raw config and update our ID.
|
// Parse the raw config and update our ID.
|
||||||
config, err := ParseConsulCAConfig(rawConfig)
|
config, err := ParseConsulCAConfig(rawConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -49,9 +52,15 @@ func (c *ConsulProvider) Configure(clusterID string, isRoot bool, rawConfig map[
|
||||||
c.config = config
|
c.config = config
|
||||||
hash := sha256.Sum256([]byte(fmt.Sprintf("%s,%s,%v", config.PrivateKey, config.RootCert, isRoot)))
|
hash := sha256.Sum256([]byte(fmt.Sprintf("%s,%s,%v", config.PrivateKey, config.RootCert, isRoot)))
|
||||||
c.id = strings.Replace(fmt.Sprintf("% x", hash), " ", ":", -1)
|
c.id = strings.Replace(fmt.Sprintf("% x", hash), " ", ":", -1)
|
||||||
c.clusterID = clusterID
|
|
||||||
c.isRoot = isRoot
|
c.isRoot = isRoot
|
||||||
c.spiffeID = connect.SpiffeIDSigningForCluster(&structs.CAConfiguration{ClusterID: clusterID})
|
c.spiffeID = connect.SpiffeIDSigningForCluster(&structs.CAConfiguration{ClusterID: clusterID})
|
||||||
|
c.dcName = datacenterName
|
||||||
|
c.domain = dnsDomain
|
||||||
|
|
||||||
|
c.clusterID = clusterID
|
||||||
|
if len(c.clusterID) > 8 {
|
||||||
|
c.clusterID = c.clusterID[:8]
|
||||||
|
}
|
||||||
|
|
||||||
// Exit early if the state store has an entry for this provider's config.
|
// Exit early if the state store has an entry for this provider's config.
|
||||||
_, providerState, err := c.Delegate.State().CAProviderState(c.id)
|
_, providerState, err := c.Delegate.State().CAProviderState(c.id)
|
||||||
|
@ -189,7 +198,8 @@ func (c *ConsulProvider) GenerateIntermediateCSR() (string, error) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
csr, err := connect.CreateCACSR(c.spiffeID, signer)
|
commonName := fmt.Sprintf("intermediate.ca.%s.%s.%s", c.clusterID, c.dcName, c.domain)
|
||||||
|
csr, err := connect.CreateCACSR(c.spiffeID, commonName, signer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -344,22 +354,22 @@ func (c *ConsulProvider) Sign(csr *x509.CertificateRequest) (string, error) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the SPIFFE ID
|
//// Parse the SPIFFE ID
|
||||||
spiffeId, err := connect.ParseCertURI(csr.URIs[0])
|
//spiffeId, err := connect.ParseCertURI(csr.URIs[0])
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
return "", err
|
// return "", err
|
||||||
}
|
//}
|
||||||
|
|
||||||
subject := ""
|
|
||||||
switch id := spiffeId.(type) {
|
|
||||||
case *connect.SpiffeIDService:
|
|
||||||
subject = id.Service
|
|
||||||
case *connect.SpiffeIDAgent:
|
|
||||||
subject = id.Agent
|
|
||||||
default:
|
|
||||||
return "", fmt.Errorf("SPIFFE ID in CSR must be a service ID")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//subjectName := ""
|
||||||
|
//switch id := spiffeId.(type) {
|
||||||
|
//case *connect.SpiffeIDService:
|
||||||
|
// subjectName = fmt.Sprintf("%s.%s.service.%s.%s", id.Host, id.Service, id.Datacenter, c.domain)
|
||||||
|
//case *connect.SpiffeIDAgent:
|
||||||
|
// subjectName = fmt.Sprintf("%s.agent.%s.%s", id.Agent, id.Datacenter, c.domain)
|
||||||
|
//default:
|
||||||
|
// return "", fmt.Errorf("SPIFFE ID in CSR must be a service ID")
|
||||||
|
//}
|
||||||
|
//
|
||||||
// Parse the CA cert
|
// Parse the CA cert
|
||||||
certPEM, err := c.ActiveIntermediate()
|
certPEM, err := c.ActiveIntermediate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -379,7 +389,7 @@ func (c *ConsulProvider) Sign(csr *x509.CertificateRequest) (string, error) {
|
||||||
effectiveNow := time.Now().Add(-1 * time.Minute)
|
effectiveNow := time.Now().Add(-1 * time.Minute)
|
||||||
template := x509.Certificate{
|
template := x509.Certificate{
|
||||||
SerialNumber: sn,
|
SerialNumber: sn,
|
||||||
Subject: pkix.Name{CommonName: subject},
|
Subject: csr.Subject,
|
||||||
URIs: csr.URIs,
|
URIs: csr.URIs,
|
||||||
Signature: csr.Signature,
|
Signature: csr.Signature,
|
||||||
SignatureAlgorithm: csr.SignatureAlgorithm,
|
SignatureAlgorithm: csr.SignatureAlgorithm,
|
||||||
|
@ -617,7 +627,7 @@ func (c *ConsulProvider) generateCA(privateKey string, sn uint64) (string, error
|
||||||
return "", fmt.Errorf("error parsing private key %q: %s", privateKey, err)
|
return "", fmt.Errorf("error parsing private key %q: %s", privateKey, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
name := fmt.Sprintf("Consul CA %d", sn)
|
commonName := fmt.Sprintf("root.ca.%s.%s.%s", c.clusterID, c.dcName, c.domain)
|
||||||
|
|
||||||
// The URI (SPIFFE compatible) for the cert
|
// The URI (SPIFFE compatible) for the cert
|
||||||
id := connect.SpiffeIDSigningForCluster(config)
|
id := connect.SpiffeIDSigningForCluster(config)
|
||||||
|
@ -631,7 +641,7 @@ func (c *ConsulProvider) generateCA(privateKey string, sn uint64) (string, error
|
||||||
serialNum.SetUint64(sn)
|
serialNum.SetUint64(sn)
|
||||||
template := x509.Certificate{
|
template := x509.Certificate{
|
||||||
SerialNumber: serialNum,
|
SerialNumber: serialNum,
|
||||||
Subject: pkix.Name{CommonName: name},
|
Subject: pkix.Name{CommonName: commonName},
|
||||||
URIs: []*url.URL{id.URI()},
|
URIs: []*url.URL{id.URI()},
|
||||||
BasicConstraintsValid: true,
|
BasicConstraintsValid: true,
|
||||||
KeyUsage: x509.KeyUsageCertSign |
|
KeyUsage: x509.KeyUsageCertSign |
|
||||||
|
|
|
@ -79,7 +79,7 @@ func TestConsulCAProvider_Bootstrap(t *testing.T) {
|
||||||
delegate := newMockDelegate(t, conf)
|
delegate := newMockDelegate(t, conf)
|
||||||
|
|
||||||
provider := &ConsulProvider{Delegate: delegate}
|
provider := &ConsulProvider{Delegate: delegate}
|
||||||
require.NoError(provider.Configure(conf.ClusterID, true, conf.Config))
|
require.NoError(provider.Configure(conf.ClusterID, "dc1", "consul", true, conf.Config))
|
||||||
require.NoError(provider.GenerateRoot())
|
require.NoError(provider.GenerateRoot())
|
||||||
|
|
||||||
root, err := provider.ActiveRoot()
|
root, err := provider.ActiveRoot()
|
||||||
|
@ -110,7 +110,7 @@ func TestConsulCAProvider_Bootstrap_WithCert(t *testing.T) {
|
||||||
delegate := newMockDelegate(t, conf)
|
delegate := newMockDelegate(t, conf)
|
||||||
|
|
||||||
provider := &ConsulProvider{Delegate: delegate}
|
provider := &ConsulProvider{Delegate: delegate}
|
||||||
require.NoError(provider.Configure(conf.ClusterID, true, conf.Config))
|
require.NoError(provider.Configure(conf.ClusterID, "dc1", "consul", true, conf.Config))
|
||||||
require.NoError(provider.GenerateRoot())
|
require.NoError(provider.GenerateRoot())
|
||||||
|
|
||||||
root, err := provider.ActiveRoot()
|
root, err := provider.ActiveRoot()
|
||||||
|
@ -127,7 +127,7 @@ func TestConsulCAProvider_SignLeaf(t *testing.T) {
|
||||||
delegate := newMockDelegate(t, conf)
|
delegate := newMockDelegate(t, conf)
|
||||||
|
|
||||||
provider := &ConsulProvider{Delegate: delegate}
|
provider := &ConsulProvider{Delegate: delegate}
|
||||||
require.NoError(provider.Configure(conf.ClusterID, true, conf.Config))
|
require.NoError(provider.Configure(conf.ClusterID, "dc1", "consul", true, conf.Config))
|
||||||
require.NoError(provider.GenerateRoot())
|
require.NoError(provider.GenerateRoot())
|
||||||
|
|
||||||
spiffeService := &connect.SpiffeIDService{
|
spiffeService := &connect.SpiffeIDService{
|
||||||
|
@ -139,7 +139,7 @@ func TestConsulCAProvider_SignLeaf(t *testing.T) {
|
||||||
|
|
||||||
// Generate a leaf cert for the service.
|
// Generate a leaf cert for the service.
|
||||||
{
|
{
|
||||||
raw, _ := connect.TestCSR(t, spiffeService)
|
raw, _ := connect.TestCSR(t, spiffeService, "node1.foo.service.dc1.consul.")
|
||||||
|
|
||||||
csr, err := connect.ParseCSR(raw)
|
csr, err := connect.ParseCSR(raw)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
|
@ -149,8 +149,8 @@ func TestConsulCAProvider_SignLeaf(t *testing.T) {
|
||||||
|
|
||||||
parsed, err := connect.ParseCert(cert)
|
parsed, err := connect.ParseCert(cert)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
require.Equal(parsed.URIs[0], spiffeService.URI())
|
require.Equal(spiffeService.URI(), parsed.URIs[0])
|
||||||
require.Equal(parsed.Subject.CommonName, "foo")
|
require.Equal("node1.foo.service.dc1.consul.", parsed.Subject.CommonName)
|
||||||
require.Equal(uint64(2), parsed.SerialNumber.Uint64())
|
require.Equal(uint64(2), parsed.SerialNumber.Uint64())
|
||||||
|
|
||||||
// Ensure the cert is valid now and expires within the correct limit.
|
// Ensure the cert is valid now and expires within the correct limit.
|
||||||
|
@ -163,7 +163,7 @@ func TestConsulCAProvider_SignLeaf(t *testing.T) {
|
||||||
// the serial number is incremented.
|
// the serial number is incremented.
|
||||||
spiffeService.Service = "bar"
|
spiffeService.Service = "bar"
|
||||||
{
|
{
|
||||||
raw, _ := connect.TestCSR(t, spiffeService)
|
raw, _ := connect.TestCSR(t, spiffeService, "node1.bar.service.dc1.consul.")
|
||||||
|
|
||||||
csr, err := connect.ParseCSR(raw)
|
csr, err := connect.ParseCSR(raw)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
|
@ -173,8 +173,8 @@ func TestConsulCAProvider_SignLeaf(t *testing.T) {
|
||||||
|
|
||||||
parsed, err := connect.ParseCert(cert)
|
parsed, err := connect.ParseCert(cert)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
require.Equal(parsed.URIs[0], spiffeService.URI())
|
require.Equal(spiffeService.URI(), parsed.URIs[0])
|
||||||
require.Equal(parsed.Subject.CommonName, "bar")
|
require.Equal("node1.bar.service.dc1.consul.", parsed.Subject.CommonName)
|
||||||
require.Equal(parsed.SerialNumber.Uint64(), uint64(2))
|
require.Equal(parsed.SerialNumber.Uint64(), uint64(2))
|
||||||
|
|
||||||
// Ensure the cert is valid now and expires within the correct limit.
|
// Ensure the cert is valid now and expires within the correct limit.
|
||||||
|
@ -189,7 +189,7 @@ func TestConsulCAProvider_SignLeaf(t *testing.T) {
|
||||||
}
|
}
|
||||||
// Generate a leaf cert for an agent.
|
// Generate a leaf cert for an agent.
|
||||||
{
|
{
|
||||||
raw, _ := connect.TestCSR(t, spiffeAgent)
|
raw, _ := connect.TestCSR(t, spiffeAgent, "uuid.agent.dc1.consul.")
|
||||||
|
|
||||||
csr, err := connect.ParseCSR(raw)
|
csr, err := connect.ParseCSR(raw)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
|
@ -200,7 +200,7 @@ func TestConsulCAProvider_SignLeaf(t *testing.T) {
|
||||||
parsed, err := connect.ParseCert(cert)
|
parsed, err := connect.ParseCert(cert)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
require.Equal(spiffeAgent.URI(), parsed.URIs[0])
|
require.Equal(spiffeAgent.URI(), parsed.URIs[0])
|
||||||
require.Equal("uuid", parsed.Subject.CommonName)
|
require.Equal("uuid.agent.dc1.consul.", parsed.Subject.CommonName)
|
||||||
require.Equal(uint64(2), parsed.SerialNumber.Uint64())
|
require.Equal(uint64(2), parsed.SerialNumber.Uint64())
|
||||||
|
|
||||||
// Ensure the cert is valid now and expires within the correct limit.
|
// Ensure the cert is valid now and expires within the correct limit.
|
||||||
|
@ -218,14 +218,14 @@ func TestConsulCAProvider_CrossSignCA(t *testing.T) {
|
||||||
conf1 := testConsulCAConfig()
|
conf1 := testConsulCAConfig()
|
||||||
delegate1 := newMockDelegate(t, conf1)
|
delegate1 := newMockDelegate(t, conf1)
|
||||||
provider1 := &ConsulProvider{Delegate: delegate1}
|
provider1 := &ConsulProvider{Delegate: delegate1}
|
||||||
require.NoError(provider1.Configure(conf1.ClusterID, true, conf1.Config))
|
require.NoError(provider1.Configure(conf1.ClusterID, "dc1", "consul", true, conf1.Config))
|
||||||
require.NoError(provider1.GenerateRoot())
|
require.NoError(provider1.GenerateRoot())
|
||||||
|
|
||||||
conf2 := testConsulCAConfig()
|
conf2 := testConsulCAConfig()
|
||||||
conf2.CreateIndex = 10
|
conf2.CreateIndex = 10
|
||||||
delegate2 := newMockDelegate(t, conf2)
|
delegate2 := newMockDelegate(t, conf2)
|
||||||
provider2 := &ConsulProvider{Delegate: delegate2}
|
provider2 := &ConsulProvider{Delegate: delegate2}
|
||||||
require.NoError(provider2.Configure(conf2.ClusterID, true, conf2.Config))
|
require.NoError(provider2.Configure(conf2.ClusterID, "dc2", "consul", true, conf2.Config))
|
||||||
require.NoError(provider2.GenerateRoot())
|
require.NoError(provider2.GenerateRoot())
|
||||||
|
|
||||||
testCrossSignProviders(t, provider1, provider2)
|
testCrossSignProviders(t, provider1, provider2)
|
||||||
|
@ -274,7 +274,7 @@ func testCrossSignProviders(t *testing.T, provider1, provider2 Provider) {
|
||||||
Datacenter: "dc1",
|
Datacenter: "dc1",
|
||||||
Service: "foo",
|
Service: "foo",
|
||||||
}
|
}
|
||||||
raw, _ := connect.TestCSR(t, spiffeService)
|
raw, _ := connect.TestCSR(t, spiffeService, "node1.foo.service.dc1.consul.")
|
||||||
|
|
||||||
leafCsr, err := connect.ParseCSR(raw)
|
leafCsr, err := connect.ParseCSR(raw)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
|
@ -310,14 +310,14 @@ func TestConsulProvider_SignIntermediate(t *testing.T) {
|
||||||
conf1 := testConsulCAConfig()
|
conf1 := testConsulCAConfig()
|
||||||
delegate1 := newMockDelegate(t, conf1)
|
delegate1 := newMockDelegate(t, conf1)
|
||||||
provider1 := &ConsulProvider{Delegate: delegate1}
|
provider1 := &ConsulProvider{Delegate: delegate1}
|
||||||
require.NoError(provider1.Configure(conf1.ClusterID, true, conf1.Config))
|
require.NoError(provider1.Configure(conf1.ClusterID, "dc1", "consul", true, conf1.Config))
|
||||||
require.NoError(provider1.GenerateRoot())
|
require.NoError(provider1.GenerateRoot())
|
||||||
|
|
||||||
conf2 := testConsulCAConfig()
|
conf2 := testConsulCAConfig()
|
||||||
conf2.CreateIndex = 10
|
conf2.CreateIndex = 10
|
||||||
delegate2 := newMockDelegate(t, conf2)
|
delegate2 := newMockDelegate(t, conf2)
|
||||||
provider2 := &ConsulProvider{Delegate: delegate2}
|
provider2 := &ConsulProvider{Delegate: delegate2}
|
||||||
require.NoError(provider2.Configure(conf2.ClusterID, false, conf2.Config))
|
require.NoError(provider2.Configure(conf2.ClusterID, "dc1", "consul", false, conf2.Config))
|
||||||
|
|
||||||
testSignIntermediateCrossDC(t, provider1, provider2)
|
testSignIntermediateCrossDC(t, provider1, provider2)
|
||||||
}
|
}
|
||||||
|
@ -347,7 +347,7 @@ func testSignIntermediateCrossDC(t *testing.T, provider1, provider2 Provider) {
|
||||||
Datacenter: "dc1",
|
Datacenter: "dc1",
|
||||||
Service: "foo",
|
Service: "foo",
|
||||||
}
|
}
|
||||||
raw, _ := connect.TestCSR(t, spiffeService)
|
raw, _ := connect.TestCSR(t, spiffeService, "node1.foo.service.dc1.consul.")
|
||||||
|
|
||||||
leafCsr, err := connect.ParseCSR(raw)
|
leafCsr, err := connect.ParseCSR(raw)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
|
@ -392,7 +392,7 @@ func TestConsulCAProvider_MigrateOldID(t *testing.T) {
|
||||||
require.NotNil(providerState)
|
require.NotNil(providerState)
|
||||||
|
|
||||||
provider := &ConsulProvider{Delegate: delegate}
|
provider := &ConsulProvider{Delegate: delegate}
|
||||||
require.NoError(provider.Configure(conf.ClusterID, true, conf.Config))
|
require.NoError(provider.Configure(conf.ClusterID, "dc1", "consul", true, conf.Config))
|
||||||
require.NoError(provider.GenerateRoot())
|
require.NoError(provider.GenerateRoot())
|
||||||
|
|
||||||
// After running Configure, the old ID entry should be gone.
|
// After running Configure, the old ID entry should be gone.
|
||||||
|
|
|
@ -25,7 +25,9 @@ type VaultProvider struct {
|
||||||
config *structs.VaultCAProviderConfig
|
config *structs.VaultCAProviderConfig
|
||||||
client *vaultapi.Client
|
client *vaultapi.Client
|
||||||
isRoot bool
|
isRoot bool
|
||||||
clusterId string
|
clusterID string
|
||||||
|
dcName string
|
||||||
|
domain string
|
||||||
}
|
}
|
||||||
|
|
||||||
func vaultTLSConfig(config *structs.VaultCAProviderConfig) *vaultapi.TLSConfig {
|
func vaultTLSConfig(config *structs.VaultCAProviderConfig) *vaultapi.TLSConfig {
|
||||||
|
@ -40,7 +42,8 @@ func vaultTLSConfig(config *structs.VaultCAProviderConfig) *vaultapi.TLSConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure sets up the provider using the given configuration.
|
// Configure sets up the provider using the given configuration.
|
||||||
func (v *VaultProvider) Configure(clusterId string, isRoot bool, rawConfig map[string]interface{}) error {
|
func (v *VaultProvider) Configure(clusterId string, datacenterName string, dnsDomain string,
|
||||||
|
isRoot bool, rawConfig map[string]interface{}) error {
|
||||||
config, err := ParseVaultCAConfig(rawConfig)
|
config, err := ParseVaultCAConfig(rawConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -62,7 +65,13 @@ func (v *VaultProvider) Configure(clusterId string, isRoot bool, rawConfig map[s
|
||||||
v.config = config
|
v.config = config
|
||||||
v.client = client
|
v.client = client
|
||||||
v.isRoot = isRoot
|
v.isRoot = isRoot
|
||||||
v.clusterId = clusterId
|
v.dcName = datacenterName
|
||||||
|
v.domain = dnsDomain
|
||||||
|
|
||||||
|
v.clusterID = clusterId
|
||||||
|
if len(v.clusterID) > 8 {
|
||||||
|
v.clusterID = v.clusterID[:8]
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -96,13 +105,10 @@ func (v *VaultProvider) GenerateRoot() error {
|
||||||
|
|
||||||
fallthrough
|
fallthrough
|
||||||
case ErrBackendNotInitialized:
|
case ErrBackendNotInitialized:
|
||||||
spiffeID := connect.SpiffeIDSigning{ClusterID: v.clusterId, Domain: "consul"}
|
uuid, _ := uuid.GenerateUUID()
|
||||||
uuid, err := uuid.GenerateUUID()
|
spiffeID := connect.SpiffeIDSigning{ClusterID: v.clusterID, Domain: v.domain}
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = v.client.Logical().Write(v.config.RootPKIPath+"root/generate/internal", map[string]interface{}{
|
_, err = v.client.Logical().Write(v.config.RootPKIPath+"root/generate/internal", map[string]interface{}{
|
||||||
"common_name": fmt.Sprintf("Vault CA Root Authority %s", uuid),
|
"common_name": fmt.Sprintf("%s.root.ca.%s.%s.%s", uuid[:8], v.clusterID, v.dcName, v.domain),
|
||||||
"uri_sans": spiffeID.URI().String(),
|
"uri_sans": spiffeID.URI().String(),
|
||||||
"key_type": v.config.PrivateKeyType,
|
"key_type": v.config.PrivateKeyType,
|
||||||
"key_bits": v.config.PrivateKeyBits,
|
"key_bits": v.config.PrivateKeyBits,
|
||||||
|
@ -158,10 +164,11 @@ func (v *VaultProvider) generateIntermediateCSR() (string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
spiffeID := connect.SpiffeIDSigning{ClusterID: v.clusterId, Domain: "consul"}
|
spiffeID := connect.SpiffeIDSigning{ClusterID: v.clusterID, Domain: "consul"}
|
||||||
if role == nil {
|
if role == nil {
|
||||||
_, err := v.client.Logical().Write(rolePath, map[string]interface{}{
|
_, err := v.client.Logical().Write(rolePath, map[string]interface{}{
|
||||||
"allow_any_name": true,
|
"allow_any_name": true,
|
||||||
|
"enforce_hostnames": false,
|
||||||
"allowed_uri_sans": "spiffe://*",
|
"allowed_uri_sans": "spiffe://*",
|
||||||
"key_type": "any",
|
"key_type": "any",
|
||||||
"max_ttl": v.config.LeafCertTTL.String(),
|
"max_ttl": v.config.LeafCertTTL.String(),
|
||||||
|
@ -174,8 +181,9 @@ func (v *VaultProvider) generateIntermediateCSR() (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a new intermediate CSR for the root to sign.
|
// Generate a new intermediate CSR for the root to sign.
|
||||||
|
uuid, _ := uuid.GenerateUUID()
|
||||||
data, err := v.client.Logical().Write(v.config.IntermediatePKIPath+"intermediate/generate/internal", map[string]interface{}{
|
data, err := v.client.Logical().Write(v.config.IntermediatePKIPath+"intermediate/generate/internal", map[string]interface{}{
|
||||||
"common_name": "Vault CA Intermediate Authority",
|
"common_name": fmt.Sprintf("%s.intermediate.ca.%s.%s.%s", uuid[:8], v.clusterID, v.dcName, v.domain),
|
||||||
"key_type": v.config.PrivateKeyType,
|
"key_type": v.config.PrivateKeyType,
|
||||||
"key_bits": v.config.PrivateKeyBits,
|
"key_bits": v.config.PrivateKeyBits,
|
||||||
"uri_sans": spiffeID.URI().String(),
|
"uri_sans": spiffeID.URI().String(),
|
||||||
|
|
|
@ -48,7 +48,7 @@ func testVaultClusterWithConfig(t *testing.T, isRoot bool, rawConf map[string]in
|
||||||
|
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
provider := &VaultProvider{}
|
provider := &VaultProvider{}
|
||||||
require.NoError(provider.Configure("asdf", isRoot, conf))
|
require.NoError(provider.Configure("asdf", "dc1", "consul", isRoot, conf))
|
||||||
if isRoot {
|
if isRoot {
|
||||||
require.NoError(provider.GenerateRoot())
|
require.NoError(provider.GenerateRoot())
|
||||||
_, err := provider.GenerateIntermediate()
|
_, err := provider.GenerateIntermediate()
|
||||||
|
@ -120,7 +120,7 @@ func TestVaultCAProvider_Bootstrap(t *testing.T) {
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
require.True(parsed.IsCA)
|
require.True(parsed.IsCA)
|
||||||
require.Len(parsed.URIs, 1)
|
require.Len(parsed.URIs, 1)
|
||||||
require.Equal(parsed.URIs[0].String(), fmt.Sprintf("spiffe://%s.consul", provider.clusterId))
|
require.Equal(parsed.URIs[0].String(), fmt.Sprintf("spiffe://%s.consul", provider.clusterID))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ func TestVaultCAProvider_SignLeaf(t *testing.T) {
|
||||||
// Generate a leaf cert for the service.
|
// Generate a leaf cert for the service.
|
||||||
var firstSerial uint64
|
var firstSerial uint64
|
||||||
{
|
{
|
||||||
raw, _ := connect.TestCSR(t, spiffeService)
|
raw, _ := connect.TestCSR(t, spiffeService, "node1.foo.service.dc1.consul.")
|
||||||
|
|
||||||
csr, err := connect.ParseCSR(raw)
|
csr, err := connect.ParseCSR(raw)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
|
@ -159,7 +159,7 @@ func TestVaultCAProvider_SignLeaf(t *testing.T) {
|
||||||
|
|
||||||
parsed, err := connect.ParseCert(cert)
|
parsed, err := connect.ParseCert(cert)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
require.Equal(parsed.URIs[0], spiffeService.URI())
|
require.Equal(spiffeService.URI(), parsed.URIs[0])
|
||||||
firstSerial = parsed.SerialNumber.Uint64()
|
firstSerial = parsed.SerialNumber.Uint64()
|
||||||
|
|
||||||
// Ensure the cert is valid now and expires within the correct limit.
|
// Ensure the cert is valid now and expires within the correct limit.
|
||||||
|
@ -172,7 +172,7 @@ func TestVaultCAProvider_SignLeaf(t *testing.T) {
|
||||||
// the serial number is unique.
|
// the serial number is unique.
|
||||||
spiffeService.Service = "bar"
|
spiffeService.Service = "bar"
|
||||||
{
|
{
|
||||||
raw, _ := connect.TestCSR(t, spiffeService)
|
raw, _ := connect.TestCSR(t, spiffeService, "node1.bar.service.dc1.consul.")
|
||||||
|
|
||||||
csr, err := connect.ParseCSR(raw)
|
csr, err := connect.ParseCSR(raw)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
|
@ -182,7 +182,7 @@ func TestVaultCAProvider_SignLeaf(t *testing.T) {
|
||||||
|
|
||||||
parsed, err := connect.ParseCert(cert)
|
parsed, err := connect.ParseCert(cert)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
require.Equal(parsed.URIs[0], spiffeService.URI())
|
require.Equal(spiffeService.URI(), parsed.URIs[0])
|
||||||
require.NotEqual(firstSerial, parsed.SerialNumber.Uint64())
|
require.NotEqual(firstSerial, parsed.SerialNumber.Uint64())
|
||||||
|
|
||||||
// Ensure the cert is valid now and expires within the correct limit.
|
// Ensure the cert is valid now and expires within the correct limit.
|
||||||
|
@ -233,7 +233,7 @@ func TestVaultProvider_SignIntermediateConsul(t *testing.T) {
|
||||||
conf := testConsulCAConfig()
|
conf := testConsulCAConfig()
|
||||||
delegate := newMockDelegate(t, conf)
|
delegate := newMockDelegate(t, conf)
|
||||||
provider2 := &ConsulProvider{Delegate: delegate}
|
provider2 := &ConsulProvider{Delegate: delegate}
|
||||||
require.NoError(provider2.Configure(conf.ClusterID, false, conf.Config))
|
require.NoError(provider2.Configure(conf.ClusterID, "dc2", "consul", false, conf.Config))
|
||||||
|
|
||||||
testSignIntermediateCrossDC(t, provider1, provider2)
|
testSignIntermediateCrossDC(t, provider1, provider2)
|
||||||
}
|
}
|
||||||
|
@ -243,7 +243,7 @@ func TestVaultProvider_SignIntermediateConsul(t *testing.T) {
|
||||||
conf := testConsulCAConfig()
|
conf := testConsulCAConfig()
|
||||||
delegate := newMockDelegate(t, conf)
|
delegate := newMockDelegate(t, conf)
|
||||||
provider1 := &ConsulProvider{Delegate: delegate}
|
provider1 := &ConsulProvider{Delegate: delegate}
|
||||||
require.NoError(provider1.Configure(conf.ClusterID, true, conf.Config))
|
require.NoError(provider1.Configure(conf.ClusterID, "dc1", "consul", true, conf.Config))
|
||||||
require.NoError(provider1.GenerateRoot())
|
require.NoError(provider1.GenerateRoot())
|
||||||
|
|
||||||
provider2, core, listener := testVaultClusterWithConfig(t, false, nil)
|
provider2, core, listener := testVaultClusterWithConfig(t, false, nil)
|
||||||
|
|
|
@ -13,8 +13,9 @@ import (
|
||||||
|
|
||||||
// CreateCSR returns a CSR to sign the given service along with the PEM-encoded
|
// CreateCSR returns a CSR to sign the given service along with the PEM-encoded
|
||||||
// private key for this certificate.
|
// private key for this certificate.
|
||||||
func CreateCSR(uri CertURI, privateKey crypto.Signer, extensions ...pkix.Extension) (string, error) {
|
func CreateCSR(uri CertURI, commonName string, privateKey crypto.Signer, extensions ...pkix.Extension) (string, error) {
|
||||||
template := &x509.CertificateRequest{
|
template := &x509.CertificateRequest{
|
||||||
|
Subject: pkix.Name{CommonName: commonName},
|
||||||
URIs: []*url.URL{uri.URI()},
|
URIs: []*url.URL{uri.URI()},
|
||||||
SignatureAlgorithm: x509.ECDSAWithSHA256,
|
SignatureAlgorithm: x509.ECDSAWithSHA256,
|
||||||
ExtraExtensions: extensions,
|
ExtraExtensions: extensions,
|
||||||
|
@ -37,13 +38,13 @@ func CreateCSR(uri CertURI, privateKey crypto.Signer, extensions ...pkix.Extensi
|
||||||
|
|
||||||
// CreateCSR returns a CA CSR to sign the given service along with the PEM-encoded
|
// CreateCSR returns a CA CSR to sign the given service along with the PEM-encoded
|
||||||
// private key for this certificate.
|
// private key for this certificate.
|
||||||
func CreateCACSR(uri CertURI, privateKey crypto.Signer) (string, error) {
|
func CreateCACSR(uri CertURI, commonName string, privateKey crypto.Signer) (string, error) {
|
||||||
ext, err := CreateCAExtension()
|
ext, err := CreateCAExtension()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return CreateCSR(uri, privateKey, ext)
|
return CreateCSR(uri, commonName, privateKey, ext)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateCAExtension creates a pkix.Extension for the x509 Basic Constraints
|
// CreateCAExtension creates a pkix.Extension for the x509 Basic Constraints
|
||||||
|
|
|
@ -227,8 +227,9 @@ func TestLeaf(t testing.T, service string, root *structs.CARoot) (string, string
|
||||||
|
|
||||||
// TestCSR returns a CSR to sign the given service along with the PEM-encoded
|
// TestCSR returns a CSR to sign the given service along with the PEM-encoded
|
||||||
// private key for this certificate.
|
// private key for this certificate.
|
||||||
func TestCSR(t testing.T, uri CertURI) (string, string) {
|
func TestCSR(t testing.T, uri CertURI, commonName string) (string, string) {
|
||||||
template := &x509.CertificateRequest{
|
template := &x509.CertificateRequest{
|
||||||
|
Subject: pkix.Name{CommonName: commonName},
|
||||||
URIs: []*url.URL{uri.URI()},
|
URIs: []*url.URL{uri.URI()},
|
||||||
SignatureAlgorithm: x509.ECDSAWithSHA256,
|
SignatureAlgorithm: x509.ECDSAWithSHA256,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue