diff --git a/pkg/cosign/cosign.go b/pkg/cosign/cosign.go index 07e0ff5afd..ff020626dc 100644 --- a/pkg/cosign/cosign.go +++ b/pkg/cosign/cosign.go @@ -186,7 +186,7 @@ func buildCosignOptions(ctx context.Context, opts images.Options) (*cosign.Check } cosignOpts.IgnoreSCT = opts.IgnoreSCT - cosignOpts.CTLogPubKeys, err = cosign.GetCTLogPubs(ctx) + cosignOpts.CTLogPubKeys, err = getCTLogPubs(ctx, opts.CTLogsPubKey) if err != nil { return nil, fmt.Errorf("failed to load Rekor public keys: %w", err) } @@ -583,3 +583,15 @@ func getRekorPubs(ctx context.Context, rekorPubKey string) (*cosign.TrustedTrans } return &publicKeys, nil } + +func getCTLogPubs(ctx context.Context, ctlogPubKey string) (*cosign.TrustedTransparencyLogPubKeys, error) { + if ctlogPubKey == "" { + return cosign.GetCTLogPubs(ctx) + } + + publicKeys := cosign.NewTrustedTransparencyLogPubKeys() + if err := publicKeys.AddTransparencyLogPubKey([]byte(ctlogPubKey), tuf.Active); err != nil { + return nil, fmt.Errorf("AddRekorPubKey: %w", err) + } + return &publicKeys, nil +} diff --git a/pkg/cosign/cosign_test.go b/pkg/cosign/cosign_test.go index 00690a60c7..962ef3dfbf 100644 --- a/pkg/cosign/cosign_test.go +++ b/pkg/cosign/cosign_test.go @@ -63,7 +63,7 @@ kBbmLSGtks4L3qX6yYY0zufBnhC8Ur/iy55GhWP/9A/bY2LhC30M9+RYtw== -----END PUBLIC KEY----- ` -const wrongRekorPubKey = `-----BEGIN PUBLIC KEY----- +const wrongPubKey = `-----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoiR2ouEAp4JS/JIgkCVYCxpp/dMe 4Mkc/92O8rbWs6xIAcIEju7+Z2yecpQH6RbztEVCZbBZhEVfMdRgWKOrrQ== -----END PUBLIC KEY-----` @@ -128,7 +128,7 @@ func TestRekorPubkeys(t *testing.T) { Issuer: "https://github.com/login/oauth", Subject: "jim@nirmata.com", RekorURL: "--INVALID--", // To avoid using the default rekor url as thats where signature is uploaded - RekorPubKey: wrongRekorPubKey, + RekorPubKey: wrongPubKey, IgnoreSCT: true, } @@ -145,6 +145,28 @@ func TestRekorPubkeys(t *testing.T) { assert.NilError(t, err) } +func TestCTLogsPubkeys(t *testing.T) { + opts := images.Options{ + ImageRef: "ghcr.io/vishal-chdhry/cosign-test:v1", + Issuer: "https://accounts.google.com", + Subject: "vishal.choudhary@nirmata.com", + RekorPubKey: globalRekorPubKey, + CTLogsPubKey: wrongPubKey, + } + + rc, err := registryclient.New() + assert.NilError(t, err) + opts.Client = rc + + verifier := &cosignVerifier{} + _, err = verifier.VerifySignature(context.TODO(), opts) + assert.ErrorContains(t, err, "no matching signatures: ctfe public key not found for payload.") + + opts.CTLogsPubKey = "" + _, err = verifier.VerifySignature(context.TODO(), opts) + assert.NilError(t, err) +} + func TestCosignMatchCertificateData(t *testing.T) { pem1 := "-----BEGIN CERTIFICATE-----\nMIIDtzCCAzygAwIBAgIUX9MdOHZMlRONmc0Iu3DtiLXLVLYwCgYIKoZIzj0EAwMw\nNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRl\ncm1lZGlhdGUwHhcNMjIxMDA3MTkyNDI0WhcNMjIxMDA3MTkzNDI0WjAAMFkwEwYH\nKoZIzj0CAQYIKoZIzj0DAQcDQgAE0+a5/FhwY4fREWP++3V4rciGiqWGRgHaiP1z\nSlWihKkU71sBVeTzjdrcN8wXzBAefqh5URBfCeE8pJRfQsVKxKOCAlswggJXMA4G\nA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUJy79\nhpkwHtXtLWOvFu/icY56bwgwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4Y\nZD8wbgYDVR0RAQH/BGQwYoZgaHR0cHM6Ly9naXRodWIuY29tL0ppbUJ1Z3dhZGlh\nL2RlbW8tamF2YS10b21jYXQvLmdpdGh1Yi93b3JrZmxvd3MvcHVibGlzaC55YW1s\nQHJlZnMvdGFncy92MC4wLjIyMDkGCisGAQQBg78wAQEEK2h0dHBzOi8vdG9rZW4u\nYWN0aW9ucy5naXRodWJ1c2VyY29udGVudC5jb20wEgYKKwYBBAGDvzABAgQEcHVz\naDA2BgorBgEEAYO/MAEDBChjNzY0NTI4NGZhN2FlYmU1NTQ2MThlZWU4NzliNGQ2\nOTQ3Zjg1NjRlMB8GCisGAQQBg78wAQQEEWJ1aWxkLXNpZ24tYXR0ZXN0MCoGCisG\nAQQBg78wAQUEHEppbUJ1Z3dhZGlhL2RlbW8tamF2YS10b21jYXQwHwYKKwYBBAGD\nvzABBgQRcmVmcy90YWdzL3YwLjAuMjIwgYoGCisGAQQB1nkCBAIEfAR6AHgAdgAI\nYJLwKFL/aEXR0WsnhJxFZxisFj3DONJt5rwiBjZvcgAAAYOz5+pbAAAEAwBHMEUC\nIBb8fwsLBOu+qJkL6UhT4pwGvRVAN2n74BF1BL703rqPAiEAznbfgYJbqA+JIUiQ\nwwLiFOD8pqidSl+HhW8Lhdg3o+wwCgYIKoZIzj0EAwMDaQAwZgIxAJIBIkZBhM+K\nkBIFNeuWBsyVaAcFRallz3C8jvPQCPbec0ZpIsw624dUs8zD3c96AQIxALf875rt\n+oZgwE6hsDazJzoTcBZ1mYVF6bAlwVdtMiC98aApG6T+qaBirxSgu7IGQw==\n-----END CERTIFICATE-----\n" cert1, err := loadCert([]byte(pem1)) diff --git a/pkg/engine/internal/imageverifier.go b/pkg/engine/internal/imageverifier.go index 6a2b0a12b6..da5b11db17 100644 --- a/pkg/engine/internal/imageverifier.go +++ b/pkg/engine/internal/imageverifier.go @@ -554,15 +554,16 @@ func (iv *ImageVerifier) buildCosignVerifier( opts.IgnoreTlog = attestor.Keys.Rekor.IgnoreTlog } else { opts.RekorURL = "https://rekor.sigstore.dev" - opts.IgnoreSCT = false opts.IgnoreTlog = false } if attestor.Keys.CTLog != nil { opts.IgnoreSCT = attestor.Keys.CTLog.IgnoreSCT + opts.CTLogsPubKey = attestor.Keys.CTLog.CTLogPubKey } else { opts.IgnoreSCT = false } + opts.SignatureAlgorithm = attestor.Keys.SignatureAlgorithm } else if attestor.Certificates != nil { path = path + ".certificates" @@ -579,12 +580,12 @@ func (iv *ImageVerifier) buildCosignVerifier( opts.IgnoreTlog = attestor.Keyless.Rekor.IgnoreTlog } else { opts.RekorURL = "https://rekor.sigstore.dev" - opts.IgnoreSCT = false opts.IgnoreTlog = false } if attestor.Keyless.CTLog != nil { opts.IgnoreSCT = attestor.Keyless.CTLog.IgnoreSCT + opts.CTLogsPubKey = attestor.Keyless.CTLog.CTLogPubKey } else { opts.IgnoreSCT = false } diff --git a/pkg/images/verifier.go b/pkg/images/verifier.go index ca0a7ed200..1b7fb0755a 100644 --- a/pkg/images/verifier.go +++ b/pkg/images/verifier.go @@ -33,10 +33,11 @@ type Options struct { AdditionalExtensions map[string]string Annotations map[string]string Repository string + IgnoreTlog bool RekorURL string RekorPubKey string IgnoreSCT bool - IgnoreTlog bool + CTLogsPubKey string SignatureAlgorithm string PredicateType string Type string diff --git a/test/cli/test/images/verify-signature/policies.yaml b/test/cli/test/images/verify-signature/policies.yaml index 80d33a1fdd..9957168d4a 100644 --- a/test/cli/test/images/verify-signature/policies.yaml +++ b/test/cli/test/images/verify-signature/policies.yaml @@ -68,4 +68,4 @@ spec: url: https://rekor.sigstore.dev ignoreTlog: true ctlog: - ignoreSCT: true \ No newline at end of file + ignoreSCT: true