diff --git a/verifiers/internal/gcb/keys/keys.go b/verifiers/internal/gcb/keys/keys.go index bd3b1210e..e7d8367e6 100644 --- a/verifiers/internal/gcb/keys/keys.go +++ b/verifiers/internal/gcb/keys/keys.go @@ -16,8 +16,9 @@ import ( var publicKeys embed.FS type PublicKey struct { - Value []byte - Region string + value []byte + pubKey *ecdsa.PublicKey + region string // TODO: key type and size } @@ -27,31 +28,35 @@ func PublicKeyNew(region string) (*PublicKey, error) { return nil, fmt.Errorf("%w: cannot read key materials", err) } - return &PublicKey{ - Value: content, - Region: region, - }, nil -} - -func (self *PublicKey) VerifySignature(digest [32]byte, sig []byte) error { - block, _ := pem.Decode(self.Value) + block, _ := pem.Decode(content) if block == nil { - return fmt.Errorf("%w: %s", serrors.ErrorInvalidPEM, self.Value) + return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidPEM, content) } key, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { - return fmt.Errorf("x509.ParsePKIXPublicKey: %w", err) + return nil, fmt.Errorf("x509.ParsePKIXPublicKey: %w", err) } pubKey, ok := key.(*ecdsa.PublicKey) if !ok { - return fmt.Errorf("%w: public key not of type ECDSA", err) + return nil, fmt.Errorf("%w: public key not of type ECDSA", err) } - if !ecdsa.VerifyASN1(pubKey, digest[:], sig) { + return &PublicKey{ + value: content, + pubKey: pubKey, + region: region, + }, nil +} + +func (self *PublicKey) VerifySignature(digest [32]byte, sig []byte) error { + if self.pubKey == nil { + return fmt.Errorf("%w: key is empty", serrors.ErrorInternal) + } + if !ecdsa.VerifyASN1(self.pubKey, digest[:], sig) { return fmt.Errorf("%w: cannot verify with public key '%v'", - serrors.ErrorInvalidSignature, string(self.Region)) + serrors.ErrorInvalidSignature, string(self.region)) } return nil diff --git a/verifiers/internal/gcb/provenance.go b/verifiers/internal/gcb/provenance.go index 9e1c2cd7a..0352281ac 100644 --- a/verifiers/internal/gcb/provenance.go +++ b/verifiers/internal/gcb/provenance.go @@ -65,16 +65,6 @@ func ProvenanceFromBytes(payload []byte) (*GCBProvenance, error) { }, nil } -func signatureAsRaw(s string) ([]byte, error) { - s = strings.ReplaceAll(s, "-", "+") - s = strings.ReplaceAll(s, "_", "/") - sig, err := base64.StdEncoding.DecodeString(s) - if err != nil { - return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, err.Error()) - } - return sig, nil -} - func payloadFromEnvelope(env *dsselib.Envelope) ([]byte, error) { payload, err := base64.StdEncoding.DecodeString(env.Payload) if err != nil { @@ -327,14 +317,14 @@ func (self *GCBProvenance) verifySignatures(prov *provenance) error { } // Decode the signature. - sig, err := signatureAsRaw(sig.Sig) + rsig, err := base64.RawURLEncoding.DecodeString(sig.Sig) if err != nil { errs = append(errs, err) continue } // Verify the signature. - err = pubKey.VerifySignature(payloadHash, sig) + err = pubKey.VerifySignature(payloadHash, rsig) if err != nil { errs = append(errs, err) continue