Rename some of the CA structs/files

This commit is contained in:
Kyle Havlovitz 2018-05-09 15:12:31 -07:00 committed by Mitchell Hashimoto
parent 1660f9ebab
commit d1265bc38b
No known key found for this signature in database
GPG key ID: 744E147AA52F5B0A
8 changed files with 73 additions and 65 deletions

View file

@ -2,8 +2,6 @@ package connect
import ( import (
"bytes" "bytes"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand" "crypto/rand"
"crypto/x509" "crypto/x509"
"crypto/x509/pkix" "crypto/x509/pkix"
@ -20,26 +18,26 @@ import (
"github.com/mitchellh/mapstructure" "github.com/mitchellh/mapstructure"
) )
type ConsulCAProvider struct { type ConsulProvider struct {
config *structs.ConsulCAProviderConfig config *structs.ConsulCAProviderConfig
id string id string
delegate ConsulCAStateDelegate delegate ConsulProviderStateDelegate
sync.RWMutex sync.RWMutex
} }
type ConsulCAStateDelegate interface { type ConsulProviderStateDelegate interface {
State() *state.Store State() *state.Store
ApplyCARequest(*structs.CARequest) error ApplyCARequest(*structs.CARequest) error
} }
// NewConsulCAProvider returns a new instance of the Consul CA provider, // NewConsulProvider returns a new instance of the Consul CA provider,
// bootstrapping its state in the state store necessary // bootstrapping its state in the state store necessary
func NewConsulCAProvider(rawConfig map[string]interface{}, delegate ConsulCAStateDelegate) (*ConsulCAProvider, error) { func NewConsulProvider(rawConfig map[string]interface{}, delegate ConsulProviderStateDelegate) (*ConsulProvider, error) {
conf, err := ParseConsulCAConfig(rawConfig) conf, err := ParseConsulCAConfig(rawConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
provider := &ConsulCAProvider{ provider := &ConsulProvider{
config: conf, config: conf,
delegate: delegate, delegate: delegate,
id: fmt.Sprintf("%s,%s", conf.PrivateKey, conf.RootCert), id: fmt.Sprintf("%s,%s", conf.PrivateKey, conf.RootCert),
@ -81,7 +79,7 @@ func NewConsulCAProvider(rawConfig map[string]interface{}, delegate ConsulCAStat
// Generate a private key if needed // Generate a private key if needed
if conf.PrivateKey == "" { if conf.PrivateKey == "" {
pk, err := GeneratePrivateKey() pk, err := connect.GeneratePrivateKey()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -127,7 +125,7 @@ func ParseConsulCAConfig(raw map[string]interface{}) (*structs.ConsulCAProviderC
} }
// Return the active root CA and generate a new one if needed // Return the active root CA and generate a new one if needed
func (c *ConsulCAProvider) ActiveRoot() (string, error) { func (c *ConsulProvider) ActiveRoot() (string, error) {
state := c.delegate.State() state := c.delegate.State()
_, providerState, err := state.CAProviderState(c.id) _, providerState, err := state.CAProviderState(c.id)
if err != nil { if err != nil {
@ -139,13 +137,13 @@ func (c *ConsulCAProvider) ActiveRoot() (string, error) {
// We aren't maintaining separate root/intermediate CAs for the builtin // We aren't maintaining separate root/intermediate CAs for the builtin
// provider, so just return the root. // provider, so just return the root.
func (c *ConsulCAProvider) ActiveIntermediate() (string, error) { func (c *ConsulProvider) ActiveIntermediate() (string, error) {
return c.ActiveRoot() return c.ActiveRoot()
} }
// We aren't maintaining separate root/intermediate CAs for the builtin // We aren't maintaining separate root/intermediate CAs for the builtin
// provider, so just generate a CSR for the active root. // provider, so just generate a CSR for the active root.
func (c *ConsulCAProvider) GenerateIntermediate() (string, error) { func (c *ConsulProvider) GenerateIntermediate() (string, error) {
ca, err := c.ActiveIntermediate() ca, err := c.ActiveIntermediate()
if err != nil { if err != nil {
return "", err return "", err
@ -157,7 +155,7 @@ func (c *ConsulCAProvider) GenerateIntermediate() (string, error) {
} }
// Remove the state store entry for this provider instance. // Remove the state store entry for this provider instance.
func (c *ConsulCAProvider) Cleanup() error { func (c *ConsulProvider) Cleanup() error {
args := &structs.CARequest{ args := &structs.CARequest{
Op: structs.CAOpDeleteProviderState, Op: structs.CAOpDeleteProviderState,
ProviderState: &structs.CAConsulProviderState{ID: c.id}, ProviderState: &structs.CAConsulProviderState{ID: c.id},
@ -171,7 +169,7 @@ func (c *ConsulCAProvider) Cleanup() error {
// Sign returns a new certificate valid for the given SpiffeIDService // Sign returns a new certificate valid for the given SpiffeIDService
// using the current CA. // using the current CA.
func (c *ConsulCAProvider) Sign(csr *x509.CertificateRequest) (string, error) { func (c *ConsulProvider) Sign(csr *x509.CertificateRequest) (string, error) {
// Lock during the signing so we don't use the same index twice // Lock during the signing so we don't use the same index twice
// for different cert serial numbers. // for different cert serial numbers.
c.Lock() c.Lock()
@ -262,7 +260,7 @@ func (c *ConsulCAProvider) Sign(csr *x509.CertificateRequest) (string, error) {
} }
// CrossSignCA returns the given intermediate CA cert signed by the current active root. // CrossSignCA returns the given intermediate CA cert signed by the current active root.
func (c *ConsulCAProvider) CrossSignCA(cert *x509.Certificate) (string, error) { func (c *ConsulProvider) CrossSignCA(cert *x509.Certificate) (string, error) {
c.Lock() c.Lock()
defer c.Unlock() defer c.Unlock()
@ -319,7 +317,7 @@ func (c *ConsulCAProvider) CrossSignCA(cert *x509.Certificate) (string, error) {
// incrementProviderIndex does a write to increment the provider state store table index // incrementProviderIndex does a write to increment the provider state store table index
// used for serial numbers when generating certificates. // used for serial numbers when generating certificates.
func (c *ConsulCAProvider) incrementProviderIndex(providerState *structs.CAConsulProviderState) error { func (c *ConsulProvider) incrementProviderIndex(providerState *structs.CAConsulProviderState) error {
newState := *providerState newState := *providerState
args := &structs.CARequest{ args := &structs.CARequest{
Op: structs.CAOpSetProviderState, Op: structs.CAOpSetProviderState,
@ -332,31 +330,8 @@ func (c *ConsulCAProvider) incrementProviderIndex(providerState *structs.CAConsu
return nil return nil
} }
// GeneratePrivateKey returns a new private key
func GeneratePrivateKey() (string, error) {
var pk *ecdsa.PrivateKey
pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return "", fmt.Errorf("error generating private key: %s", err)
}
bs, err := x509.MarshalECPrivateKey(pk)
if err != nil {
return "", fmt.Errorf("error generating private key: %s", err)
}
var buf bytes.Buffer
err = pem.Encode(&buf, &pem.Block{Type: "EC PRIVATE KEY", Bytes: bs})
if err != nil {
return "", fmt.Errorf("error encoding private key: %s", err)
}
return buf.String(), nil
}
// generateCA makes a new root CA using the current private key // generateCA makes a new root CA using the current private key
func (c *ConsulCAProvider) generateCA(privateKey string, sn uint64) (string, error) { func (c *ConsulProvider) generateCA(privateKey string, sn uint64) (string, error) {
state := c.delegate.State() state := c.delegate.State()
_, config, err := state.CAConfig() _, config, err := state.CAConfig()
if err != nil { if err != nil {

View file

@ -74,7 +74,7 @@ func TestCAProvider_Bootstrap(t *testing.T) {
conf := testConsulCAConfig() conf := testConsulCAConfig()
delegate := newMockDelegate(t, conf) delegate := newMockDelegate(t, conf)
provider, err := NewConsulCAProvider(conf.Config, delegate) provider, err := NewConsulProvider(conf.Config, delegate)
assert.NoError(err) assert.NoError(err)
root, err := provider.ActiveRoot() root, err := provider.ActiveRoot()
@ -104,7 +104,7 @@ func TestCAProvider_Bootstrap_WithCert(t *testing.T) {
} }
delegate := newMockDelegate(t, conf) delegate := newMockDelegate(t, conf)
provider, err := NewConsulCAProvider(conf.Config, delegate) provider, err := NewConsulProvider(conf.Config, delegate)
assert.NoError(err) assert.NoError(err)
root, err := provider.ActiveRoot() root, err := provider.ActiveRoot()
@ -119,7 +119,7 @@ func TestCAProvider_SignLeaf(t *testing.T) {
conf := testConsulCAConfig() conf := testConsulCAConfig()
delegate := newMockDelegate(t, conf) delegate := newMockDelegate(t, conf)
provider, err := NewConsulCAProvider(conf.Config, delegate) provider, err := NewConsulProvider(conf.Config, delegate)
assert.NoError(err) assert.NoError(err)
spiffeService := &connect.SpiffeIDService{ spiffeService := &connect.SpiffeIDService{
@ -143,7 +143,7 @@ func TestCAProvider_SignLeaf(t *testing.T) {
assert.NoError(err) assert.NoError(err)
assert.Equal(parsed.URIs[0], spiffeService.URI()) assert.Equal(parsed.URIs[0], spiffeService.URI())
assert.Equal(parsed.Subject.CommonName, "foo") assert.Equal(parsed.Subject.CommonName, "foo")
assert.Equal(parsed.SerialNumber.Uint64(), uint64(1)) assert.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.
assert.True(parsed.NotAfter.Sub(time.Now()) < 3*24*time.Hour) assert.True(parsed.NotAfter.Sub(time.Now()) < 3*24*time.Hour)
@ -180,7 +180,7 @@ func TestCAProvider_CrossSignCA(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
conf := testConsulCAConfig() conf := testConsulCAConfig()
delegate := newMockDelegate(t, conf) delegate := newMockDelegate(t, conf)
provider, err := NewConsulCAProvider(conf.Config, delegate) provider, err := NewConsulProvider(conf.Config, delegate)
assert.NoError(err) assert.NoError(err)
// Make a new CA cert to get cross-signed. // Make a new CA cert to get cross-signed.

34
agent/connect/generate.go Normal file
View file

@ -0,0 +1,34 @@
package connect
import (
"bytes"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"encoding/pem"
"fmt"
)
// GeneratePrivateKey returns a new private key
func GeneratePrivateKey() (string, error) {
var pk *ecdsa.PrivateKey
pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return "", fmt.Errorf("error generating private key: %s", err)
}
bs, err := x509.MarshalECPrivateKey(pk)
if err != nil {
return "", fmt.Errorf("error generating private key: %s", err)
}
var buf bytes.Buffer
err = pem.Encode(&buf, &pem.Block{Type: "EC PRIVATE KEY", Bytes: bs})
if err != nil {
return "", fmt.Errorf("error encoding private key: %s", err)
}
return buf.String(), nil
}

View file

@ -8,7 +8,7 @@ import (
"time" "time"
"github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/connect"
connect_ca "github.com/hashicorp/consul/agent/connect/ca" ca "github.com/hashicorp/consul/agent/connect/ca"
"github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/structs"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -77,7 +77,7 @@ func TestConnectCAConfig(t *testing.T) {
assert.NoError(err) assert.NoError(err)
value := obj.(structs.CAConfiguration) value := obj.(structs.CAConfiguration)
parsed, err := connect_ca.ParseConsulCAConfig(value.Config) parsed, err := ca.ParseConsulCAConfig(value.Config)
assert.NoError(err) assert.NoError(err)
assert.Equal("consul", value.Provider) assert.Equal("consul", value.Provider)
assert.Equal(expected, parsed) assert.Equal(expected, parsed)
@ -107,8 +107,7 @@ func TestConnectCAConfig(t *testing.T) {
assert.NoError(err) assert.NoError(err)
value := obj.(structs.CAConfiguration) value := obj.(structs.CAConfiguration)
//t.Fatalf("%#v", value) parsed, err := ca.ParseConsulCAConfig(value.Config)
parsed, err := connect_ca.ParseConsulCAConfig(value.Config)
assert.NoError(err) assert.NoError(err)
assert.Equal("consul", value.Provider) assert.Equal("consul", value.Provider)
assert.Equal(expected, parsed) assert.Equal(expected, parsed)

View file

@ -7,7 +7,7 @@ import (
"time" "time"
"github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/connect"
connect_ca "github.com/hashicorp/consul/agent/connect/ca" ca "github.com/hashicorp/consul/agent/connect/ca"
"github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/testrpc" "github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/net-rpc-msgpackrpc" "github.com/hashicorp/net-rpc-msgpackrpc"
@ -83,9 +83,9 @@ func TestConnectCAConfig_GetSet(t *testing.T) {
var reply structs.CAConfiguration var reply structs.CAConfiguration
assert.NoError(msgpackrpc.CallWithCodec(codec, "ConnectCA.ConfigurationGet", args, &reply)) assert.NoError(msgpackrpc.CallWithCodec(codec, "ConnectCA.ConfigurationGet", args, &reply))
actual, err := connect_ca.ParseConsulCAConfig(reply.Config) actual, err := ca.ParseConsulCAConfig(reply.Config)
assert.NoError(err) assert.NoError(err)
expected, err := connect_ca.ParseConsulCAConfig(s1.config.CAConfig.Config) expected, err := ca.ParseConsulCAConfig(s1.config.CAConfig.Config)
assert.NoError(err) assert.NoError(err)
assert.Equal(reply.Provider, s1.config.CAConfig.Provider) assert.Equal(reply.Provider, s1.config.CAConfig.Provider)
assert.Equal(actual, expected) assert.Equal(actual, expected)
@ -118,9 +118,9 @@ func TestConnectCAConfig_GetSet(t *testing.T) {
var reply structs.CAConfiguration var reply structs.CAConfiguration
assert.NoError(msgpackrpc.CallWithCodec(codec, "ConnectCA.ConfigurationGet", args, &reply)) assert.NoError(msgpackrpc.CallWithCodec(codec, "ConnectCA.ConfigurationGet", args, &reply))
actual, err := connect_ca.ParseConsulCAConfig(reply.Config) actual, err := ca.ParseConsulCAConfig(reply.Config)
assert.NoError(err) assert.NoError(err)
expected, err := connect_ca.ParseConsulCAConfig(newConfig.Config) expected, err := ca.ParseConsulCAConfig(newConfig.Config)
assert.NoError(err) assert.NoError(err)
assert.Equal(reply.Provider, newConfig.Provider) assert.Equal(reply.Provider, newConfig.Provider)
assert.Equal(actual, expected) assert.Equal(actual, expected)
@ -150,7 +150,7 @@ func TestConnectCAConfig_TriggerRotation(t *testing.T) {
// Update the provider config to use a new private key, which should // Update the provider config to use a new private key, which should
// cause a rotation. // cause a rotation.
newKey, err := connect_ca.GeneratePrivateKey() newKey, err := connect.GeneratePrivateKey()
assert.NoError(err) assert.NoError(err)
newConfig := &structs.CAConfiguration{ newConfig := &structs.CAConfiguration{
Provider: "consul", Provider: "consul",
@ -220,9 +220,9 @@ func TestConnectCAConfig_TriggerRotation(t *testing.T) {
var reply structs.CAConfiguration var reply structs.CAConfiguration
assert.NoError(msgpackrpc.CallWithCodec(codec, "ConnectCA.ConfigurationGet", args, &reply)) assert.NoError(msgpackrpc.CallWithCodec(codec, "ConnectCA.ConfigurationGet", args, &reply))
actual, err := connect_ca.ParseConsulCAConfig(reply.Config) actual, err := ca.ParseConsulCAConfig(reply.Config)
assert.NoError(err) assert.NoError(err)
expected, err := connect_ca.ParseConsulCAConfig(newConfig.Config) expected, err := ca.ParseConsulCAConfig(newConfig.Config)
assert.NoError(err) assert.NoError(err)
assert.Equal(reply.Provider, newConfig.Provider) assert.Equal(reply.Provider, newConfig.Provider)
assert.Equal(actual, expected) assert.Equal(actual, expected)

View file

@ -11,7 +11,7 @@ import (
"github.com/armon/go-metrics" "github.com/armon/go-metrics"
"github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/connect"
connect_ca "github.com/hashicorp/consul/agent/connect/ca" ca "github.com/hashicorp/consul/agent/connect/ca"
"github.com/hashicorp/consul/agent/consul/autopilot" "github.com/hashicorp/consul/agent/consul/autopilot"
"github.com/hashicorp/consul/agent/metadata" "github.com/hashicorp/consul/agent/metadata"
"github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/structs"
@ -496,18 +496,18 @@ func parseCARoot(pemValue, provider string) (*structs.CARoot, error) {
} }
// createProvider returns a connect CA provider from the given config. // createProvider returns a connect CA provider from the given config.
func (s *Server) createCAProvider(conf *structs.CAConfiguration) (connect_ca.Provider, error) { func (s *Server) createCAProvider(conf *structs.CAConfiguration) (ca.Provider, error) {
switch conf.Provider { switch conf.Provider {
case structs.ConsulCAProvider: case structs.ConsulCAProvider:
return connect_ca.NewConsulCAProvider(conf.Config, &consulCADelegate{s}) return ca.NewConsulProvider(conf.Config, &consulCADelegate{s})
default: default:
return nil, fmt.Errorf("unknown CA provider %q", conf.Provider) return nil, fmt.Errorf("unknown CA provider %q", conf.Provider)
} }
} }
func (s *Server) getCAProvider() connect.CAProvider { func (s *Server) getCAProvider() ca.Provider {
retries := 0 retries := 0
var result connect.CAProvider var result ca.Provider
for result == nil { for result == nil {
s.caProviderLock.RLock() s.caProviderLock.RLock()
result = s.caProvider result = s.caProvider
@ -528,7 +528,7 @@ func (s *Server) getCAProvider() connect.CAProvider {
return result return result
} }
func (s *Server) setCAProvider(newProvider connect_ca.Provider) { func (s *Server) setCAProvider(newProvider ca.Provider) {
s.caProviderLock.Lock() s.caProviderLock.Lock()
defer s.caProviderLock.Unlock() defer s.caProviderLock.Unlock()
s.caProvider = newProvider s.caProvider = newProvider

View file

@ -18,7 +18,7 @@ import (
"time" "time"
"github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/acl"
connect_ca "github.com/hashicorp/consul/agent/connect/ca" ca "github.com/hashicorp/consul/agent/connect/ca"
"github.com/hashicorp/consul/agent/consul/autopilot" "github.com/hashicorp/consul/agent/consul/autopilot"
"github.com/hashicorp/consul/agent/consul/fsm" "github.com/hashicorp/consul/agent/consul/fsm"
"github.com/hashicorp/consul/agent/consul/state" "github.com/hashicorp/consul/agent/consul/state"
@ -99,7 +99,7 @@ type Server struct {
// caProvider is the current CA provider in use for Connect. This is // caProvider is the current CA provider in use for Connect. This is
// only non-nil when we are the leader. // only non-nil when we are the leader.
caProvider connect_ca.Provider caProvider ca.Provider
caProviderLock sync.RWMutex caProviderLock sync.RWMutex
// Consul configuration // Consul configuration