From 9ef6b207218572b3257a5b4251418d75569baaae Mon Sep 17 00:00:00 2001 From: Hayden B Date: Wed, 27 Apr 2022 06:40:34 -0700 Subject: [PATCH] Support PKCS1 encoded and non-ECDSA CT log public keys (#1806) * Support PKCS1 encoded CT log public keys This came up while testing out staging, which uses a PKCS1 encoded public key. We should be flexible on the supported key format. Signed-off-by: Hayden Blauzvern * Update comment Signed-off-by: Hayden Blauzvern * Remove requirement that key is ECDSA Signed-off-by: Hayden Blauzvern --- .../cli/fulcio/fulcioverifier/ctl/verify.go | 21 +++++++------------ .../fulcio/fulcioverifier/ctl/verify_test.go | 4 ++-- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/cmd/cosign/cli/fulcio/fulcioverifier/ctl/verify.go b/cmd/cosign/cli/fulcio/fulcioverifier/ctl/verify.go index 49ca970fb82..c2af470cc21 100644 --- a/cmd/cosign/cli/fulcio/fulcioverifier/ctl/verify.go +++ b/cmd/cosign/cli/fulcio/fulcioverifier/ctl/verify.go @@ -17,7 +17,6 @@ package ctl import ( "context" "crypto" - "crypto/ecdsa" "crypto/sha256" "crypto/x509" "encoding/json" @@ -89,19 +88,15 @@ func VerifySCT(ctx context.Context, certPEM, chainPEM, rawSCT []byte) error { return err } for _, t := range targets { - pub, err := cryptoutils.UnmarshalPEMToPublicKey(t.Target) + pub, err := getPublicKey(t.Target) if err != nil { return err } - ctPub, ok := pub.(*ecdsa.PublicKey) - if !ok { - return fmt.Errorf("invalid public key: was %T, require *ecdsa.PublicKey", pub) - } - keyID, err := ctutil.GetCTLogID(ctPub) + keyID, err := ctutil.GetCTLogID(pub) if err != nil { return errors.Wrap(err, "error getting CTFE public key hash") } - pubKeys[keyID] = logIDMetadata{ctPub, t.Status} + pubKeys[keyID] = logIDMetadata{pub, t.Status} } } else { fmt.Fprintf(os.Stderr, "**Warning** Using a non-standard public key for verifying SCT: %s\n", rootEnv) @@ -109,7 +104,7 @@ func VerifySCT(ctx context.Context, certPEM, chainPEM, rawSCT []byte) error { if err != nil { return errors.Wrap(err, "error reading alternate public key file") } - pubKey, err := getAlternatePublicKey(raw) + pubKey, err := getPublicKey(raw) if err != nil { return errors.Wrap(err, "error parsing alternate public key from the file") } @@ -204,9 +199,9 @@ func VerifyEmbeddedSCT(ctx context.Context, chain []*x509.Certificate) error { } // Given a byte array, try to construct a public key from it. -// Will try first to see if it's PEM formatted, if not, then it will -// try to parse it as der publics, and failing that -func getAlternatePublicKey(in []byte) (crypto.PublicKey, error) { +// Supports PEM encoded public keys, falling back to DER. Supports +// PKIX and PKCS1 encoded keys. +func getPublicKey(in []byte) (crypto.PublicKey, error) { var pubKey crypto.PublicKey var err error var derBytes []byte @@ -222,7 +217,7 @@ func getAlternatePublicKey(in []byte) (crypto.PublicKey, error) { // Try using the PKCS1 before giving up. pubKey, err = x509.ParsePKCS1PublicKey(derBytes) if err != nil { - return nil, errors.Wrap(err, "failed to parse alternate public key") + return nil, errors.Wrap(err, "failed to parse CT log public key") } } return pubKey, nil diff --git a/cmd/cosign/cli/fulcio/fulcioverifier/ctl/verify_test.go b/cmd/cosign/cli/fulcio/fulcioverifier/ctl/verify_test.go index 751e1423551..6f6bd308784 100644 --- a/cmd/cosign/cli/fulcio/fulcioverifier/ctl/verify_test.go +++ b/cmd/cosign/cli/fulcio/fulcioverifier/ctl/verify_test.go @@ -33,7 +33,7 @@ import ( "github.com/sigstore/sigstore/pkg/cryptoutils" ) -func TestGetAlternatePublicKey(t *testing.T) { +func TestGetPublicKey(t *testing.T) { wd, err := os.Getwd() if err != nil { t.Fatalf("Failed to get cwd: %v", err) @@ -58,7 +58,7 @@ func TestGetAlternatePublicKey(t *testing.T) { if err != nil { t.Fatalf("Failed to read testfile %s : %v", tc.file, err) } - got, err := getAlternatePublicKey(bytes) + got, err := getPublicKey(bytes) switch { case err == nil && tc.wantErrSub != "": t.Errorf("Wanted Error for %s but got none", tc.file)