diff --git a/agent/consul/connect_ca_endpoint.go b/agent/consul/connect_ca_endpoint.go index 619418baba..8acaa4ed09 100644 --- a/agent/consul/connect_ca_endpoint.go +++ b/agent/consul/connect_ca_endpoint.go @@ -98,15 +98,9 @@ func (s *ConnectCA) ConfigurationSet( return err } - id, err := connect.CalculateCertFingerprint(newRootPEM) + newActiveRoot, err := parseCARoot(newRootPEM, args.Config.Provider) if err != nil { - return fmt.Errorf("error parsing root fingerprint: %v", err) - } - newActiveRoot := &structs.CARoot{ - ID: id, - Name: fmt.Sprintf("%s CA Root Cert", config.Provider), - RootCert: newRootPEM, - Active: true, + return err } // Compare the new provider's root CA ID to the current one. If they @@ -240,6 +234,10 @@ func (s *ConnectCA) Roots( reply.Roots[i] = &structs.CARoot{ ID: r.ID, Name: r.Name, + SerialNumber: r.SerialNumber, + SigningKeyID: r.SigningKeyID, + NotBefore: r.NotBefore, + NotAfter: r.NotAfter, RootCert: r.RootCert, IntermediateCerts: r.IntermediateCerts, RaftIndex: r.RaftIndex, diff --git a/agent/consul/leader.go b/agent/consul/leader.go index b07a3622d8..a06871888e 100644 --- a/agent/consul/leader.go +++ b/agent/consul/leader.go @@ -4,6 +4,7 @@ import ( "fmt" "net" "strconv" + "strings" "sync" "time" @@ -427,15 +428,9 @@ func (s *Server) initializeCA() error { return fmt.Errorf("error getting root cert: %v", err) } - id, err := connect.CalculateCertFingerprint(rootPEM) + rootCA, err := parseCARoot(rootPEM, conf.Provider) if err != nil { - return fmt.Errorf("error parsing root fingerprint: %v", err) - } - rootCA := &structs.CARoot{ - ID: id, - Name: fmt.Sprintf("%s CA Root Cert", conf.Provider), - RootCert: rootPEM, - Active: true, + return err } // Check if the CA root is already initialized and exit if it is. @@ -478,6 +473,28 @@ func (s *Server) initializeCA() error { return nil } +// parseCARoot returns a filled-in structs.CARoot from a raw PEM value. +func parseCARoot(pemValue, provider string) (*structs.CARoot, error) { + id, err := connect.CalculateCertFingerprint(pemValue) + if err != nil { + return nil, fmt.Errorf("error parsing root fingerprint: %v", err) + } + rootCert, err := connect.ParseCert(pemValue) + if err != nil { + return nil, fmt.Errorf("error parsing root cert: %v", err) + } + return &structs.CARoot{ + ID: id, + Name: fmt.Sprintf("%s CA Root Cert", strings.Title(provider)), + SerialNumber: rootCert.SerialNumber.Uint64(), + SigningKeyID: connect.HexString(rootCert.AuthorityKeyId), + NotBefore: rootCert.NotBefore, + NotAfter: rootCert.NotAfter, + RootCert: pemValue, + Active: true, + }, nil +} + // createProvider returns a connect CA provider from the given config. func (s *Server) createCAProvider(conf *structs.CAConfiguration) (connect_ca.Provider, error) { switch conf.Provider { diff --git a/agent/structs/connect_ca.go b/agent/structs/connect_ca.go index ca60a677fb..3a4ca81313 100644 --- a/agent/structs/connect_ca.go +++ b/agent/structs/connect_ca.go @@ -28,6 +28,17 @@ type CARoot struct { // opaque to Consul and is not used for anything internally. Name string + // SerialNumber is the x509 serial number of the certificate. + SerialNumber uint64 + + // SigningKeyID is the ID of the public key that corresponds to the + // private key used to sign the certificate. + SigningKeyID string + + // Time validity bounds. + NotBefore time.Time + NotAfter time.Time + // RootCert is the PEM-encoded public certificate. RootCert string