From c6094b2ed62df766d567ebc40974cef58097416f Mon Sep 17 00:00:00 2001 From: "Dmitry S." Date: Tue, 9 Jul 2024 17:50:22 +0200 Subject: [PATCH] add testing VerifyBlobCmd with CA roots Signed-off-by: Dmitry S. --- test/e2e_test.go | 35 ++++++++++++++++++++++++++++++++++- test/helpers.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/test/e2e_test.go b/test/e2e_test.go index 409485341938..787d85698e7c 100644 --- a/test/e2e_test.go +++ b/test/e2e_test.go @@ -873,16 +873,26 @@ func TestVerifyWithCARoots(t *testing.T) { td := t.TempDir() imgName := path.Join(repo, "cosign-verify-caroots-e2e") - + privKeyRef := path.Join(repo, "cosign-verify-caroots-e2e-blob") _, _, cleanup := mkimage(t, imgName) defer cleanup() + blob := "someblob2sign" + b := bytes.Buffer{} + blobRef := filepath.Join(td, blob) + if err := os.WriteFile(blobRef, []byte(blob), 0644); err != nil { + t.Fatal(err) + } + must(generate.GenerateCmd(context.Background(), options.RegistryOptions{}, imgName, nil, &b), t) rootCert, rootKey, _ := GenerateRootCa() subCert, subKey, _ := GenerateSubordinateCa(rootCert, rootKey) leafCert, privKey, _ := GenerateLeafCert("subject@mail.com", "oidc-issuer", subCert, subKey) + if err := ecdsaPublicKeyToPEMFile(privKey, privKeyRef); err != nil { + t.Fatal(err) + } pemRoot := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: rootCert.Raw}) pemSub := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: subCert.Raw}) @@ -947,6 +957,14 @@ func TestVerifyWithCARoots(t *testing.T) { t.Fatal(err) } + // Now sign the blob with one key + ko := options.KeyOpts{ + KeyRef: privKeyRef, + } + blobSig, err := sign.SignBlobCmd(ro, ko, blobRef, true, "", "", false) + if err != nil { + t.Fatal(err) + } // the following fields with non-changing values are logically "factored out" for brevity // and passed to verifyKeylessTSAWithCARoots in the testing loop: // imageName string @@ -1053,6 +1071,21 @@ func TestVerifyWithCARoots(t *testing.T) { t.Errorf("%s - unexpected error: %v", tt.name, err) } } + err = verifyBlobKeylessTSAWithCARoots(blobRef, + string(blobSig), + tt.rootRef, + tt.subRef, + tt.leafRef, + false, + false) + hasErr = (err != nil) + if hasErr != tt.wantError { + if tt.wantError { + t.Errorf("%s - no expected error", tt.name) + } else { + t.Errorf("%s - unexpected error: %v", tt.name, err) + } + } } } diff --git a/test/helpers.go b/test/helpers.go index 7501ce1cc45f..66e51f13a710 100644 --- a/test/helpers.go +++ b/test/helpers.go @@ -21,11 +21,13 @@ import ( "bytes" "context" "crypto" + "crypto/ecdsa" "crypto/rand" "crypto/rsa" "crypto/x509" "crypto/x509/pkix" "encoding/pem" + "errors" "fmt" "io" "log" @@ -195,6 +197,28 @@ var verifyKeylessTSAWithCARoots = func(imageRef string, return cmd.Exec(context.Background(), args) } +var verifyBlobKeylessTSAWithCARoots = func(blobRef string, + sig string, + caroots string, // filename of a PEM file with CA Roots certificates + intermediates string, // empty or filename of a PEM file with Intermediate certificates + certFile string, // filename of a PEM file with the codesigning certificate + skipSCT bool, + skipTlogVerify bool) error { + cmd := cliverify.VerifyBlobCmd{ + CertVerifyOptions: options.CertVerifyOptions{ + CertOidcIssuerRegexp: ".*", + CertIdentityRegexp: ".*", + }, + SigRef: sig, + CertRef: certFile, + CARoots: caroots, + CAIntermediates: intermediates, + IgnoreSCT: skipSCT, + IgnoreTlog: skipTlogVerify, + } + return cmd.Exec(context.Background(), blobRef) +} + // Used to verify local images stored on disk var verifyLocal = func(keyRef, path string, checkClaims bool, annotations map[string]interface{}, attachment string) error { cmd := cliverify.VerifyCommand{ @@ -727,3 +751,26 @@ func generateCertificateBundle(genIntermediate bool) ( return caCertBuf, caPrivKeyBuf, caIntermediateCertBuf, caIntermediatePrivKeyBuf, certBuf, certBundleBuf, nil } + +func ecdsaPrivateKeyToPEM(priv *ecdsa.PrivateKey) ([]byte, error) { + der, err := x509.MarshalECPrivateKey(priv) + if err != nil { + return nil, err + } + block := &pem.Block{ + Type: "EC PRIVATE KEY", + Bytes: der, + } + return pem.EncodeToMemory(block), nil +} + +func ecdsaPublicKeyToPEMFile(priv *ecdsa.PrivateKey, fpath string) error { + pemBytes, err := ecdsaPrivateKeyToPEM(priv) + if err != nil { + return err + } + if fpath == "" { + return errors.New("file path empty") + } + return os.WriteFile(fpath, pemBytes, 0600) +}