diff --git a/pkg/cosign/verify.go b/pkg/cosign/verify.go index 7a4b2b1115c..141a07eea53 100644 --- a/pkg/cosign/verify.go +++ b/pkg/cosign/verify.go @@ -216,9 +216,17 @@ func verifyOCISignature(ctx context.Context, verifier signature.Verifier, sig pa return verifier.VerifySignature(bytes.NewReader(signature), bytes.NewReader(payload), options.WithContext(ctx)) } -// ValidateAndUnpackCert creates a Verifier from a certificate. Veries that the certificate -// chains up to a trusted root. Optionally verifies the subject and issuer of the certificate. +// ValidateAndUnpackCert creates a Verifier from a certificate. Verifies that the +// certificate chains up to a trusted root using intermediate certificate chain coming from CheckOpts. +// Optionally verifies the subject and issuer of the certificate. func ValidateAndUnpackCert(cert *x509.Certificate, co *CheckOpts) (signature.Verifier, error) { + return ValidateAndUnpackCertWithIntermediates(cert, co, co.IntermediateCerts) +} + +// ValidateAndUnpackCertWithIntermediates creates a Verifier from a certificate. Verifies that the +// certificate chains up to a trusted root using intermediate cert passed as separate argument. +// Optionally verifies the subject and issuer of the certificate. +func ValidateAndUnpackCertWithIntermediates(cert *x509.Certificate, co *CheckOpts, intermediateCerts *x509.CertPool) (signature.Verifier, error) { verifier, err := signature.LoadVerifier(cert.PublicKey, crypto.SHA256) if err != nil { return nil, fmt.Errorf("invalid certificate found on signature: %w", err) @@ -239,7 +247,8 @@ func ValidateAndUnpackCert(cert *x509.Certificate, co *CheckOpts) (signature.Ver } // Now verify the cert, then the signature. - chains, err := TrustedCert(cert, co.RootCerts, co.IntermediateCerts) + chains, err := TrustedCert(cert, co.RootCerts, intermediateCerts) + if err != nil { return nil, err } @@ -721,19 +730,21 @@ func verifyInternal(ctx context.Context, sig oci.Signature, h v1.Hash, return false, err } // If there is no chain annotation present, we preserve the pools set in the CheckOpts. - if len(chain) > 0 { - if len(chain) == 1 { - co.IntermediateCerts = nil - } else if co.IntermediateCerts == nil { + var pool *x509.CertPool + if len(chain) > 1 { + if co.IntermediateCerts == nil { // If the intermediate certs have not been loaded in by TUF - pool := x509.NewCertPool() + pool = x509.NewCertPool() for _, cert := range chain[:len(chain)-1] { pool.AddCert(cert) } - co.IntermediateCerts = pool } } - verifier, err = ValidateAndUnpackCert(cert, co) + // In case pool is not set than set it from co.IntermediateCerts + if pool == nil { + pool = co.IntermediateCerts + } + verifier, err = ValidateAndUnpackCertWithIntermediates(cert, co, pool) if err != nil { return false, err } diff --git a/pkg/cosign/verify_test.go b/pkg/cosign/verify_test.go index d887a09c206..578d349056c 100644 --- a/pkg/cosign/verify_test.go +++ b/pkg/cosign/verify_test.go @@ -1228,6 +1228,36 @@ func TestValidateAndUnpackCertWithIdentities(t *testing.T) { } } } + +func TestValidateAndUnpackCertWithIntermediatesSuccess(t *testing.T) { + subject := "email@email" + oidcIssuer := "https://accounts.google.com" + + rootCert, rootKey, _ := test.GenerateRootCa() + subCert, subKey, _ := test.GenerateSubordinateCa(rootCert, rootKey) + leafCert, _, _ := test.GenerateLeafCert(subject, oidcIssuer, subCert, subKey) + + rootPool := x509.NewCertPool() + rootPool.AddCert(rootCert) + subPool := x509.NewCertPool() + rootPool.AddCert(subCert) + + co := &CheckOpts{ + RootCerts: rootPool, + IgnoreSCT: true, + Identities: []Identity{{Subject: subject, Issuer: oidcIssuer}}, + } + + _, err := ValidateAndUnpackCertWithIntermediates(leafCert, co, subPool) + if err != nil { + t.Errorf("ValidateAndUnpackCertWithIntermediates expected no error, got err = %v", err) + } + err = CheckCertificatePolicy(leafCert, co) + if err != nil { + t.Errorf("CheckCertificatePolicy expected no error, got err = %v", err) + } +} + func TestCompareSigs(t *testing.T) { // TODO(nsmith5): Add test cases for invalid signature, missing signature etc tests := []struct { diff --git a/test/e2e_test_attach.sh b/test/e2e_test_attach.sh index 708986feff2..21937b7255b 100755 --- a/test/e2e_test_attach.sh +++ b/test/e2e_test_attach.sh @@ -14,6 +14,12 @@ # See the License for the specific language governing permissions and # limitations under the License. +# This test case test two scenarios +# scenario 1: Attach a single signature with certificate and certificate chain to an artifact +# and verify it using root certificate +# scenario 2: Attaches second signature with diffrent certificate and certificate chain to same +# artifact and verify it using both root certificates separately + set -ex go build -o cosign ./cmd/cosign @@ -25,6 +31,10 @@ cp ./test/testdata/test_attach_private_key $tmp/private_key cp ./test/testdata/test_attach_leafcert.pem $tmp/leafcert.pem cp ./test/testdata/test_attach_certchain.pem $tmp/certchain.pem cp ./test/testdata/test_attach_rootcert.pem $tmp/rootcert.pem +cp ./test/testdata/test_attach_second_private_key $tmp/secondprivate_key +cp ./test/testdata/test_attach_second_leafcert.pem $tmp/secondleafcert.pem +cp ./test/testdata/test_attach_second_certchain.pem $tmp/secondcertchain.pem +cp ./test/testdata/test_attach_second_rootcert.pem $tmp/secondrootcert.pem pushd $tmp @@ -44,39 +54,48 @@ IMAGE_URI_DIGEST=$IMAGE_URI@$SRC_DIGEST ## Generate ./cosign generate $IMAGE_URI_DIGEST > payload.json -## Sign with Leafcert Private Key +## Scenario 1 Starts + +## Sign with First Leafcert Private Key openssl dgst -sha256 -sign ./private_key -out payload.sig payload.json cat payload.sig | base64 > payloadbase64.sig - SIGNATURE=$(cat payloadbase64.sig | base64) echo "Signature: $SIGNATURE" PAYLOAD=$(cat payload.json) echo "Payload: $PAYLOAD" - - ## Attach Signature, payload, cert and cert-chain ./cosign attach signature --signature ./payloadbase64.sig --payload ./payload.json --cert ./leafcert.pem --cert-chain ./certchain.pem $IMAGE_URI_DIGEST - ## confirm manifest conatins annotation for cert and cert chain crane manifest $(./cosign triangulate $IMAGE_URI_DIGEST) | grep -q "application/vnd.oci.image.config.v1+json" crane manifest $(./cosign triangulate $IMAGE_URI_DIGEST) | grep -q "dev.sigstore.cosign/certificate" crane manifest $(./cosign triangulate $IMAGE_URI_DIGEST) | grep -q "dev.sigstore.cosign/chain" -## Verify Signature, payload, cert and cert-chain using SIGSTORE_ROOT_FILE +## Verify Signature, payload, cert and cert-chain using Root certificate only +./cosign verify $IMAGE_URI_DIGEST --insecure-ignore-sct --insecure-ignore-tlog --certificate-identity-regexp '.*' --certificate-oidc-issuer-regexp '.*' --cert-chain=./rootcert.pem + +## Scenario 2 Starts + +## Sign with Leafcert Private Key +openssl dgst -sha256 -sign ./secondprivate_key -out secondpayload.sig payload.json +cat secondpayload.sig | base64 > secondpayloadbase64.sig + +SIGNATURE2=$(cat secondpayloadbase64.sig | base64) +echo "Second Signature: $SIGNATURE2" + +## Attach Second Signature, payload, cert and cert-chain +./cosign attach signature --signature ./secondpayloadbase64.sig --payload ./payload.json --cert ./secondleafcert.pem --cert-chain ./secondcertchain.pem $IMAGE_URI_DIGEST -export SIGSTORE_ROOT_FILE=./rootcert.pem -./cosign verify $IMAGE_URI_DIGEST --insecure-ignore-sct --insecure-ignore-tlog --certificate-identity-regexp '.*' --certificate-oidc-issuer-regexp '.*' +## Verify Signature, payload, cert and cert-chain using Root certificate only +./cosign verify $IMAGE_URI_DIGEST --insecure-ignore-sct --insecure-ignore-tlog --certificate-identity-regexp '.*' --certificate-oidc-issuer-regexp '.*' --cert-chain=./rootcert.pem +./cosign verify $IMAGE_URI_DIGEST --insecure-ignore-sct --insecure-ignore-tlog --certificate-identity-regexp '.*' --certificate-oidc-issuer-regexp '.*' --cert-chain=./secondrootcert.pem # clean up a bit -for image in $IMAGE_URI_DIGEST -do - (crane delete $(./cosign triangulate $IMAGE_URI_DIGEST)) || true -done +./cosign clean $IMAGE_URI_DIGEST --force=true crane delete $IMAGE_URI_DIGEST || true diff --git a/test/testdata/README.md b/test/testdata/README.md index 2c67e7d762c..248812e2aa0 100644 --- a/test/testdata/README.md +++ b/test/testdata/README.md @@ -106,3 +106,98 @@ $ cp certChain.crt test/testdata/test_attach_certchain.pem ```shell $ cp leafCA.crt test/testdata/test_attach_leafcert.pem ``` + +16. Generate a private key for Second Root certificate + +```shell +$ openssl genrsa -des3 -out secondrootCA.key 2048 +``` +17. Generate Second Root certificate + +```shell +$ openssl req -x509 -new -nodes -key secondrootCA.key -sha256 -days 1825 -out secondrootCA.crt +``` + in Certificate generation set following values + C = IN, ST = DEL, L = DEL, O = exampleclient.com, OU = sigstore, CN = sigstore, emailAddress = foo@exampleclient.com + +18. Generate Private key for second Intermediate certificate + +```shell +$ openssl genrsa -out secondintermediateCA.key 2048 +``` +19. Generate CSR for second Intermediate certificate + +```shell +$ openssl req -new -key secondintermediateCA.key -out secondintermediateCA.csr +``` + in Certificate generation set following values + C = IN, ST = DEL, L = DEL, O = exampleclient.com, OU = sigstore-sub, CN = sigstore-sub, emailAddress = foo@exampleclient.com + +20. Create intermediate certificate config file by name "intermediateConfigFile" having content + subjectKeyIdentifier = hash + authorityKeyIdentifier = keyid:always,issuer + basicConstraints = critical, CA:true, pathlen:0 + keyUsage = critical, digitalSignature, cRLSign, keyCertSign + +21. Create intermediate certificate + +```shell +$ openssl x509 -req -in secondintermediateCA.csr -CA secondrootCA.crt -CAkey secondrootCA.key -CAcreateserial -CAserial secondintermediateca.srl -out secondintermediateCA.crt -days 1825 -sha256 -extfile intermediateConfigFile +``` + +22. Create Private key for second leaf certificate + +```shell +$ openssl genrsa -out secondleafCA.key 2048 +``` + +23. Create CSR for second Leaf certificate + +```shell +$ openssl req -new -key secondleafCA.key -out secondleafCA.csr +``` + in certificate generation set following values + C = IN, ST = DEL, L = DEL, O = exampleclient.com, OU = sigstore-leaf, CN = sigstore-leaf, emailAddress = foo@exampleclient.com + +24. Create Leaf certificate config file by name "leafConfigFile" having content + authorityKeyIdentifier=keyid,issuer + basicConstraints=CA:FALSE + keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment + extendedKeyUsage=codeSigning + subjectAltName=email:copy + +25. Create Leaf certificate + +```shell +$ openssl x509 -req -in secondleafCA.csr -CA secondintermediateCA.crt -CAkey secondintermediateCA.key -CAcreateserial -CAserial secondleafca.srl -out secondleafCA.crt -days 1825 -sha256 -extfile leafConfigFile +``` + +26. Generate Certificate chain by concatinating second Intermediate certificate and second Root certificate + +```shell +$ cat secondintermediateCA.crt secondrootCA.crt > secondcertChain.crt +``` + +27. copy private key of second Leaf certificate to test/testdata/test_attach_second_private_key + +```shell +$ cp secondleafCA.key test/testdata/test_attach_second_private_key +``` + +28. copy root certificate to test/testdata/test_attach_second_rootcert.pem + +```shell +$ cp secondrootCA.crt test/testdata/test_attach_second_rootcert.pem +``` + +29. copy second cert chain to test/testdata/test_attach_second_certchain.pem + +```shell +$ cp secondcertChain.crt test/testdata/test_attach_second_certchain.pem +``` + +30. copy second Leaf certificate to test/testdata/test_attach_second_leafcert.pem + +```shell +$ cp secondleafCA.crt test/testdata/test_attach_second_leafcert.pem +``` diff --git a/test/testdata/test_attach_second_certchain.pem b/test/testdata/test_attach_second_certchain.pem new file mode 100644 index 00000000000..3bf4e7dd5f0 --- /dev/null +++ b/test/testdata/test_attach_second_certchain.pem @@ -0,0 +1,49 @@ +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIUP2BVjdyg37MRM6Xa2l0TSF2/+rcwDQYJKoZIhvcNAQEL +BQAwgZExCzAJBgNVBAYTAklOMQwwCgYDVQQIDANERUwxDDAKBgNVBAcMA0RFTDEa +MBgGA1UECgwRZXhhbXBsZWNsaWVudC5jb20xETAPBgNVBAsMCHNpZ3N0b3JlMREw +DwYDVQQDDAhzaWdzdG9yZTEkMCIGCSqGSIb3DQEJARYVZm9vQGV4YW1wbGVjbGll +bnQuY29tMB4XDTI0MDExODEwMTE0N1oXDTI5MDExNjEwMTE0N1owgZkxCzAJBgNV +BAYTAklOMQwwCgYDVQQIDANERUwxDDAKBgNVBAcMA0RFTDEaMBgGA1UECgwRZXhh +bXBsZWNsaWVudC5jb20xFTATBgNVBAsMDHNpZ3N0b3JlLXN1YjEVMBMGA1UEAwwM +c2lnc3RvcmUtc3ViMSQwIgYJKoZIhvcNAQkBFhVmb29AZXhhbXBsZWNsaWVudC5j +b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCz37o+ObXK1b8/RqEv +MaQQp6X1aD1FptsW+X07ESqZz0XiJToGMdE2ETlFza9VyyeMwJF6YcFK3wfsakB0 +QG40nMt7KI8cT/sFot8WzQTVTSe0HfALvdOnY4OBM5mZPmQlemWfpipsTIiCyIXp +I2tWSjR7rtDlw2VW5N+wpyn+qid+EZRm/ZGzQhwAcH0u+di+6ynt2rdcSn1RMsRr +vGB0/yqbboRsBh5pWNl/42mCoWFRFk3vsUvxKDieTDdTy53vqi7MNB3wDZ3TRj1w +StExZYMzXeRi2VxSzt0k1u/YGgHmQOjPmxHSbQ929V+fXjw3xR06z77ojDxCCQvH +cLJxAgMBAAGjZjBkMB0GA1UdDgQWBBShacFO3pe6fgps4IcgbDV5zS5cZTAfBgNV +HSMEGDAWgBS6b9p3peGUOXzfDnq3w7NAlKX+dDASBgNVHRMBAf8ECDAGAQH/AgEA +MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEAHnds5GMnQOX8QddM +1fqpacdBOS2FhkyNGBmAramSNAEnfYPp7lZqn/TjCytUsiNPliiXpp+LF8a8pZvD +xjayyKiEbHitJdvsMf/kP8uxgv4SdiT96ycDwHCAt1obgG71ywoi9nbBAkuTep5n ++PYB8G0cwCAvyNQE0sOUXYqHHMRwAI5ke13nqWBxDBrx12iTpCL/910XUhpSVlXX +Al8zx2LT7scRu83pZBPFvr9j7IexlinhMH37xgAVXa6BPpATvvAXZg5gn1gtYAex +Af79/eiJn6zJXnF066dXW7OBpV/cILPkBciyC5Il8UMukEM5I36XH4NqPBd/JBPd +VRrmug== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBTCCAu2gAwIBAgIUKv9OVy7IcTL6gvqPRcJZKIX0/ucwDQYJKoZIhvcNAQEL +BQAwgZExCzAJBgNVBAYTAklOMQwwCgYDVQQIDANERUwxDDAKBgNVBAcMA0RFTDEa +MBgGA1UECgwRZXhhbXBsZWNsaWVudC5jb20xETAPBgNVBAsMCHNpZ3N0b3JlMREw +DwYDVQQDDAhzaWdzdG9yZTEkMCIGCSqGSIb3DQEJARYVZm9vQGV4YW1wbGVjbGll +bnQuY29tMB4XDTI0MDExODEwMDkzM1oXDTI5MDExNjEwMDkzM1owgZExCzAJBgNV +BAYTAklOMQwwCgYDVQQIDANERUwxDDAKBgNVBAcMA0RFTDEaMBgGA1UECgwRZXhh +bXBsZWNsaWVudC5jb20xETAPBgNVBAsMCHNpZ3N0b3JlMREwDwYDVQQDDAhzaWdz +dG9yZTEkMCIGCSqGSIb3DQEJARYVZm9vQGV4YW1wbGVjbGllbnQuY29tMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn9FAPZNON2O7k/fYqpI894aUf3ur +LyJsEx6RhC7JYjumc4VLvDA9vSauXeM4fQ+YDaOs9K8FujDbAFGsrltXBBA/Czsd +Ml/OMkkn5ZzDkTXqFXVer31M0fNLWMoAZ9q7c601ndRuTLDp8Ka3aR2Caj2W7VgO +mGDUhgaVo31Omx4TM5ydnSLGewRfw/7nFveHBGKaRG+tVF1zLZwTESGG5/lV8Vq1 +cSctqK9kDwfNFzZKjpIsEDoT2L3ZosevtC3lY07KqvtKEOS9QWTZSRECO0Tzescn +OP9Unb+miTTSl1tuu/gDULhYaCfDZu8bxIRaLt3tHV7falwbvUzO3wO8MQIDAQAB +o1MwUTAdBgNVHQ4EFgQUum/ad6XhlDl83w56t8OzQJSl/nQwHwYDVR0jBBgwFoAU +um/ad6XhlDl83w56t8OzQJSl/nQwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B +AQsFAAOCAQEAVPnYFFhYdAquC2g5k3mA+brhBuxFY+Rf9COE3u4lREJsXxjudsBR +1dE+n9Zla2andkEyu9KQZlTb0WE7WfxDgKEtYCzRYhvtj9xFKCjzncH1w4Z2iN/R +n8qmBWSFN5se0J/7uGsZ1YIcR8BsbkofmgnvBydUSXjNY7lbDOkY79gm/wykgdLe +TNOnRz+z6ofEkduBsxwSyY1Ck9CrRNklcfEW6YY0Re4FzUpBIWgeWqmxhIqeOWFI +eH7n4hqOrENTN7/GJvZH8PnjQj4Nx27cj+EW6xh5QMjYXkaxFFgGyMs/8AaresZZ +geieV/J2gfe+zBuG5h5cJ+9kR26d/0InUA== +-----END CERTIFICATE----- diff --git a/test/testdata/test_attach_second_leafcert.pem b/test/testdata/test_attach_second_leafcert.pem new file mode 100644 index 00000000000..f5ec7c98de8 --- /dev/null +++ b/test/testdata/test_attach_second_leafcert.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIUEc3nCZYvXtlMHd+tLM7x4zueFYgwDQYJKoZIhvcNAQEL +BQAwgZkxCzAJBgNVBAYTAklOMQwwCgYDVQQIDANERUwxDDAKBgNVBAcMA0RFTDEa +MBgGA1UECgwRZXhhbXBsZWNsaWVudC5jb20xFTATBgNVBAsMDHNpZ3N0b3JlLXN1 +YjEVMBMGA1UEAwwMc2lnc3RvcmUtc3ViMSQwIgYJKoZIhvcNAQkBFhVmb29AZXhh +bXBsZWNsaWVudC5jb20wHhcNMjQwMTE4MTAxNDA2WhcNMjkwMTE2MTAxNDA2WjCB +mzELMAkGA1UEBhMCSU4xDDAKBgNVBAgMA0RFTDEMMAoGA1UEBwwDREVMMRowGAYD +VQQKDBFleGFtcGxlY2xpZW50LmNvbTEWMBQGA1UECwwNc2lnc3RvcmUtbGVhZjEW +MBQGA1UEAwwNc2lnc3RvcmUtbGVhZjEkMCIGCSqGSIb3DQEJARYVZm9vQGV4YW1w +bGVjbGllbnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5MdM +RkWjtryLneymMdkz+I8IB8t/6LSwS7M2olnQYV1byLopYraDxCTxIeaizoeeyoK+ +F5HfwXid0X4vM/5PAdSjEq2Cf//+nnVJKQnAC96SCwQmUrKkzM69ASWsTCO3dK3d +iRTI/g6031tMDfkXj2nDDjnBGAl/YIuNSY4mUccrTaGfFbIHjCvQ3zHdsYi90vrx +miKaQRCwe2quE82ZcokkrxLQMM+qUha1TkJdKXAR28E2nZcnjcQFI5hrMMrc+PNb +CB20pZP/Mnw8tED7r+r/0LDs7GruCP+w/FH5K5E4cvyScMXYZ/TUTDv2rrTXzA8u +Rhq7xnEt9k7CQnpNSwIDAQABo3IwcDAfBgNVHSMEGDAWgBShacFO3pe6fgps4Icg +bDV5zS5cZTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE8DATBgNVHSUEDDAKBggrBgEF +BQcDAzAgBgNVHREEGTAXgRVmb29AZXhhbXBsZWNsaWVudC5jb20wDQYJKoZIhvcN +AQELBQADggEBAIJpBNO2/P3TYgp15vnBCCyDa9+BVy4C4CokM7COn24KXY8B6POT +Bk84/lI0Z6nKaSSO7wTWUkkf1UQy7eYuHPCyUMdaupbxnUtPj5+oQIh8X3wuuNzn +nfP++RBBx4qZwTCgdOj89CSw5eGSpPGEjPKacApn9cmZ6bk0ZHlKMQQRyRQ0tFdu +45Ou0r6LwZcf3kcZfSgEDzV2Kz5RKj1UID9vhQShgG0eNesfnSKY0NYxWb6u1tfZ +wHOx2N6wZ0g9tfvJxUcvkLlyg4AC6AOWQ6QINEjtJ4cq5VLkOJg2qjp7+NgfZJFl +yeAczjg+cqeX3jg+/iO9/GTokvXSHRTH85g= +-----END CERTIFICATE----- diff --git a/test/testdata/test_attach_second_private_key b/test/testdata/test_attach_second_private_key new file mode 100644 index 00000000000..6fd0a614935 --- /dev/null +++ b/test/testdata/test_attach_second_private_key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEA5MdMRkWjtryLneymMdkz+I8IB8t/6LSwS7M2olnQYV1byLop +YraDxCTxIeaizoeeyoK+F5HfwXid0X4vM/5PAdSjEq2Cf//+nnVJKQnAC96SCwQm +UrKkzM69ASWsTCO3dK3diRTI/g6031tMDfkXj2nDDjnBGAl/YIuNSY4mUccrTaGf +FbIHjCvQ3zHdsYi90vrxmiKaQRCwe2quE82ZcokkrxLQMM+qUha1TkJdKXAR28E2 +nZcnjcQFI5hrMMrc+PNbCB20pZP/Mnw8tED7r+r/0LDs7GruCP+w/FH5K5E4cvyS +cMXYZ/TUTDv2rrTXzA8uRhq7xnEt9k7CQnpNSwIDAQABAoIBACZhtU840b2PplDJ +ahyE1y5FONCt+HifD9CzcWANd2NOWV60tMrF2hdnJzlLy1ag9Cf/hUrJA2QfC0Mh +S2QKr1CcTvuMNo+o8Bu/i5Wh+CFFpvTILnHDXNirepQdsOlZOKcPoFImNY5CA2BR +ndHeT3CVCs9xKw8QUNlusDZ97bncQhiTJ6Upqmd4432BVxk3uAvPuKlgjeyXQ2hQ +iYdNfWe+qQEqkOCV+JcDQDNXOb+l6bvfhECK/92xhCNu0U8hca5xy5nQlD/epJBn +ojzX+lyQxIs+T/sQF3IbN6pVZ5IGjgPx3LUw/0GSEAr++7SupFIJjgNDrDoOn7GA +7QufhOkCgYEA8g7IZd3PO4t3GK7bnX8yBOuGufwPkJlA2YS/Uh2cbW+YXPQEKqn8 +HQysBjJCuxRnsOkAXoV3u3Ym/eph8Cz+FVqiPt33hYy81ZGGJyOmBUu/9C/Lghxt +D2NbJ7kNFEWe+qvoa13Z7r2VzQdBKjagoMPed3lkEovF14MNzvU2ZKUCgYEA8fS1 +aJ2gcxShL4enPUXykxpbUP52VYJYO75ZLDwQmvlqiNK/EC8ZMCldMrFf1nMDFaG4 +tx+pIizE3rA89ZRTPsj19G3aU1C/B+/LQFM/r+ZpdyaLs5BnPPaPYIEPt6Ad34/O +lxazRv6+FHJJ1EbZlmhsUXOdmMYvtYlJ4N83Fy8CgYBqPBixtI7OKGCFwcB7OCbg +x+niWIEQSmKO1NcPGBXeZdrt+N6XRvFyYmxhb8+fwc3cc/aIhXVOHgXw7Nw9B9If +1x5cDxkiUOlTpkHFjbzAmEVPy2Y63XT0Cvwny+y0l/W1OJuR+6e5QxWq3WM5Pq5y +wGQz9V/5T8Tt2APIcBCGTQKBgHJElpQktU0ENieDUklOyoQMk4nJ00sI9vCoMecB +Kvp1xol9tjxHcgbb0icJu/BEevVxXhImArOgHw3of7Gfbj0dnYLlipGEdeOirQPh +DRfeonpiGuIf1ZHmA8qYyTp4hQM7IF8cmmhyEIUJgLKfD03IXTeOeaRYHNoIT3rD +EHqDAoGADyUkL/6rQcHR04MgGCQX8qkQRDXlfUZps8idu5dnFmoRdzaHdITlWZgJ +V+deNWItvFmEWQdyt8aQ7r+SKbtVLw2R56KKXbMDPx2HxRyomHQymJBX/E7BSKj7 +w02PrkC96WLnupa3RvXW35RJilTiVrPoCHhr2s/SxCXVNrACLeA= +-----END RSA PRIVATE KEY----- diff --git a/test/testdata/test_attach_second_rootcert.pem b/test/testdata/test_attach_second_rootcert.pem new file mode 100644 index 00000000000..5afb1cd9bcb --- /dev/null +++ b/test/testdata/test_attach_second_rootcert.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEBTCCAu2gAwIBAgIUKv9OVy7IcTL6gvqPRcJZKIX0/ucwDQYJKoZIhvcNAQEL +BQAwgZExCzAJBgNVBAYTAklOMQwwCgYDVQQIDANERUwxDDAKBgNVBAcMA0RFTDEa +MBgGA1UECgwRZXhhbXBsZWNsaWVudC5jb20xETAPBgNVBAsMCHNpZ3N0b3JlMREw +DwYDVQQDDAhzaWdzdG9yZTEkMCIGCSqGSIb3DQEJARYVZm9vQGV4YW1wbGVjbGll +bnQuY29tMB4XDTI0MDExODEwMDkzM1oXDTI5MDExNjEwMDkzM1owgZExCzAJBgNV +BAYTAklOMQwwCgYDVQQIDANERUwxDDAKBgNVBAcMA0RFTDEaMBgGA1UECgwRZXhh +bXBsZWNsaWVudC5jb20xETAPBgNVBAsMCHNpZ3N0b3JlMREwDwYDVQQDDAhzaWdz +dG9yZTEkMCIGCSqGSIb3DQEJARYVZm9vQGV4YW1wbGVjbGllbnQuY29tMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn9FAPZNON2O7k/fYqpI894aUf3ur +LyJsEx6RhC7JYjumc4VLvDA9vSauXeM4fQ+YDaOs9K8FujDbAFGsrltXBBA/Czsd +Ml/OMkkn5ZzDkTXqFXVer31M0fNLWMoAZ9q7c601ndRuTLDp8Ka3aR2Caj2W7VgO +mGDUhgaVo31Omx4TM5ydnSLGewRfw/7nFveHBGKaRG+tVF1zLZwTESGG5/lV8Vq1 +cSctqK9kDwfNFzZKjpIsEDoT2L3ZosevtC3lY07KqvtKEOS9QWTZSRECO0Tzescn +OP9Unb+miTTSl1tuu/gDULhYaCfDZu8bxIRaLt3tHV7falwbvUzO3wO8MQIDAQAB +o1MwUTAdBgNVHQ4EFgQUum/ad6XhlDl83w56t8OzQJSl/nQwHwYDVR0jBBgwFoAU +um/ad6XhlDl83w56t8OzQJSl/nQwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B +AQsFAAOCAQEAVPnYFFhYdAquC2g5k3mA+brhBuxFY+Rf9COE3u4lREJsXxjudsBR +1dE+n9Zla2andkEyu9KQZlTb0WE7WfxDgKEtYCzRYhvtj9xFKCjzncH1w4Z2iN/R +n8qmBWSFN5se0J/7uGsZ1YIcR8BsbkofmgnvBydUSXjNY7lbDOkY79gm/wykgdLe +TNOnRz+z6ofEkduBsxwSyY1Ck9CrRNklcfEW6YY0Re4FzUpBIWgeWqmxhIqeOWFI +eH7n4hqOrENTN7/GJvZH8PnjQj4Nx27cj+EW6xh5QMjYXkaxFFgGyMs/8AaresZZ +geieV/J2gfe+zBuG5h5cJ+9kR26d/0InUA== +-----END CERTIFICATE-----