diff --git a/cmd/cosign/cli/attest/attest_blob.go b/cmd/cosign/cli/attest/attest_blob.go index 8034825f457..b55c3a4e63a 100644 --- a/cmd/cosign/cli/attest/attest_blob.go +++ b/cmd/cosign/cli/attest/attest_blob.go @@ -18,6 +18,7 @@ import ( "bytes" "context" "crypto" + "encoding/base64" "encoding/hex" "encoding/json" "fmt" @@ -26,42 +27,68 @@ import ( "path" "path/filepath" "strings" + "time" "github.com/pkg/errors" "github.com/sigstore/cosign/cmd/cosign/cli/options" + "github.com/sigstore/cosign/cmd/cosign/cli/rekor" "github.com/sigstore/cosign/cmd/cosign/cli/sign" + "github.com/sigstore/cosign/internal/pkg/cosign/tsa" "github.com/sigstore/cosign/pkg/cosign" "github.com/sigstore/cosign/pkg/cosign/attestation" + cbundle "github.com/sigstore/cosign/pkg/cosign/bundle" "github.com/sigstore/cosign/pkg/types" + "github.com/sigstore/sigstore/pkg/cryptoutils" "github.com/sigstore/sigstore/pkg/signature" "github.com/sigstore/sigstore/pkg/signature/dsse" signatureoptions "github.com/sigstore/sigstore/pkg/signature/options" + tsaclient "github.com/sigstore/timestamp-authority/pkg/client" ) // nolint type AttestBlobCommand struct { - KeyRef string + options.KeyOpts + CertPath string + CertChainPath string + ArtifactHash string PredicatePath string PredicateType string + TlogUpload bool + Timeout time.Duration + OutputSignature string OutputAttestation string - - PassFunc cosign.PassFunc + OutputCertificate string } // nolint func (c *AttestBlobCommand) Exec(ctx context.Context, artifactPath string) error { - // TODO: Add in experimental keyless mode - if !options.OneOf(c.KeyRef) { + // We can't have both a key and a security key + if options.NOf(c.KeyRef, c.Sk) > 1 { return &options.KeyParseError{} } + if c.Timeout != 0 { + var cancelFn context.CancelFunc + ctx, cancelFn = context.WithTimeout(ctx, c.Timeout) + defer cancelFn() + } + + if c.TSAServerURL != "" && c.RFC3161TimestampPath == "" { + return errors.New("expected an rfc3161-timestamp path when using a TSA server") + } + + sv, err := sign.SignerFromKeyOpts(ctx, c.CertPath, c.CertChainPath, c.KeyOpts) + if err != nil { + return fmt.Errorf("getting signer: %w", err) + } + defer sv.Close() + var artifact []byte var hexDigest string - var err error if c.ArtifactHash == "" { if artifactPath == "-" { @@ -71,21 +98,11 @@ func (c *AttestBlobCommand) Exec(ctx context.Context, artifactPath string) error artifact, err = os.ReadFile(filepath.Clean(artifactPath)) } if err != nil { + fmt.Println(filepath.Clean(artifactPath)) return err } } - ko := options.KeyOpts{ - KeyRef: c.KeyRef, - PassFunc: c.PassFunc, - } - - sv, err := sign.SignerFromKeyOpts(ctx, "", "", ko) - if err != nil { - return errors.Wrap(err, "getting signer") - } - defer sv.Close() - if c.ArtifactHash == "" { digest, _, err := signature.ComputeDigestForSigning(bytes.NewReader(artifact), crypto.SHA256, []crypto.Hash{crypto.SHA256, crypto.SHA384}) if err != nil { @@ -126,6 +143,54 @@ func (c *AttestBlobCommand) Exec(ctx context.Context, artifactPath string) error return errors.Wrap(err, "signing") } + signedPayload := cosign.LocalSignedPayload{} + if c.TSAServerURL != "" { + clientTSA, err := tsaclient.GetTimestampClient(c.TSAServerURL) + if err != nil { + return fmt.Errorf("failed to create TSA client: %w", err) + } + rfc3161Timestamp, err := tsa.GetTimestampedSignature(sig, clientTSA) + if err != nil { + return err + } + if err := os.WriteFile(c.RFC3161TimestampPath, rfc3161Timestamp, 0600); err != nil { + return fmt.Errorf("create rfc3161 timestamp file: %w", err) + } + fmt.Printf("RF3161 timestamp bundle wrote in the file %s\n", c.RFC3161TimestampPath) + } + + var rekorBytes []byte + if sign.ShouldUploadToTlog(ctx, c.KeyOpts, nil, c.TlogUpload) { + rekorBytes, err = sv.Bytes(ctx) + if err != nil { + return err + } + rekorClient, err := rekor.NewClient(c.RekorURL) + if err != nil { + return err + } + entry, err := cosign.TLogUploadInTotoAttestation(ctx, rekorClient, sig, rekorBytes) + if err != nil { + return err + } + fmt.Fprintln(os.Stderr, "tlog entry created with index:", *entry.LogIndex) + signedPayload.Bundle = cbundle.EntryToBundle(entry) + } + + if c.BundlePath != "" { + signedPayload.Base64Signature = base64.StdEncoding.EncodeToString(sig) + signedPayload.Cert = base64.StdEncoding.EncodeToString(rekorBytes) + + contents, err := json.Marshal(signedPayload) + if err != nil { + return err + } + if err := os.WriteFile(c.BundlePath, contents, 0600); err != nil { + return fmt.Errorf("create bundle file: %w", err) + } + fmt.Printf("Bundle wrote in the file %s\n", c.BundlePath) + } + if c.OutputSignature != "" { if err := os.WriteFile(c.OutputSignature, sig, 0600); err != nil { return fmt.Errorf("create signature file: %w", err) @@ -142,5 +207,21 @@ func (c *AttestBlobCommand) Exec(ctx context.Context, artifactPath string) error fmt.Fprintf(os.Stderr, "Attestation written in %s\n", c.OutputAttestation) } + if c.OutputCertificate != "" { + signer, err := sv.Bytes(ctx) + if err != nil { + return fmt.Errorf("error getting signer: %w", err) + } + cert, err := cryptoutils.UnmarshalCertificatesFromPEM(signer) + // signer is a certificate + if err == nil && len(cert) == 1 { + bts := signer + if err := os.WriteFile(c.OutputCertificate, bts, 0600); err != nil { + return fmt.Errorf("create certificate file: %w", err) + } + fmt.Printf("Certificate wrote in the file %s\n", c.OutputCertificate) + } + } + return nil } diff --git a/cmd/cosign/cli/attest/attest_blob_test.go b/cmd/cosign/cli/attest/attest_blob_test.go new file mode 100644 index 00000000000..ff0c10fcae0 --- /dev/null +++ b/cmd/cosign/cli/attest/attest_blob_test.go @@ -0,0 +1,244 @@ +// Copyright 2022 The Sigstore Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package attest + +import ( + "bytes" + "context" + "crypto" + "crypto/x509" + "encoding/base64" + "encoding/hex" + "encoding/json" + "encoding/pem" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/in-toto/in-toto-golang/in_toto" + "github.com/pkg/errors" + ssldsse "github.com/secure-systems-lab/go-securesystemslib/dsse" + "github.com/sigstore/cosign/cmd/cosign/cli/generate" + "github.com/sigstore/cosign/cmd/cosign/cli/options" + "github.com/sigstore/cosign/pkg/cosign" + "github.com/sigstore/cosign/test" + "github.com/sigstore/sigstore/pkg/signature" + "github.com/sigstore/sigstore/pkg/signature/dsse" + "github.com/theupdateframework/go-tuf/encrypted" +) + +// TestAttestBlobCmdLocalKeyAndSk verifies the AttestBlobCmd returns an error +// if both a local key path and a sk are specified +func TestAttestBlobCmdLocalKeyAndSk(t *testing.T) { + ctx := context.Background() + for _, ko := range []options.KeyOpts{ + // local and sk keys + { + KeyRef: "testLocalPath", + PassFunc: generate.GetPass, + Sk: true, + }, + } { + at := AttestBlobCommand{ + KeyOpts: ko, + } + err := at.Exec(ctx, "some/path") + if (errors.Is(err, &options.KeyParseError{}) == false) { + t.Fatal("expected KeyParseError") + } + } +} + +func writeFile(t *testing.T, td string, blob string, name string) string { + // Write blob to disk + blobPath := filepath.Join(td, name) + if err := os.WriteFile(blobPath, []byte(blob), 0644); err != nil { + t.Fatal(err) + } + return blobPath +} + +// TestAttestBlobCmdWithCert verifies the AttestBlobCmd checks +// that the cmd correctly matches the signing key with the cert +// provided. +func TestAttestBlobCmdLocalKeyAndCert(t *testing.T) { + td := t.TempDir() + rootCert, rootKey, _ := test.GenerateRootCa() + subCert, subKey, _ := test.GenerateSubordinateCa(rootCert, rootKey) + leafCert, privKey, _ := test.GenerateLeafCert("subject", "oidc-issuer", subCert, subKey) + pemChain := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: subCert.Raw}) + subCertPem := writeFile(t, td, string(pemChain), "other_cert.pem") + pemChain = append(pemChain, + pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: rootCert.Raw})...) + pemLeaf := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: leafCert.Raw}) + + otherRootCert, _, _ := test.GenerateRootCa() + pemOtherRoot := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: otherRootCert.Raw}) + otherRootPem := writeFile(t, td, string(pemOtherRoot), "other_root_cert.pem") + + x509Encoded, _ := x509.MarshalPKCS8PrivateKey(privKey) + encBytes, _ := encrypted.Encrypt(x509Encoded, nil) + keyPem := pem.EncodeToMemory(&pem.Block{ + Type: cosign.CosignPrivateKeyPemType, + Bytes: encBytes}) + keyRef := writeFile(t, td, string(keyPem), "key.pem") + certRef := writeFile(t, td, string(pemLeaf), "cert.pem") + chainRef := writeFile(t, td, string(pemChain), "chain.pem") + + blob := writeFile(t, td, "foo", "foo.txt") + predicate := `{ "buildType": "x", "builder": { "id": "2" }, "recipe": {} }` + predicateType := "slsaprovenance" + predicatePath := writeFile(t, td, predicate, "predicate.json") + + ctx := context.Background() + for _, tc := range []struct { + name string + keyref string + certref string + certchainref string + errString string + }{ + { + name: "no cert", + keyref: keyRef, + }, + { + name: "cert matches key", + keyref: keyRef, + certref: certRef, + }, + { + name: "fail: cert no match key", + keyref: keyRef, + certref: subCertPem, + errString: "public key in certificate does not match the provided public key", + }, + { + name: "cert chain matches key", + keyref: keyRef, + certref: certRef, + certchainref: chainRef, + }, + { + name: "cert chain partial", + keyref: keyRef, + certref: certRef, + certchainref: subCertPem, + }, + { + name: "fail: cert chain bad", + keyref: keyRef, + certref: certRef, + certchainref: otherRootPem, + errString: "unable to validate certificate chain", + }, + } { + t.Run(tc.name, func(t *testing.T) { + at := AttestBlobCommand{ + KeyOpts: options.KeyOpts{KeyRef: tc.keyref}, + CertPath: tc.certref, + CertChainPath: tc.certchainref, + PredicatePath: predicatePath, + PredicateType: predicateType, + } + err := at.Exec(ctx, blob) + if err != nil { + if tc.errString == "" { + t.Fatalf("unexpected error %v", err) + } + if !strings.Contains(err.Error(), tc.errString) { + t.Fatalf("expected error %v got %v", tc.errString, err) + } + return + } + if tc.errString != "" { + t.Fatalf("expected error %v", tc.errString) + } + }) + } +} + +// TestAttestBlob tests the main functionality -- does the command produce +// a validly signed DSSE envelope? (Using an on disk key) +func TestAttestBlob(t *testing.T) { + ctx := context.Background() + td := t.TempDir() + + keys, _ := cosign.GenerateKeyPair(nil) + keyRef := writeFile(t, td, string(keys.PrivateBytes), "key.pem") + pubKeyRef := writeFile(t, td, string(keys.PublicBytes), "key.pub") + + blob := []byte("foo") + blobPath := writeFile(t, td, string(blob), "foo.txt") + digest, _, _ := signature.ComputeDigestForSigning(bytes.NewReader(blob), crypto.SHA256, []crypto.Hash{crypto.SHA256, crypto.SHA384}) + blobDigest := strings.ToLower(hex.EncodeToString(digest)) + predicate := `{ "buildType": "x", "builder": { "id": "2" }, "recipe": {} }` + predicateType := "slsaprovenance" + predicatePath := writeFile(t, td, predicate, "predicate.json") + + dssePath := filepath.Join(td, "dsse.intoto.jsonl") + at := AttestBlobCommand{ + KeyOpts: options.KeyOpts{KeyRef: keyRef}, + PredicatePath: predicatePath, + PredicateType: predicateType, + OutputSignature: dssePath, + } + err := at.Exec(ctx, blobPath) + if err != nil { + t.Fatal(err) + } + + // Load the attestation. + dsseBytes, _ := os.ReadFile(dssePath) + env := &ssldsse.Envelope{} + if err := json.Unmarshal(dsseBytes, env); err != nil { + t.Fatal(err) + } + + if len(env.Signatures) != 1 { + t.Fatalf("expected 1 signature, got %d", len(env.Signatures)) + } + + // Verify the subject digest + decodedPredicate, err := base64.StdEncoding.DecodeString(env.Payload) + if err != nil { + t.Fatalf("decoding dsse payload: %v", err) + } + var statement in_toto.Statement + if err := json.Unmarshal(decodedPredicate, &statement); err != nil { + t.Fatalf("decoding predicate: %v", err) + } + if statement.Subject == nil || len(statement.Subject) != 1 { + t.Fatalf("expected one subject in intoto statement") + } + if statement.Subject[0].Digest["sha256"] != blobDigest { + t.Fatalf("expected matching digest") + } + if statement.PredicateType != options.PredicateTypeMap[predicateType] { + t.Fatalf("expected matching predicate type") + } + + // Load a verifier and DSSE verify + verifier, _ := signature.LoadVerifierFromPEMFile(pubKeyRef, crypto.SHA256) + dssev, err := ssldsse.NewEnvelopeVerifier(&dsse.VerifierAdapter{SignatureVerifier: verifier}) + if err != nil { + t.Fatalf("new envelope verifier: %v", err) + } + if _, err := dssev.Verify(env); err != nil { + t.Fatalf("dsse verify: %v", err) + } + +} diff --git a/cmd/cosign/cli/attest_blob.go b/cmd/cosign/cli/attest_blob.go index 0eca6c8c810..3867476d95f 100644 --- a/cmd/cosign/cli/attest_blob.go +++ b/cmd/cosign/cli/attest_blob.go @@ -16,6 +16,7 @@ package cli import ( "github.com/sigstore/cosign/cmd/cosign/cli/attest" + "github.com/sigstore/cosign/cmd/cosign/cli/generate" "github.com/sigstore/cosign/cmd/cosign/cli/options" "github.com/spf13/cobra" ) @@ -46,13 +47,41 @@ func AttestBlob() *cobra.Command { Args: cobra.ExactArgs(1), PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { + oidcClientSecret, err := o.OIDC.ClientSecret() + if err != nil { + return err + } + ko := options.KeyOpts{ + KeyRef: o.Key, + PassFunc: generate.GetPass, + Sk: o.SecurityKey.Use, + Slot: o.SecurityKey.Slot, + FulcioURL: o.Fulcio.URL, + IDToken: o.Fulcio.IdentityToken, + InsecureSkipFulcioVerify: o.Fulcio.InsecureSkipFulcioVerify, + RekorURL: o.Rekor.URL, + OIDCIssuer: o.OIDC.Issuer, + OIDCClientID: o.OIDC.ClientID, + OIDCClientSecret: oidcClientSecret, + OIDCRedirectURL: o.OIDC.RedirectURL, + OIDCProvider: o.OIDC.Provider, + SkipConfirmation: o.SkipConfirmation, + TSAServerURL: o.TSAServerURL, + RFC3161TimestampPath: o.RFC3161TimestampPath, + BundlePath: o.BundlePath, + } v := attest.AttestBlobCommand{ - KeyRef: o.Key, + KeyOpts: ko, + CertPath: o.Cert, + CertChainPath: o.CertChain, ArtifactHash: o.Hash, + TlogUpload: o.TlogUpload, PredicateType: o.Predicate.Type, PredicatePath: o.Predicate.Path, OutputSignature: o.OutputSignature, OutputAttestation: o.OutputAttestation, + OutputCertificate: o.OutputCertificate, + Timeout: ro.Timeout, } return v.Exec(cmd.Context(), args[0]) }, diff --git a/cmd/cosign/cli/options/attest_blob.go b/cmd/cosign/cli/options/attest_blob.go index d530d122dff..3a942760cd1 100644 --- a/cmd/cosign/cli/options/attest_blob.go +++ b/cmd/cosign/cli/options/attest_blob.go @@ -20,12 +20,27 @@ import ( // AttestOptions is the top level wrapper for the attest command. type AttestBlobOptions struct { - Key string - Hash string + Key string + Cert string + CertChain string + + SkipConfirmation bool + TlogUpload bool + TSAServerURL string + RFC3161TimestampPath string + + Hash string + Predicate PredicateLocalOptions + OutputSignature string OutputAttestation string + OutputCertificate string + BundlePath string - Predicate PredicateLocalOptions + Rekor RekorOptions + Fulcio FulcioOptions + OIDC OIDCOptions + SecurityKey SecurityKeyOptions } var _ Interface = (*AttestOptions)(nil) @@ -33,9 +48,25 @@ var _ Interface = (*AttestOptions)(nil) // AddFlags implements Interface func (o *AttestBlobOptions) AddFlags(cmd *cobra.Command) { o.Predicate.AddFlags(cmd) + o.Rekor.AddFlags(cmd) + o.Fulcio.AddFlags(cmd) + o.OIDC.AddFlags(cmd) + o.SecurityKey.AddFlags(cmd) cmd.Flags().StringVar(&o.Key, "key", "", "path to the private key file, KMS URI or Kubernetes Secret") + _ = cmd.Flags().SetAnnotation("key", cobra.BashCompFilenameExt, []string{"key"}) + + cmd.Flags().StringVar(&o.Cert, "certificate", "", + "path to the X.509 certificate in PEM format to include in the OCI Signature") + _ = cmd.Flags().SetAnnotation("certificate", cobra.BashCompFilenameExt, []string{"cert"}) + + cmd.Flags().StringVar(&o.CertChain, "certificate-chain", "", + "path to a list of CA X.509 certificates in PEM format which will be needed "+ + "when building the certificate chain for the signing certificate. "+ + "Must start with the parent intermediate CA certificate of the "+ + "signing certificate and end with the root certificate. Included in the OCI Signature") + _ = cmd.Flags().SetAnnotation("certificate-chain", cobra.BashCompFilenameExt, []string{"cert"}) cmd.Flags().StringVar(&o.OutputSignature, "output-signature", "", "write the signature to FILE") @@ -44,6 +75,27 @@ func (o *AttestBlobOptions) AddFlags(cmd *cobra.Command) { cmd.Flags().StringVar(&o.OutputAttestation, "output-attestation", "", "write the attestation to FILE") + cmd.Flags().StringVar(&o.OutputCertificate, "output-certificate", "", + "write the certificate to FILE") + _ = cmd.Flags().SetAnnotation("key", cobra.BashCompFilenameExt, []string{}) + + cmd.Flags().StringVar(&o.BundlePath, "bundle", "", + "write everything required to verify the blob to a FILE") + _ = cmd.Flags().SetAnnotation("bundle", cobra.BashCompFilenameExt, []string{}) + cmd.Flags().StringVar(&o.Hash, "hash", "", "hash of blob in hexadecimal (base16). Used if you want to sign an artifact stored elsewhere and have the hash") + + cmd.Flags().BoolVarP(&o.SkipConfirmation, "yes", "y", false, + "skip confirmation prompts for non-destructive operations") + + cmd.Flags().BoolVar(&o.TlogUpload, "tlog-upload", false, + "whether or not to upload to the tlog") + + cmd.Flags().StringVar(&o.TSAServerURL, "timestamp-server-url", "", + "url to the Timestamp RFC3161 server, default none") + + cmd.Flags().StringVar(&o.RFC3161TimestampPath, "rfc3161-timestamp-bundle", "", + "write everything required to verify the blob to a FILE") + _ = cmd.Flags().SetAnnotation("rfc3161-timestamp-bundle", cobra.BashCompFilenameExt, []string{}) } diff --git a/doc/cosign_attest-blob.md b/doc/cosign_attest-blob.md index 78b1aee319d..9f6e125283b 100644 --- a/doc/cosign_attest-blob.md +++ b/doc/cosign_attest-blob.md @@ -30,13 +30,33 @@ cosign attest-blob [flags] ### Options ``` - --hash string hash of blob in hexadecimal (base16). Used if you want to sign an artifact stored elsewhere and have the hash - -h, --help help for attest-blob - --key string path to the private key file, KMS URI or Kubernetes Secret - --output-attestation string write the attestation to FILE - --output-signature string write the signature to FILE - --predicate string path to the predicate file. - --type string specify a predicate type (slsaprovenance|link|spdx|spdxjson|cyclonedx|vuln|custom) or an URI (default "custom") + --bundle string write everything required to verify the blob to a FILE + --certificate string path to the X.509 certificate in PEM format to include in the OCI Signature + --certificate-chain string path to a list of CA X.509 certificates in PEM format which will be needed when building the certificate chain for the signing certificate. Must start with the parent intermediate CA certificate of the signing certificate and end with the root certificate. Included in the OCI Signature + --fulcio-url string [EXPERIMENTAL] address of sigstore PKI server (default "https://fulcio.sigstore.dev") + --hash string hash of blob in hexadecimal (base16). Used if you want to sign an artifact stored elsewhere and have the hash + -h, --help help for attest-blob + --identity-token string [EXPERIMENTAL] identity token to use for certificate from fulcio + --insecure-skip-verify [EXPERIMENTAL] skip verifying fulcio published to the SCT (this should only be used for testing). + --key string path to the private key file, KMS URI or Kubernetes Secret + --oidc-client-id string [EXPERIMENTAL] OIDC client ID for application (default "sigstore") + --oidc-client-secret-file string [EXPERIMENTAL] Path to file containing OIDC client secret for application + --oidc-disable-ambient-providers [EXPERIMENTAL] Disable ambient OIDC providers. When true, ambient credentials will not be read + --oidc-issuer string [EXPERIMENTAL] OIDC provider to be used to issue ID token (default "https://oauth2.sigstore.dev/auth") + --oidc-provider string [EXPERIMENTAL] Specify the provider to get the OIDC token from (Optional). If unset, all options will be tried. Options include: [spiffe, google, github, filesystem] + --oidc-redirect-url string [EXPERIMENTAL] OIDC redirect URL (Optional). The default oidc-redirect-url is 'http://localhost:0/auth/callback'. + --output-attestation string write the attestation to FILE + --output-certificate string write the certificate to FILE + --output-signature string write the signature to FILE + --predicate string path to the predicate file. + --rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev") + --rfc3161-timestamp-bundle string write everything required to verify the blob to a FILE + --sk whether to use a hardware security key + --slot string security key slot to use for generated key (default: signature) (authentication|signature|card-authentication|key-management) + --timestamp-server-url string url to the Timestamp RFC3161 server, default none + --tlog-upload whether or not to upload to the tlog + --type string specify a predicate type (slsaprovenance|link|spdx|spdxjson|cyclonedx|vuln|custom) or an URI (default "custom") + -y, --yes skip confirmation prompts for non-destructive operations ``` ### Options inherited from parent commands diff --git a/test/e2e_test.go b/test/e2e_test.go index cc7c54ffb26..c1d266596e7 100644 --- a/test/e2e_test.go +++ b/test/e2e_test.go @@ -1865,12 +1865,15 @@ func TestAttestBlobSignVerify(t *testing.T) { mustErr(blobVerifyAttestationCmd.Exec(ctx, bp), t) // Now attest the blob with the private key + ko := options.KeyOpts{ + KeyRef: privKeyPath1, + PassFunc: passFunc, + } attestBlobCmd := attest.AttestBlobCommand{ - KeyRef: privKeyPath1, + KeyOpts: ko, PredicatePath: predicatePath, PredicateType: predicateType, OutputSignature: outputSignature, - PassFunc: passFunc, } must(attestBlobCmd.Exec(ctx, bp), t) diff --git a/test/e2e_test.sh b/test/e2e_test.sh index 594eba6503a..4a17ecdf120 100755 --- a/test/e2e_test.sh +++ b/test/e2e_test.sh @@ -18,7 +18,7 @@ set -ex echo "copying rekor repo" pushd $HOME -git clone https://github.com/sigstore/rekor.git +# git clone https://github.com/sigstore/rekor.git cd rekor echo "starting services"