From 546ca56aeb420cc4c6219d8acc0989744eed9b1f Mon Sep 17 00:00:00 2001 From: Hector Fernandez Date: Mon, 18 Apr 2022 00:20:58 +0200 Subject: [PATCH] fix: add support for rsa keys (#1768) Signed-off-by: hectorj2f --- go.mod | 4 +- go.sum | 6 ++- pkg/apis/config/image_policies_test.go | 4 +- .../clusterimagepolicy_types.go | 48 +++++++++++-------- pkg/cosign/kubernetes/webhook/validation.go | 11 ++--- .../kubernetes/webhook/validator_test.go | 3 +- 6 files changed, 43 insertions(+), 33 deletions(-) diff --git a/go.mod b/go.mod index d622821d8cf..b0f9a6da0b0 100644 --- a/go.mod +++ b/go.mod @@ -113,7 +113,7 @@ require ( cloud.google.com/go/kms v1.4.0 // indirect contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d // indirect contrib.go.opencensus.io/exporter/prometheus v0.4.0 // indirect - github.com/Azure/azure-sdk-for-go v63.0.0+incompatible // indirect + github.com/Azure/azure-sdk-for-go v63.2.0+incompatible // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/autorest v0.11.25 // indirect github.com/Azure/go-autorest/autorest/adal v0.9.18 // indirect @@ -131,7 +131,7 @@ require ( github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/ReneKroon/ttlcache/v2 v2.11.0 // indirect github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect - github.com/aws/aws-sdk-go v1.43.30 // indirect + github.com/aws/aws-sdk-go v1.43.37 // indirect github.com/aws/aws-sdk-go-v2 v1.14.0 // indirect github.com/aws/aws-sdk-go-v2/config v1.14.0 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.9.0 // indirect diff --git a/go.sum b/go.sum index 538d3d7f87b..2d0f124866c 100644 --- a/go.sum +++ b/go.sum @@ -130,8 +130,9 @@ github.com/Azure/azure-sdk-for-go v59.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9mo github.com/Azure/azure-sdk-for-go v60.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v60.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v62.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v63.0.0+incompatible h1:whPsa+jCHQSo5wGMPNLw4bz8q9Co2+vnXHzXGctoTaQ= github.com/Azure/azure-sdk-for-go v63.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v63.2.0+incompatible h1:OIqkK/zTGqVUuzpEvY0B1YSYDRAFC/j+y0w2GovCggI= +github.com/Azure/azure-sdk-for-go v63.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-service-bus-go v0.9.1/go.mod h1:yzBx6/BUGfjfeqbRZny9AQIbIe3AcV9WZbAdpkoXOa0= github.com/Azure/azure-service-bus-go v0.11.5/go.mod h1:MI6ge2CuQWBVq+ly456MY7XqNLJip5LO1iSFodbNLbU= github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0= @@ -323,8 +324,9 @@ github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zK github.com/aws/aws-sdk-go v1.42.8/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/aws/aws-sdk-go v1.42.22/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/aws/aws-sdk-go v1.42.25/go.mod h1:gyRszuZ/icHmHAVE4gc/r+cfCmhA1AD+vqfWbgI+eHs= -github.com/aws/aws-sdk-go v1.43.30 h1:Q3lgrX/tz/MkEiPVVQnOQThBAK2QC2SCTCKTD1mwGFA= github.com/aws/aws-sdk-go v1.43.30/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.43.37 h1:kyZ7UjaPZaCik+asF33UFOOYSwr9liDRr/UM/vuw8yY= +github.com/aws/aws-sdk-go v1.43.37/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aws/aws-sdk-go-v2 v1.7.1/go.mod h1:L5LuPC1ZgDr2xQS7AmIec/Jlc7O/Y1u2KxJyNVab250= github.com/aws/aws-sdk-go-v2 v1.11.0/go.mod h1:SQfA+m2ltnu1cA0soUkj4dRSsmITiVQUJvBIZjzfPyQ= diff --git a/pkg/apis/config/image_policies_test.go b/pkg/apis/config/image_policies_test.go index 7c9c4015c44..ff7146b53b3 100644 --- a/pkg/apis/config/image_policies_test.go +++ b/pkg/apis/config/image_policies_test.go @@ -15,7 +15,7 @@ package config import ( - "crypto/ecdsa" + "crypto" "crypto/x509" "encoding/pem" "strings" @@ -143,7 +143,7 @@ func checkGetMatches(t *testing.T, c map[string][]webhookcip.Authority, err erro t.Error("Wanted a config and non-zero authorities, got no authorities") } -func checkPublicKey(t *testing.T, gotKey *ecdsa.PublicKey) { +func checkPublicKey(t *testing.T, gotKey crypto.PublicKey) { t.Helper() derBytes, err := x509.MarshalPKIXPublicKey(gotKey) diff --git a/pkg/cosign/kubernetes/webhook/clusterimagepolicy/clusterimagepolicy_types.go b/pkg/cosign/kubernetes/webhook/clusterimagepolicy/clusterimagepolicy_types.go index 41706d53fc1..4a06e9a2f67 100644 --- a/pkg/cosign/kubernetes/webhook/clusterimagepolicy/clusterimagepolicy_types.go +++ b/pkg/cosign/kubernetes/webhook/clusterimagepolicy/clusterimagepolicy_types.go @@ -15,7 +15,7 @@ package clusterimagepolicy import ( - "crypto/ecdsa" + "crypto" "crypto/x509" "encoding/json" "encoding/pem" @@ -55,7 +55,7 @@ type KeyRef struct { // PublicKeys are not marshalled because JSON unmarshalling // errors for *big.Int // +optional - PublicKeys []*ecdsa.PublicKey `json:"-"` + PublicKeys []crypto.PublicKey `json:"-"` } type KeylessRef struct { @@ -70,7 +70,7 @@ type KeylessRef struct { // UnmarshalJSON populates the PublicKeys using Data because // JSON unmashalling errors for *big.Int func (k *KeyRef) UnmarshalJSON(data []byte) error { - var publicKeys []*ecdsa.PublicKey + var publicKeys []crypto.PublicKey var err error ret := make(map[string]string) @@ -143,28 +143,36 @@ func convertKeylessRefV1Alpha1ToWebhook(in *v1alpha1.KeylessRef) *KeylessRef { } } -func ConvertKeyDataToPublicKeys(pubKey string) ([]*ecdsa.PublicKey, error) { - keys := []*ecdsa.PublicKey{} - pems := parsePems([]byte(pubKey)) +func parsePEMKey(b []byte) ([]*pem.Block, bool) { + pemKey, rest := pem.Decode(b) + valid := true + if pemKey == nil { + return nil, false + } + pemBlocks := []*pem.Block{pemKey} + + if len(rest) > 0 { + list, check := parsePEMKey(rest) + return append(pemBlocks, list...), check + } + return pemBlocks, valid +} + +func ConvertKeyDataToPublicKeys(pubKey string) ([]crypto.PublicKey, error) { + keys := []crypto.PublicKey{} + pems, validPEM := parsePEMKey([]byte(pubKey)) + if !validPEM { + // TODO: If it is not valid report the error instead of ignore the key + return keys, nil + } + for _, p := range pems { key, err := x509.ParsePKIXPublicKey(p.Bytes) if err != nil { return nil, err } - keys = append(keys, key.(*ecdsa.PublicKey)) + keys = append(keys, key.(crypto.PublicKey)) } - return keys, nil -} -func parsePems(b []byte) []*pem.Block { - p, rest := pem.Decode(b) - if p == nil { - return nil - } - pems := []*pem.Block{p} - - if rest != nil { - return append(pems, parsePems(rest)...) - } - return pems + return keys, nil } diff --git a/pkg/cosign/kubernetes/webhook/validation.go b/pkg/cosign/kubernetes/webhook/validation.go index 6a54ade1faa..f32bbc6068c 100644 --- a/pkg/cosign/kubernetes/webhook/validation.go +++ b/pkg/cosign/kubernetes/webhook/validation.go @@ -18,7 +18,6 @@ package webhook import ( "context" "crypto" - "crypto/ecdsa" "crypto/x509" "encoding/pem" "errors" @@ -37,7 +36,7 @@ import ( "github.com/sigstore/sigstore/pkg/signature" ) -func valid(ctx context.Context, ref name.Reference, keys []*ecdsa.PublicKey, opts ...ociremote.Option) ([]oci.Signature, error) { +func valid(ctx context.Context, ref name.Reference, keys []crypto.PublicKey, opts ...ociremote.Option) ([]oci.Signature, error) { if len(keys) == 0 { // If there are no keys, then verify against the fulcio root. sps, err := validSignaturesWithFulcio(ctx, ref, fulcioroots.Get(), nil /* rekor */, nil /* no identities */, opts...) @@ -52,7 +51,7 @@ func valid(ctx context.Context, ref name.Reference, keys []*ecdsa.PublicKey, opt // We return nil if ANY key matches var lastErr error for _, k := range keys { - verifier, err := signature.LoadECDSAVerifier(k, crypto.SHA256) + verifier, err := signature.LoadVerifier(k, crypto.SHA256) if err != nil { logging.FromContext(ctx).Errorf("error creating verifier: %v", err) lastErr = err @@ -98,8 +97,8 @@ func validSignaturesWithFulcio(ctx context.Context, ref name.Reference, fulcioRo return sigs, err } -func getKeys(ctx context.Context, cfg map[string][]byte) ([]*ecdsa.PublicKey, *apis.FieldError) { - keys := []*ecdsa.PublicKey{} +func getKeys(ctx context.Context, cfg map[string][]byte) ([]crypto.PublicKey, *apis.FieldError) { + keys := []crypto.PublicKey{} errs := []error{} logging.FromContext(ctx).Debugf("Got public key: %v", cfg["cosign.pub"]) @@ -111,7 +110,7 @@ func getKeys(ctx context.Context, cfg map[string][]byte) ([]*ecdsa.PublicKey, *a if err != nil { errs = append(errs, err) } else { - keys = append(keys, key.(*ecdsa.PublicKey)) + keys = append(keys, key.(crypto.PublicKey)) } } if keys == nil { diff --git a/pkg/cosign/kubernetes/webhook/validator_test.go b/pkg/cosign/kubernetes/webhook/validator_test.go index f66772f4766..6b1ca61fffc 100644 --- a/pkg/cosign/kubernetes/webhook/validator_test.go +++ b/pkg/cosign/kubernetes/webhook/validator_test.go @@ -18,6 +18,7 @@ package webhook import ( "bytes" "context" + "crypto" "crypto/ecdsa" "crypto/elliptic" "crypto/x509" @@ -240,7 +241,7 @@ UoJou2P8sbDxpLiE/v3yLw1/jyOrCPWYHWFXnyyeGlkgSVefG54tNoK7Uw== { Key: &webhookcip.KeyRef{ Data: authorityKeyCosignPubString, - PublicKeys: []*ecdsa.PublicKey{authorityKeyCosignPub}, + PublicKeys: []crypto.PublicKey{authorityKeyCosignPub}, }, }, },