sigstore / policy-controller

Sigstore Policy Controller - an admission controller that can be used to enforce policy on a Kubernetes cluster based on verifiable supply-chain metadata from cosign
Other
123 stars 54 forks source link

Support keyless Signature verification using only Root certificate #710

Open Mukuls77 opened 1 year ago

Mukuls77 commented 1 year ago

Support keyless Signature verification using only Root certificate

Use case Description:

  1. A company has a private CA which is being used to sign the artifacts.
  2. Private CA generates Signature, Certificate and Cert Chain associated to the Artifact.
  3. certificate linkage is Signature <- Leaf Cert <- Intermediate cert <- Root Cert.
  4. Signer uses the cosign attach command to attach the Signature, Cert and Cert chain with artifact in registry
  5. Root Cert is shared to the verifier via out of band mechanism.
  6. Verifier uses the provided Root cert only to verify the Signature using the cosign verify command.

Issue Description currently cosign support verification of the signature using just root certificate using following mechanism.

We have an artifact which has associated signature, cert and cert chain in the registry.

showing the manifest of the signature for refrence.

Artifact : ttl.sh/cosign-ci/68ab7a70@sha256:ffb13da98453e0f04d33a6eee5bb8e46ee50d08ebe17735fc0779d0349e889e9 Fetching signature: ./cosign-linux-amd64 triangulate ttl.sh/cosign-ci/68ab7a70@sha256:ffb13da98453e0f04d33a6eee5bb8e46ee50d08ebe17735fc0779d0349e889e9 ttl.sh/cosign-ci/68ab7a70:sha256-ffb13da98453e0f04d33a6eee5bb8e46ee50d08ebe17735fc0779d0349e889e9.sig

Signature manifest

crane manifest ttl.sh/cosign-ci/68ab7a70:sqa256-ffb13da98453e0f04d33a6eee5bb8e46ee50d08ebe17735fc0779d0349e889e9.sig |j { "schemaVersion": 2, "mediaType": "application/vnd.oci.image.manifest.v1+json", "config": { "mediaType": "application/vnd.oci.image.config.v1+json", "size": 357, "digest": "sha256:da8a1a9eb14cf44984c1daba0400ae5047ed3cae705266594597116d8738fc91" }, "layers": [ { "mediaType": "application/vnd.dev.cosign.simplesigning.v1+json", "size": 241, "digest": "sha256:3c2165afcc2d11083dcc469440ca74b8bffa0fdd6c8818ed06933f3c839533c1", "annotations": { "dev.cosignproject.cosign/signature": "MEYCIQDiD1Ba6QvsNu6R1uMi3f/Kw7UqcIWejVyJxFv1mTDFeQIhAIzeMcZYPFd9J5cuEdiGqfGb0CY6mH0IBRyKvBpwKBuQ" } }, { "mediaType": "application/vnd.dev.cosign.simplesigning.v1+json", "size": 242, "digest": "sha256:61b4e7ee03e7df79b6c8182e8440b4b794300aabb9f25b29d818e9aa595fa2ff", "annotations": { "dev.cosignproject.cosign/signature": "DLDjxmPo5pJOaoX3+EPzMBGMQ85iaKadAdCIPVh80fidXy8cf194JT0/J3dbS1isxmFEPNolpdsU\nZtJ1Nsq1zM5biyM6iwyEZre07nAkvxrhrr+33BGI4p8Iq8snfyF/Dn9kkntxpAgXfQbtg2M0GMcv\n8hO7Vq7rlX2ZJTqfPgyfxIoobIml1wfA5MksiYbzxryCKG/p1Da9rytJPA36QbLsZEK/pjVH993m\ny3pylEDqkqi2kbNQFMZr9Pc3Blx1UiRP+8qDlmI+D1g+Qf0xo8VUTGgcsWZQBuIBXa35RakbA5Ib\nXurzHWU0nnk0IFdicUlaORIrKr/7SeIjC6mcew==\n", "dev.sigstore.cosign/certificate": "-----BEGIN CERTIFICATE-----\nMIIEWjCCA0KgAwIBAgIUalwY9QSFIWt2+DP9R5bwTZ71SQUwDQYJKoZIhvcNAQEL\nBQAwfTELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAlVQMQ4wDAYDVQQHDAVub2lkYTEO\nMAwGA1UECgwFbm9raWExDDAKBgNVBAsMA0NOUzEMMAoGA1UEAwwDTkNEMSUwIwYJ\nKoZIhvcNAQkBFhZtdWt1bC5zaGFybWFAbm9raWEuY29tMB4XDTIyMTExNzA2NDIw\nM1oXDTI1MDIxOTA2NDIwM1owfTELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAlVQMQ4w\nDAYDVQQHDAVub2lkYTEOMAwGA1UECgwFbm9raWExDDAKBgNVBAsMA0NOUzEMMAoG\nA1UEAwwDTkNEMSUwIwYJKoZIhvcNAQkBFhZtdWt1bC5zaGFybWFAbm9raWEuY29t\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq8LSBp7llnTCPXplnS2W\nBLzW/92hVawMuCpZeWHmIW6XeKkBnrQhPR3EQ1zgUJxrltUsxP45LwcZcUedUg06\ne/KHrqIyoWIv1CHFTND4N0z8qBrSAGaQwWDQw82Av26eTi5NiGe3ToRpLG1Ic4ib\n63l/SFLtdChdwfgicM/JmCj5ekFw9Lp0nC0X84TWThPVAvFkEF86WeAGNg0Zdtzs\ni/zcTypAOTDhdqJwNtr87ajo5iKRIh/wjxzirjjW3zSzzv6kwcRMv4ndYb1N0auW\nj9hCDx5ADKSZwM6khy9Ve+BvfvEBohaCzbtYtyxrWXMMAdPlsjYDc2u8Pwaw+pAL\nVQIDAQABo4HRMIHOMIGgBgNVHSMEgZgwgZWhfaR7MHkxCzAJBgNVBAYTAklOMQsw\nCQYDVQQIDAJVUDEOMAwGA1UEBwwFbm9pZGExDjAMBgNVBAoMBW5va2lhMQwwCgYD\nVQQLDANDTlMxDDAKBgNVBAMMA05DRDEhMB8GCSqGSIb3DQEJARYSbXVrdWwuc2hh\ncm1hQG5va2lhghRl+/SDGAklhZqyvmACldrfggAA6DAJBgNVHRMEAjAAMAsGA1Ud\nDwQEAwIE8DARBgNVHREECjAIggZsZWFmQ0EwDQYJKoZIhvcNAQELBQADggEBAFui\nwuM3BqbOKjr/UrvXBKppKWPFBcB/oIo2NfaSrL5HdDyBLVlNFL7Z/p+9VWE3Tb8k\nZaEEKghazJQnWIsh0UfPLyZ62fI+00ulVwBC3N5kS0avnmvXGXhRuSLKUWr2cFi+\nVwxx8/rjgKZ0WdnvZnVtHQB20KCIr6ksVJit0izIj2/hBuZ8DUI2k4YfR5JAM/BZ\ntTb8jgEvfX+9Q+0HZ/ZTOPWZszvtRq7brsBJfrkulA7WEfXHYAA6G4A7hsyxsqbz\nQetrZZklKSz5igxwxI9cbxaf9x7mAD0U4WY2EHRLZokE+qpKxCb3veO9X2RFzbOu\nB3ZlZ7xhkqYB2vHjk2c=\n-----END CERTIFICATE-----\n", "dev.sigstore.cosign/chain": "-----BEGIN CERTIFICATE-----\nMIID0DCCArigAwIBAgIUZfv0gxgJJYWasr5gApXa34IAAOgwDQYJKoZIhvcNAQEL\nBQAweTELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAlVQMQ4wDAYDVQQHDAVub2lkYTEO\nMAwGA1UECgwFbm9raWExDDAKBgNVBAsMA0NOUzEMMAoGA1UEAwwDTkNEMSEwHwYJ\nKoZIhvcNAQkBFhJtdWt1bC5zaGFybWFAbm9raWEwHhcNMjIxMTE3MDYzODUxWhcN\nMjUwMjE5MDYzODUxWjB9MQswCQYDVQQGEwJJTjELMAkGA1UECAwCVVAxDjAMBgNV\nBAcMBW5vaWRhMQ4wDAYDVQQKDAVub2tpYTEMMAoGA1UECwwDQ05TMQwwCgYDVQQD\nDANOQ0QxJTAjBgkqhkiG9w0BCQEWFm11a3VsLnNoYXJtYUBub2tpYS5jb20wggEi\nMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpEjqBA0y2rb6GAkAAHC/dn/3Z\nEfvTMwhyk1pVnT1HCayTMI6d0+aXvvSFRAKm7ciJXEeSrsKERgGGyUEMF6/rvsom\nLCjDH8sgz74wJn4LOOORJV9y2dilUlUTu9HQ7I1fIV7YCrpvjxEzm7ct0Pwbfw4C\nUmYB/1eIPHZhJJFkAg4AJws/Be/2Wj01qT2QYdTFYec1q9JcqspLxmL8PWe88CBp\ndwlE62yWLiW3zscPqKpELC2wc3LM5K/+rki8NCFtAX1lx5U3WOvI9PqHj88mBet3\nbRezYbSQaqfIqJSZGUlgRWr6sqp3iRl8CqFF/nGl3MVbJvyDnPYuE+fiNorPAgMB\nAAGjTDBKMB8GA1UdIwQYMBaAFLmBxLrvwbbAiLHxEaNai3sS7d15MAwGA1UdEwQF\nMAMBAf8wGQYDVR0RBBIwEIIOaW50ZXJtZWRpYXRlQ0EwDQYJKoZIhvcNAQELBQAD\nggEBAGwnXydEWXyF4yN+9sFc8nB9lyTtRG+7mqd6TwAXc7/K0igojnLtDRGTJZyt\ne1PV9az/FPRjYBqajQgHlyqQ0A9h0emueHg+m255w6mOd6i/uVGTxfEEDBnVDq8m\nff1w7LJUOjRafQvsXHL5mleOdm9SSVOESv8F6zWlE/2utqoOIdoTg9g0goxJYT/e\nn8Gq0cpH0hU/FUr78v8GTBOwaT2i5Wn7c6u2nh3gGUA/A/3G86/oAPIzjSKdficr\nQTytfdvwRELbSp70qNi8c4zHqwat65mCH2tiUdJE3guXSHV0/JYsZkxBT/R4zhGz\n2itq2p3qLmcxj+YguGUCLLL0K1c=\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIID0zCCArugAwIBAgIURrUdHZJMzykRUM9hDeLrLtyVxU8wDQYJKoZIhvcNAQEL\nBQAweTELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAlVQMQ4wDAYDVQQHDAVub2lkYTEO\nMAwGA1UECgwFbm9raWExDDAKBgNVBAsMA0NOUzEMMAoGA1UEAwwDTkNEMSEwHwYJ\nKoZIhvcNAQkBFhJtdWt1bC5zaGFybWFAbm9raWEwHhcNMjIxMTE3MDU1NDA4WhcN\nMjcxMTE2MDU1NDA4WjB5MQswCQYDVQQGEwJJTjELMAkGA1UECAwCVVAxDjAMBgNV\nBAcMBW5vaWRhMQ4wDAYDVQQKDAVub2tpYTEMMAoGA1UECwwDQ05TMQwwCgYDVQQD\nDANOQ0QxITAfBgkqhkiG9w0BCQEWEm11a3VsLnNoYXJtYUBub2tpYTCCASIwDQYJ\nKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwDtQ+CxpZmF4ruWWFMDHxJH564ZRYa\nMEtJOahJZ0lFTfNEqutRA0+NLZPPoc3jEX3b2k89VlDRir7o853NHLm/AtDsvekf\nof+qhw4BtrMstMQoom24fLld2XbcgAo8DwAYNQMUFKfNjZvJONEQgrcasEueLJn5\nwPDgLWr4sgx5gnsEONME6yumzgAPvff0lfJ8/A5k8VmTmJz8uLuKNxYRHb3o5cKf\nyFVaGAf7wCxEn8Jg5SRThyeG2uk0IFsX5L9BhJgfqeveNQh3WiynHYLqZJ3FACRn\ndc3gUio94Ec1UjZA1BKszNx89zUAf6KzrLkvx95IvUauq3habGKEz3cCAwEAAaNT\nMFEwHQYDVR0OBBYEFLmBxLrvwbbAiLHxEaNai3sS7d15MB8GA1UdIwQYMBaAFLmB\nxLrvwbbAiLHxEaNai3sS7d15MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL\nBQADggEBAMAoOL59+1x3GpU8PyIgjY3iyviaLOtdlA8wbCT21nP0fjGS2RNhsq5I\nYyPRf6w3WLTmgkXI7P3LpM9fYanBzSFrPNB6x0pNmaokgAEKxqKqqfUfgSYTtg95\n+5bdd9/ZQw210KGiD6AZf87Xp6x3U9n+uvSlg5CaIU2O2iOypj7az5EBSVyoBvIE\nuZHz+sHoShFU4iPZ6iuzS+r7P23b9Bl5gMR60ujSHUew0NLsZpBYdYkAERsScwrc\nX7Gh2duwSKgjSK0uh4G3sbKKqmZLj4aJGvyZI4iNIcePCKAJwJWlCkZrWhai33+A\nFuOC9rk2pAYN49IXN7EpNhgIvCp4O0A=\n-----END CERTIFICATE-----\n" } } ] }

Verify using cosign verify command

  1. set Environment Variable SIGSTORE_ROOT_FILE to point to trusted Root certificate. export SIGSTORE_ROOT_FILE=
  2. use cosign verify command as shown below.

echo $SIGSTORE_ROOT_FILE /home/mukul/policy-controller/mypolicy/rootCA.crt /home/mukul/policy-controller/mypolicy>./cosign-linux-amd64 verify ttl.sh/cosign-ci/68ab7a70@sha256:ffb13da98453e0f04d33a6eee5bb8e46ee50d08ebe17735fc0779d0349e889e9 --insecure-ignore-sct --insecure-ignore-tlog --certificate-identity-regexp '.' --certificate-oidc-issuer-regexp '.' Warning Skipping tlog verification is an insecure practice that lacks of transparency and auditability verification for the signature.

Verification for ttl.sh/cosign-ci/68ab7a70@sha256:ffb13da98453e0f04d33a6eee5bb8e46ee50d08ebe17735fc0779d0349e889e9 -- The following checks were performed on each of these signatures:

[{"critical":{"identity":{"docker-reference":"ttl.sh/cosign-ci/68ab7a70"},"image":{"docker-manifest-digest":"sha256:ffb13da98453e0f04d33a6eee5bb8e46ee50d08ebe17735fc0779d0349e889e9"},"type":"cosign container image signature"},"optional":{"Subject":""}}]

Verification using policy tester To verify the policy for this scenario i used the policy Tester. Created following policies Policy File: cip-my-keyless.yaml apiVersion: policy.sigstore.dev/v1alpha1 kind: ClusterImagePolicy metadata: name: demo spec: images:

Trust Root: file my-sigstore-keys.yaml

apiVersion: policy.sigstore.dev/v1alpha1 kind: TrustRoot metadata: name: my-sigstore-keys spec: sigstoreKeys: certificateAuthorities:

Testing using policy tester When i test this policy and trust root it fails

/home/mukul/policy-controller/mypolicy>./policy-tester -image ttl.sh/cosign-ci/68ab7a70@sha256:ffb13da98453e0f04d33a6eee5bb8e46ee50d08ebe17735fc0779d0349e889e9 -policy cip-my-keyless.yaml -trustroot my-sigstore-keys.yaml 2023-04-07T12:01:05.933+0530 DEBUG webhook/validator.go:497 Checking Authority: authority-0 2023-04-07T12:01:10.896+0530 ERROR webhook/validator.go:763 failed validSignatures for authority authority-0 with fulcio for ttl.sh/cosign-ci/68ab7a70@sha256:ffb13da98453e0f04d33a6eee5bb8e46ee50d08ebe17735fc0779d0349e889e9: no matching signatures: no certificate found on signature cert verification failed: x509: certificate signed by unknown authority. Check your TUF root (see cosign initialize) or set a custom root with env var SIGSTORE_ROOT_FILE github.com/sigstore/policy-controller/pkg/webhook.ValidatePolicySignaturesForAuthority github.com/sigstore/policy-controller/pkg/webhook/validator.go:763 github.com/sigstore/policy-controller/pkg/webhook.ValidatePolicy.func1 github.com/sigstore/policy-controller/pkg/webhook/validator.go:529 {"errors":["signature keyless validation failed for authority authority-0 for ttl.sh/cosign-ci/68ab7a70@sha256:ffb13da98453e0f04d33a6eee5bb8e46ee50d08ebe17735fc0779d0349e889e9: no matching signatures:\nno certificate found on signature\n cert verification failed: x509: certificate signed by unknown authority. Check your TUF root (see cosign initialize) or set a custom root with env var SIGSTORE_ROOT_FILE: "]}

It works only when i use the complete cert chain i.e. (Intermediate cert + Root Cert) in the argument

Impact and benefit of this issue currently as i notice policy controller only support passing complete cert chain in the argument to validate the signature. This will have impact on usability in the case where an organization generates separate Intermediate Certs for its departments, so in such case the policy logic will become complex

  1. we need to create separate trust root including specific pairs of +
  2. and use specific trust root in the policy logic as per the image being verified.

This can be made simple if we allow only Root cert to be used for verification as is allowed in cosign tool. In that case we will just need a single Trust Root and can use that trust root in all the policies.

Mukuls77 commented 1 year ago

I have tested the scenario on a cluster now sharing the working and not working logs TestResults.zip

hectorj2f commented 1 year ago

@Mukuls77 I am afraid this behaviour is intentional to ask for any intermediate and the root certificate.

Mukuls77 commented 1 year ago

Hi Hector the cosign base code support the flow in which we set the SIGSTORE_ROOT_FILE env variable to rootCert and than in verify command we dont pass any Intermediate cert so than cosign picks the cert chain and cert from the Registry and validate those using the Root cert provided in SIGSTORE_ROOT_FILE. so a similar behaviour should be supported when we are using policy controller also kindly ignore the failed logs traces i shared before today there was a mistake in my policy i am now sharing the correct failed log traces here now NotWorkingLogswithRootCertOnly.zip

hectorj2f commented 1 year ago

@Mukuls77 Alright! I'll have a look at the logs.

hectorj2f commented 1 year ago

@Mukuls77 I've tried using the certChain containing the SIGSTORE_ROOT_FILE (with only the root certificate), and it worked for me. Are you sure you set the right organization and commonName aligned with your certificate ? I saw the content of the certificate and they don't match the value entered in the trustRoot.

Please, make sure you're using the root certificate only.

Mukuls77 commented 1 year ago

Hi Hector thanks for the update. actually i used a new set of certs for generating these logs, and i validated that i am using correct root cert in my test. I am sharing the cert used for this test for your view. printing the values of the cert for quick view

/home/mukul/tarballTest>openssl x509 -text -in rootCA.crt Certificate: Data: Version: 3 (0x2) Serial Number: 54:c0:4b:1e:d7:24:24:10:bd:6d:65:ad:73:a1:01:f9:54:ba:17:2e Signature Algorithm: sha256WithRSAEncryption Issuer: C = IN, ST = DELHI, L = DELHI, O = NOKIA, OU = CNS, CN = NCD, emailAddress = mukul.sharma@nokia.com Validity Not Before: Apr 25 07:07:07 2023 GMT Not After : Apr 23 07:07:07 2028 GMT Subject: C = IN, ST = DELHI, L = DELHI, O = NOKIA, OU = CNS, CN = NCD, emailAddress = mukul.sharma@nokia.com

/home/mukul/tarballTest>openssl x509 -text -in intermediateCA.crt Certificate: Data: Version: 3 (0x2) Serial Number: 2e:7c:21:be:8c:21:ca:c6:e0:66:a9:5b:42:ac:f2:9e:21:8b:7a:e5 Signature Algorithm: sha256WithRSAEncryption Issuer: C = IN, ST = DELHI, L = DELHI, O = NOKIA, OU = CNS, CN = NCD, emailAddress = mukul.sharma@nokia.com Validity Not Before: Apr 25 09:32:37 2023 GMT Not After : Apr 23 09:32:37 2028 GMT Subject: C = IN, ST = DELHI, L = DELHI, O = NOKIA, OU = CNS, CN = NCD, emailAddress = mukul.sharma@nokia.com

/home/mukul/tarballTest>openssl x509 -text -in leafCA.crt Certificate: Data: Version: 3 (0x2) Serial Number: 06:35:d1:dc:1f:fe:0d:17:1d:38:b4:e7:ad:25:40:08:6b:48:bc:71 Signature Algorithm: sha256WithRSAEncryption Issuer: C = IN, ST = DELHI, L = DELHI, O = NOKIA, OU = CNS, CN = NCD, emailAddress = mukul.sharma@nokia.com Validity Not Before: Apr 25 09:34:06 2023 GMT Not After : Apr 23 09:34:06 2028 GMT Subject: C = IN, ST = DELHI, L = DELHI, O = NOKIA, OU = NCD, CN = NCD, emailAddress = mukul.sharma@nokia.com

cert used.zip

also when i use Intemediate cert + root cert in the cert chain than the policy controller works fine. it only fails when i am using only root cert.

logs attached for working case

workingLogs.zip

Mukuls77 commented 1 year ago

Hi Hector i tried the policy validation again with a different set of leaf, intermediate and root cert but the result is the same if it only use root cert in the Trustroot than validation fails but it works if i use Intermediate cert + root cert in the trust root. as you mentioned it worked for you can you pls share the certs you used for your case (leaf, intermediate, root) so that i can check what is the difference in my case.

Mukuls77 commented 1 year ago

@hectorj2f can you pls provide the certs (leaf , intermediate, root) and the leaf key so that i can check this case, as i tried it myself using my certs and cert chain but it is not working till i provide complete cert chain (intermediate + root) in the trust root. It only work for me when i have only leaf and root cert as the complete chain i.e. no intermediate cert is present, as i use an intermediate cert than just setting root cert in trust root does not work. But as i explained before the same scenario works with cosign when i just set SIGSTORE_ROOT_FILE to root cert.