diff --git a/test/e2e_test.go b/test/e2e_test.go index ed393958ad1c..77890a0efdf4 100644 --- a/test/e2e_test.go +++ b/test/e2e_test.go @@ -146,7 +146,7 @@ func TestSignVerifyCertBundle(t *testing.T) { _, _, cleanup := mkimage(t, imgName) defer cleanup() - caCertFile, _ /* caPrivKeyFile */, caIntermediateCertFile, _ /* caIntermediatePrivKeyFile */, certFile, privKeyFile, pubkeyFile, err := generateCertificateBundleFiles(td, true, "foobar") + caCertFile, _ /* caPrivKeyFile */, caIntermediateCertFile, _ /* caIntermediatePrivKeyFile */, certFile, privKeyFile, pubkeyFile, certChainFile, err := generateCertificateBundleFiles(td, true, "foobar") ctx := context.Background() // Verify should fail at first @@ -169,6 +169,8 @@ func TestSignVerifyCertBundle(t *testing.T) { // Now verify and download should work! must(verifyCertBundle(pubkeyFile, caCertFile, caIntermediateCertFile, certFile, imgName, true, nil, "", false), t) + // verification with certificate chain instead of root/intermediate files should work as well + must(verifyCertChain(pubkeyFile, certChainFile, certFile, imgName, true, nil, "", false), t) must(download.SignatureCmd(ctx, options.RegistryOptions{}, imgName), t) // Look for a specific annotation diff --git a/test/helpers.go b/test/helpers.go index fb41aacbb9a7..38bffaa282cd 100644 --- a/test/helpers.go +++ b/test/helpers.go @@ -87,6 +87,27 @@ var verify = func(keyRef, imageRef string, checkClaims bool, annotations map[str return cmd.Exec(context.Background(), args) } +var verifyCertChain = func(keyRef, certChain, certFile, imageRef string, checkClaims bool, annotations map[string]interface{}, attachment string, skipTlogVerify bool) error { + cmd := cliverify.VerifyCommand{ + KeyRef: keyRef, + RekorURL: rekorURL, + CheckClaims: checkClaims, + Annotations: sigs.AnnotationsMap{Annotations: annotations}, + Attachment: attachment, + HashAlgorithm: crypto.SHA256, + MaxWorkers: 10, + IgnoreTlog: skipTlogVerify, + CertVerifyOptions: options.CertVerifyOptions{ + Cert: certFile, + CertChain: certChain, + }, + } + + args := []string{imageRef} + + return cmd.Exec(context.Background(), args) +} + var verifyCertBundle = func(keyRef, caCertFile, caIntermediates, certFile, imageRef string, checkClaims bool, annotations map[string]interface{}, attachment string, skipTlogVerify bool) error { cmd := cliverify.VerifyCommand{ KeyRef: keyRef, @@ -484,9 +505,10 @@ func generateCertificateBundleFiles(td string, genIntermediate bool, outputSuffi certFile string, keyFile string, pubKeyFile string, + certChainFile string, err error, ) { - caCertBuf, caPrivKeyBuf, caIntermediateCertBuf, caIntermediatePrivKeyBuf, certBuf, keyBuf, pubkey, err := generateCertificateBundle(genIntermediate) + caCertBuf, caPrivKeyBuf, caIntermediateCertBuf, caIntermediatePrivKeyBuf, certBuf, keyBuf, pubkey, certChainBuf, err := generateCertificateBundle(genIntermediate) if err != nil { err = fmt.Errorf("error generating certificate bundle: %w", err) return @@ -523,6 +545,13 @@ func generateCertificateBundleFiles(td string, genIntermediate bool, outputSuffi err = fmt.Errorf("error writing key to file: %w", err) return } + // write the contents of certChainBuf to a file + certChainFile = filepath.Join(td, fmt.Sprintf("certchain%s.pem", outputSuffix)) + err = os.WriteFile(certChainFile, certChainBuf.Bytes(), 0600) + if err != nil { + err = fmt.Errorf("error writing certificate chain to file: %w", err) + return + } // write the public key to a file pubKeyFile = filepath.Join(td, fmt.Sprintf("pubkey%s.pem", outputSuffix)) pubKeyBuf := &bytes.Buffer{} @@ -546,6 +575,7 @@ func generateCertificateBundle(genIntermediate bool) ( certBuf *bytes.Buffer, keyBuf *bytes.Buffer, pubkeyBuf *bytes.Buffer, + certBundleBuf *bytes.Buffer, err error, ) { // set up our CA certificate @@ -710,5 +740,18 @@ func generateCertificateBundle(genIntermediate bool) ( log.Fatalf("failed to encode cert: %v", err) } - return caCertBuf, caPrivKeyBuf, caIntermediateCertBuf, caIntermediatePrivKeyBuf, certBuf, keyBuf, pubkeyBuf, nil + // concatenate into certChainBuf the contents of caIntermediateCertBuf and caCertBuf + certBundleBuf = &bytes.Buffer{} + if genIntermediate { + _, err = certBundleBuf.Write(caIntermediateCertBuf.Bytes()) + if err != nil { + log.Fatalf("failed to write caIntermediateCertBuf to certChainBuf: %v", err) + } + } + _, err = certBundleBuf.Write(caCertBuf.Bytes()) + if err != nil { + log.Fatalf("failed to write caCertBuf to certChainBuf: %v", err) + } + + return caCertBuf, caPrivKeyBuf, caIntermediateCertBuf, caIntermediatePrivKeyBuf, certBuf, keyBuf, pubkeyBuf, certBundleBuf, nil } diff --git a/test/helpers_test.go b/test/helpers_test.go index a40588a2f18d..9c43468d966f 100644 --- a/test/helpers_test.go +++ b/test/helpers_test.go @@ -19,7 +19,7 @@ func TestGenerateCertificateBundle(t *testing.T) { }, } { t.Run(test.name, func(t *testing.T) { - _, _, _, _, _, _, _, err := generateCertificateBundle(true) + _, _, _, _, _, _, _, _, err := generateCertificateBundle(true) if err != nil { t.Fatalf("Error generating certificate bundle: %v", err) }