Skip to content

Commit

Permalink
Merge pull request #7019 from hashicorp/connect_fixes
Browse files Browse the repository at this point in the history
Connect fixes
  • Loading branch information
hanshasselberg authored Jan 9, 2020
2 parents 1d77f34 + c50d9ab commit d867616
Show file tree
Hide file tree
Showing 9 changed files with 176 additions and 85 deletions.
83 changes: 43 additions & 40 deletions agent/connect/ca/provider_consul.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type ConsulProvider struct {

type ConsulProviderStateDelegate interface {
State() *state.Store
ApplyCARequest(*structs.CARequest) error
ApplyCARequest(*structs.CARequest) (interface{}, error)
}

// Configure sets up the provider using the given configuration.
Expand Down Expand Up @@ -78,15 +78,15 @@ func (c *ConsulProvider) Configure(clusterID string, isRoot bool, rawConfig map[
Op: structs.CAOpSetProviderState,
ProviderState: &newState,
}
if err := c.Delegate.ApplyCARequest(createReq); err != nil {
if _, err := c.Delegate.ApplyCARequest(createReq); err != nil {
return err
}

deleteReq := &structs.CARequest{
Op: structs.CAOpDeleteProviderState,
ProviderState: providerState,
}
if err := c.Delegate.ApplyCARequest(deleteReq); err != nil {
if _, err := c.Delegate.ApplyCARequest(deleteReq); err != nil {
return err
}

Expand All @@ -102,7 +102,7 @@ func (c *ConsulProvider) Configure(clusterID string, isRoot bool, rawConfig map[
Op: structs.CAOpSetProviderState,
ProviderState: &newState,
}
if err := c.Delegate.ApplyCARequest(args); err != nil {
if _, err := c.Delegate.ApplyCARequest(args); err != nil {
return err
}

Expand All @@ -122,7 +122,7 @@ func (c *ConsulProvider) ActiveRoot() (string, error) {
// GenerateRoot initializes a new root certificate and private key
// if needed.
func (c *ConsulProvider) GenerateRoot() error {
idx, providerState, err := c.getState()
_, providerState, err := c.getState()
if err != nil {
return err
}
Expand All @@ -148,7 +148,12 @@ func (c *ConsulProvider) GenerateRoot() error {

// Generate the root CA if necessary
if c.config.RootCert == "" {
ca, err := c.generateCA(newState.PrivateKey, idx+1)
nextSerial, err := c.incrementAndGetNextSerialNumber()
if err != nil {
return fmt.Errorf("error computing next serial number: %v", err)
}

ca, err := c.generateCA(newState.PrivateKey, nextSerial)
if err != nil {
return fmt.Errorf("error generating CA: %v", err)
}
Expand All @@ -162,7 +167,7 @@ func (c *ConsulProvider) GenerateRoot() error {
Op: structs.CAOpSetProviderState,
ProviderState: &newState,
}
if err := c.Delegate.ApplyCARequest(args); err != nil {
if _, err := c.Delegate.ApplyCARequest(args); err != nil {
return err
}

Expand Down Expand Up @@ -200,7 +205,7 @@ func (c *ConsulProvider) GenerateIntermediateCSR() (string, error) {
Op: structs.CAOpSetProviderState,
ProviderState: &newState,
}
if err := c.Delegate.ApplyCARequest(args); err != nil {
if _, err := c.Delegate.ApplyCARequest(args); err != nil {
return "", err
}

Expand Down Expand Up @@ -236,7 +241,7 @@ func (c *ConsulProvider) SetIntermediate(intermediatePEM, rootPEM string) error
Op: structs.CAOpSetProviderState,
ProviderState: &newState,
}
if err := c.Delegate.ApplyCARequest(args); err != nil {
if _, err := c.Delegate.ApplyCARequest(args); err != nil {
return err
}

Expand Down Expand Up @@ -270,7 +275,7 @@ func (c *ConsulProvider) Cleanup() error {
Op: structs.CAOpDeleteProviderState,
ProviderState: &structs.CAConsulProviderState{ID: c.id},
}
if err := c.Delegate.ApplyCARequest(args); err != nil {
if _, err := c.Delegate.ApplyCARequest(args); err != nil {
return err
}

Expand All @@ -286,7 +291,7 @@ func (c *ConsulProvider) Sign(csr *x509.CertificateRequest) (string, error) {
defer c.Unlock()

// Get the provider state
idx, providerState, err := c.getState()
_, providerState, err := c.getState()
if err != nil {
return "", err
}
Expand Down Expand Up @@ -333,9 +338,14 @@ func (c *ConsulProvider) Sign(csr *x509.CertificateRequest) (string, error) {
return "", fmt.Errorf("error parsing CA cert: %s", err)
}

nextSerial, err := c.incrementAndGetNextSerialNumber()
if err != nil {
return "", fmt.Errorf("error computing next serial number: %v", err)
}

// Cert template for generation
sn := &big.Int{}
sn.SetUint64(idx + 1)
sn.SetUint64(nextSerial)
// Sign the certificate valid from 1 minute in the past, this helps it be
// accepted right away even when nodes are not in close time sync across the
// cluster. A minute is more than enough for typical DC clock drift.
Expand Down Expand Up @@ -375,11 +385,6 @@ func (c *ConsulProvider) Sign(csr *x509.CertificateRequest) (string, error) {
return "", fmt.Errorf("error encoding certificate: %s", err)
}

err = c.incrementProviderIndex(providerState)
if err != nil {
return "", err
}

// Set the response
return buf.String(), nil
}
Expand All @@ -389,7 +394,7 @@ func (c *ConsulProvider) Sign(csr *x509.CertificateRequest) (string, error) {
// are met. It should return a signed CA certificate with a path length constraint
// of 0 to ensure that the certificate cannot be used to generate further CA certs.
func (c *ConsulProvider) SignIntermediate(csr *x509.CertificateRequest) (string, error) {
idx, providerState, err := c.getState()
_, providerState, err := c.getState()
if err != nil {
return "", err
}
Expand Down Expand Up @@ -424,9 +429,14 @@ func (c *ConsulProvider) SignIntermediate(csr *x509.CertificateRequest) (string,
return "", fmt.Errorf("error parsing CA cert: %s", err)
}

nextSerial, err := c.incrementAndGetNextSerialNumber()
if err != nil {
return "", fmt.Errorf("error computing next serial number: %v", err)
}

// Cert template for generation
sn := &big.Int{}
sn.SetUint64(idx + 1)
sn.SetUint64(nextSerial)
// Sign the certificate valid from 1 minute in the past, this helps it be
// accepted right away even when nodes are not in close time sync across the
// cluster. A minute is more than enough for typical DC clock drift.
Expand Down Expand Up @@ -462,11 +472,6 @@ func (c *ConsulProvider) SignIntermediate(csr *x509.CertificateRequest) (string,
return "", fmt.Errorf("error encoding certificate: %s", err)
}

err = c.incrementProviderIndex(providerState)
if err != nil {
return "", err
}

// Set the response
return buf.String(), nil
}
Expand All @@ -477,7 +482,7 @@ func (c *ConsulProvider) CrossSignCA(cert *x509.Certificate) (string, error) {
defer c.Unlock()

// Get the provider state
idx, providerState, err := c.getState()
_, providerState, err := c.getState()
if err != nil {
return "", err
}
Expand All @@ -497,9 +502,14 @@ func (c *ConsulProvider) CrossSignCA(cert *x509.Certificate) (string, error) {
return "", err
}

nextSerial, err := c.incrementAndGetNextSerialNumber()
if err != nil {
return "", fmt.Errorf("error computing next serial number: %v", err)
}

// Create the cross-signing template from the existing root CA
serialNum := &big.Int{}
serialNum.SetUint64(idx + 1)
serialNum.SetUint64(nextSerial)
template := *cert
template.SerialNumber = serialNum
template.SignatureAlgorithm = rootCA.SignatureAlgorithm
Expand Down Expand Up @@ -528,11 +538,6 @@ func (c *ConsulProvider) CrossSignCA(cert *x509.Certificate) (string, error) {
return "", fmt.Errorf("error encoding private key: %s", err)
}

err = c.incrementProviderIndex(providerState)
if err != nil {
return "", err
}

return buf.String(), nil
}

Expand All @@ -552,19 +557,17 @@ func (c *ConsulProvider) getState() (uint64, *structs.CAConsulProviderState, err
return idx, providerState, nil
}

// incrementProviderIndex does a write to increment the provider state store table index
// used for serial numbers when generating certificates.
func (c *ConsulProvider) incrementProviderIndex(providerState *structs.CAConsulProviderState) error {
newState := *providerState
func (c *ConsulProvider) incrementAndGetNextSerialNumber() (uint64, error) {
args := &structs.CARequest{
Op: structs.CAOpSetProviderState,
ProviderState: &newState,
Op: structs.CAOpIncrementProviderSerialNumber,
}
if err := c.Delegate.ApplyCARequest(args); err != nil {
return err

raw, err := c.Delegate.ApplyCARequest(args)
if err != nil {
return 0, err
}

return nil
return raw.(uint64), nil
}

// generateCA makes a new root CA using the current private key
Expand Down
18 changes: 10 additions & 8 deletions agent/connect/ca/provider_consul_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,30 @@ func (c *consulCAMockDelegate) State() *state.Store {
return c.state
}

func (c *consulCAMockDelegate) ApplyCARequest(req *structs.CARequest) error {
func (c *consulCAMockDelegate) ApplyCARequest(req *structs.CARequest) (interface{}, error) {
idx, _, err := c.state.CAConfig(nil)
if err != nil {
return err
return nil, err
}

switch req.Op {
case structs.CAOpSetProviderState:
_, err := c.state.CASetProviderState(idx+1, req.ProviderState)
if err != nil {
return err
return nil, err
}

return nil
return true, nil
case structs.CAOpDeleteProviderState:
if err := c.state.CADeleteProviderState(req.ProviderState.ID); err != nil {
return err
return nil, err
}

return nil
return true, nil
case structs.CAOpIncrementProviderSerialNumber:
return uint64(2), nil
default:
return fmt.Errorf("Invalid CA operation '%s'", req.Op)
return nil, fmt.Errorf("Invalid CA operation '%s'", req.Op)
}
}

Expand Down Expand Up @@ -405,7 +407,7 @@ func TestConsulCAProvider_MigrateOldID(t *testing.T) {
delegate := newMockDelegate(t, conf)

// Create an entry with an old-style ID.
err := delegate.ApplyCARequest(&structs.CARequest{
_, err := delegate.ApplyCARequest(&structs.CARequest{
Op: structs.CAOpSetProviderState,
ProviderState: &structs.CAConsulProviderState{
ID: ",",
Expand Down
8 changes: 4 additions & 4 deletions agent/consul/consul_ca_delegate.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ func (c *consulCADelegate) State() *state.Store {
return c.srv.fsm.State()
}

func (c *consulCADelegate) ApplyCARequest(req *structs.CARequest) error {
func (c *consulCADelegate) ApplyCARequest(req *structs.CARequest) (interface{}, error) {
resp, err := c.srv.raftApply(structs.ConnectCARequestType, req)
if err != nil {
return err
return nil, err
}
if respErr, ok := resp.(error); ok {
return respErr
return nil, respErr
}

return nil
return resp, nil
}
7 changes: 7 additions & 0 deletions agent/consul/fsm/commands_oss.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,13 @@ func (c *FSM) applyConnectCAOperation(buf []byte, index uint64) interface{} {
return err
}
return act
case structs.CAOpIncrementProviderSerialNumber:
sn, err := c.state.CAIncrementProviderSerialNumber()
if err != nil {
return err
}

return sn
default:
c.logger.Printf("[WARN] consul.fsm: Invalid CA operation '%s'", req.Op)
return fmt.Errorf("Invalid CA operation '%s'", req.Op)
Expand Down
Loading

0 comments on commit d867616

Please sign in to comment.