From ee2be2979f5bb101f587b92efcf54339f736a51c Mon Sep 17 00:00:00 2001 From: Russell Jones Date: Mon, 11 Mar 2019 17:49:30 -0700 Subject: [PATCH] Improved error when CA pin does not match. Improved error messaging when Certificate Authority (CA) pin does not match provided pin. Fixed typo in abbreviation of "Subject Public Key Info" from SKPI to SPKI. --- lib/auth/register.go | 4 ++-- lib/auth/tls_test.go | 2 +- lib/utils/{skpi.go => spki.go} | 21 +++++++++++++-------- tool/tctl/common/token_command.go | 4 ++-- 4 files changed, 18 insertions(+), 13 deletions(-) rename lib/utils/{skpi.go => spki.go} (56%) diff --git a/lib/auth/register.go b/lib/auth/register.go index abc7322c68d..45d98af293d 100644 --- a/lib/auth/register.go +++ b/lib/auth/register.go @@ -209,10 +209,10 @@ func pinRegisterClient(params RegisterParams) (*Client, error) { return nil, trace.Wrap(err) } - // Check that the SKPI pin matches the CA we fetched over a insecure + // Check that the SPKI pin matches the CA we fetched over a insecure // connection. This makes sure the CA fetched over a insecure connection is // in-fact the expected CA. - err = utils.CheckSKPI(params.CAPin, tlsCA) + err = utils.CheckSPKI(params.CAPin, tlsCA) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/auth/tls_test.go b/lib/auth/tls_test.go index f5aba776ab2..6f50e985f9f 100644 --- a/lib/auth/tls_test.go +++ b/lib/auth/tls_test.go @@ -1699,7 +1699,7 @@ func (s *TLSSuite) TestRegisterCAPin(c *check.C) { c.Assert(err, check.IsNil) tlsCA, err := hostCA.TLSCA() c.Assert(err, check.IsNil) - caPin := utils.CalculateSKPI(tlsCA.Cert) + caPin := utils.CalculateSPKI(tlsCA.Cert) // Attempt to register with valid CA pin, should work. _, err = Register(RegisterParams{ diff --git a/lib/utils/skpi.go b/lib/utils/spki.go similarity index 56% rename from lib/utils/skpi.go rename to lib/utils/spki.go index a5a58b7a93e..a054fc38652 100644 --- a/lib/utils/skpi.go +++ b/lib/utils/spki.go @@ -26,28 +26,33 @@ import ( "github.com/gravitational/trace" ) -// CalculateSKPI the hash value of the SPKI header in a certificate. -func CalculateSKPI(cert *x509.Certificate) string { +// CalculateSPKI the hash value of the SPKI header in a certificate. +func CalculateSPKI(cert *x509.Certificate) string { sum := sha256.Sum256(cert.RawSubjectPublicKeyInfo) return "sha256:" + hex.EncodeToString(sum[:]) } -// CheckSKPI the passed in pin against the calculated value from a certificate. -func CheckSKPI(pin string, cert *x509.Certificate) error { +// CheckSPKI the passed in pin against the calculated value from a certificate. +func CheckSPKI(pin string, cert *x509.Certificate) error { // Check that the format of the pin is valid. parts := strings.Split(pin, ":") if len(parts) != 2 { - return trace.BadParameter("invalid format for SKPI hash") + return trace.BadParameter("invalid format for certificate pin, expected algorithm:pin") } if parts[0] != "sha256" { - return trace.BadParameter("only sha256 supported by SKPI hash") + return trace.BadParameter("sha256 only supported hashing algorithm for certificate pin") } // Check that that pin itself matches that value calculated from the passed // in certificate. - if subtle.ConstantTimeCompare([]byte(CalculateSKPI(cert)), []byte(pin)) != 1 { - return trace.BadParameter("SKPI values do not match") + if subtle.ConstantTimeCompare([]byte(CalculateSPKI(cert)), []byte(pin)) != 1 { + return trace.BadParameter(errorMessage) } return nil } + +var errorMessage string = "provided certificate pin does not match cluster pin. " + + "This could have occurred if the Certificate Authority (CA) for the cluster " + + "was rotated, invalidating the old pin. Run \"tctl status\" to compare the pin " + + "used to join the cluster to the actual pin for the cluster." diff --git a/tool/tctl/common/token_command.go b/tool/tctl/common/token_command.go index e761aae79ba..b35dc490984 100644 --- a/tool/tctl/common/token_command.go +++ b/tool/tctl/common/token_command.go @@ -193,7 +193,7 @@ func (c *TokenCommand) List(client auth.ClientI) error { return nil } -// calculateCAPin returns the SKPI pin for the local cluster. +// calculateCAPin returns the SPKI pin for the local cluster. func calculateCAPin(client auth.ClientI) (string, error) { localCA, err := client.GetClusterCACert() if err != nil { @@ -204,5 +204,5 @@ func calculateCAPin(client auth.ClientI) (string, error) { return "", trace.Wrap(err) } - return utils.CalculateSKPI(tlsCA), nil + return utils.CalculateSPKI(tlsCA), nil }