Skip to content

Commit

Permalink
Add LoadSignerVerifier types/opts for more flexibility
Browse files Browse the repository at this point in the history
  • Loading branch information
ret2libc committed Jan 15, 2024
1 parent 286a98a commit 976d483
Show file tree
Hide file tree
Showing 26 changed files with 195 additions and 173 deletions.
2 changes: 1 addition & 1 deletion cmd/cosign/cli/attest/attest_blob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ func TestAttestBlob(t *testing.T) {
}

// Load a verifier and DSSE verify
verifier, _ := signature.LoadVerifierFromPEMFile(pubKeyRef, crypto.SHA256)
verifier, _ := signature.LoadVerifierFromPEMFile(pubKeyRef, crypto.SHA256, signature.LoadDefaultSV, nil)
dssev, err := ssldsse.NewEnvelopeVerifier(&dsse.VerifierAdapter{SignatureVerifier: verifier})
if err != nil {
t.Fatalf("new envelope verifier: %v", err)
Expand Down
51 changes: 28 additions & 23 deletions cmd/cosign/cli/options/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,36 @@

package options

import "github.com/sigstore/cosign/v2/pkg/cosign"
import (
"github.com/sigstore/cosign/v2/pkg/cosign"
"github.com/sigstore/sigstore/pkg/signature"
)

type KeyOpts struct {
Sk bool
Slot string
KeyRef string
FulcioURL string
RekorURL string
IDToken string
PassFunc cosign.PassFunc
OIDCIssuer string
OIDCClientID string
OIDCClientSecret string
OIDCRedirectURL string
OIDCDisableProviders bool // Disable OIDC credential providers in keyless signer
OIDCProvider string // Specify which OIDC credential provider to use for keyless signer
BundlePath string
SkipConfirmation bool
TSAClientCACert string
TSAClientCert string
TSAClientKey string
TSAServerName string // expected SAN field in the TSA server's certificate - https://pkg.go.dev/crypto/tls#Config.ServerName
TSAServerURL string
RFC3161TimestampPath string
TSACertChainPath string
Sk bool
Slot string
KeyRef string
FulcioURL string
RekorURL string
IDToken string
PassFunc cosign.PassFunc
OIDCIssuer string
OIDCClientID string
OIDCClientSecret string
OIDCRedirectURL string
OIDCDisableProviders bool // Disable OIDC credential providers in keyless signer
OIDCProvider string // Specify which OIDC credential provider to use for keyless signer
LoadSignerVerifierType signature.LoadSignerVerifierType
LoadSignerVerifierOpts *signature.LoadSignerVerifierOpts
BundlePath string
SkipConfirmation bool
TSAClientCACert string
TSAClientCert string
TSAClientKey string
TSAServerName string // expected SAN field in the TSA server's certificate - https://pkg.go.dev/crypto/tls#Config.ServerName
TSAServerURL string
RFC3161TimestampPath string
TSACertChainPath string
// IssueCertificate controls whether to issue a certificate when a key is
// provided.
IssueCertificateForExistingKey bool
Expand Down
2 changes: 1 addition & 1 deletion cmd/cosign/cli/publickey/public_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func GetPublicKey(ctx context.Context, opts Pkopts, writer NamedWriter, pf cosig
var k signature.PublicKeyProvider
switch {
case opts.KeyRef != "":
s, err := sigs.SignerFromKeyRef(ctx, opts.KeyRef, pf)
s, err := sigs.SignerFromKeyRef(ctx, opts.KeyRef, pf, signature.LoadDefaultSV, nil)
if err != nil {
return err
}
Expand Down
6 changes: 3 additions & 3 deletions cmd/cosign/cli/sign/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,8 +391,8 @@ func signerFromSecurityKey(ctx context.Context, keySlot string) (*SignerVerifier
}, nil
}

func signerFromKeyRef(ctx context.Context, certPath, certChainPath, keyRef string, passFunc cosign.PassFunc) (*SignerVerifier, error) {
k, err := sigs.SignerVerifierFromKeyRef(ctx, keyRef, passFunc)
func signerFromKeyRef(ctx context.Context, certPath, certChainPath, keyRef string, passFunc cosign.PassFunc, loadSignerVerifierType signature.LoadSignerVerifierType, loadSignerVerifierOpts *signature.LoadSignerVerifierOpts) (*SignerVerifier, error) {
k, err := sigs.SignerVerifierFromKeyRef(ctx, keyRef, passFunc, loadSignerVerifierType, loadSignerVerifierOpts)
if err != nil {
return nil, fmt.Errorf("reading key: %w", err)
}
Expand Down Expand Up @@ -567,7 +567,7 @@ func SignerFromKeyOpts(ctx context.Context, certPath string, certChainPath strin
case ko.Sk:
sv, err = signerFromSecurityKey(ctx, ko.Slot)
case ko.KeyRef != "":
sv, err = signerFromKeyRef(ctx, certPath, certChainPath, ko.KeyRef, ko.PassFunc)
sv, err = signerFromKeyRef(ctx, certPath, certChainPath, ko.KeyRef, ko.PassFunc, ko.LoadSignerVerifierType, ko.LoadSignerVerifierOpts)
default:
genKey = true
ui.Infof(ctx, "Generating ephemeral keys...")
Expand Down
46 changes: 36 additions & 10 deletions cmd/cosign/cli/sign/sign_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ package sign

import (
"context"
"crypto/sha256"
"crypto"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa"
"encoding/base64"
"encoding/json"
"fmt"
Expand All @@ -36,6 +39,24 @@ import (
signatureoptions "github.com/sigstore/sigstore/pkg/signature/options"
)

func getHashAlgorithmFromSignerVerifier(sv *SignerVerifier) (crypto.Hash, error) {
publicKey, err := sv.SignerVerifier.PublicKey()
if err != nil {
return crypto.Hash(0), err
}

switch publicKey.(type) {
case *ecdsa.PublicKey:
return crypto.SHA256, nil
case *rsa.PublicKey:
return crypto.SHA256, nil
case ed25519.PublicKey:
return crypto.SHA512, nil
default:
return crypto.Hash(0), fmt.Errorf("unsupported public key type")
}
}

// nolint
func SignBlobCmd(ro *options.RootOptions, ko options.KeyOpts, payloadPath string, b64 bool, outputSignature string, outputCertificate string, tlogUpload bool) ([]byte, error) {
var payload internal.HashReader
Expand All @@ -44,26 +65,31 @@ func SignBlobCmd(ro *options.RootOptions, ko options.KeyOpts, payloadPath string
ctx, cancel := context.WithTimeout(context.Background(), ro.Timeout)
defer cancel()

sv, err := SignerFromKeyOpts(ctx, "", "", ko)
if err != nil {
return nil, err
}
defer sv.Close()

hashAlgorithm, err := getHashAlgorithmFromSignerVerifier(sv)
if err != nil {
return nil, err
}

if payloadPath == "-" {
payload = internal.NewHashReader(os.Stdin, sha256.New())
payload = internal.NewHashReader(os.Stdin, hashAlgorithm.New())
} else {
ui.Infof(ctx, "Using payload from: %s", payloadPath)
f, err := os.Open(filepath.Clean(payloadPath))
if err != nil {
return nil, err
}
payload = internal.NewHashReader(f, sha256.New())
payload = internal.NewHashReader(f, hashAlgorithm.New())
}
if err != nil {
return nil, err
}

sv, err := SignerFromKeyOpts(ctx, "", "", ko)
if err != nil {
return nil, err
}
defer sv.Close()

sig, err := sv.SignMessage(&payload, signatureoptions.WithContext(ctx))
if err != nil {
return nil, fmt.Errorf("signing blob: %w", err)
Expand Down Expand Up @@ -123,7 +149,7 @@ func SignBlobCmd(ro *options.RootOptions, ko options.KeyOpts, payloadPath string
if err != nil {
return nil, err
}
entry, err := cosign.TLogUpload(ctx, rekorClient, sig, &payload, rekorBytes)
entry, err := cosign.TLogUpload(ctx, rekorClient, sig, &payload, hashAlgorithm, rekorBytes)
if err != nil {
return nil, err
}
Expand Down
11 changes: 6 additions & 5 deletions cmd/cosign/cli/sign/sign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
"github.com/sigstore/cosign/v2/pkg/cosign"
"github.com/sigstore/cosign/v2/test"
"github.com/sigstore/sigstore/pkg/cryptoutils"
"github.com/sigstore/sigstore/pkg/signature"
)

func pass(s string) cosign.PassFunc {
Expand Down Expand Up @@ -134,7 +135,7 @@ func Test_signerFromKeyRefSuccess(t *testing.T) {
ctx := context.Background()
keyFile, certFile, chainFile, privKey, cert, chain := generateCertificateFiles(t, tmpDir, pass("foo"))

signer, err := signerFromKeyRef(ctx, certFile, chainFile, keyFile, pass("foo"))
signer, err := signerFromKeyRef(ctx, certFile, chainFile, keyFile, pass("foo"), signature.LoadDefaultSV, nil)
if err != nil {
t.Fatalf("unexpected error generating signer: %v", err)
}
Expand Down Expand Up @@ -173,17 +174,17 @@ func Test_signerFromKeyRefFailure(t *testing.T) {
_, certFile2, chainFile2, _, _, _ := generateCertificateFiles(t, tmpDir2, pass("bar"))

// Public keys don't match
_, err := signerFromKeyRef(ctx, certFile2, chainFile2, keyFile, pass("foo"))
_, err := signerFromKeyRef(ctx, certFile2, chainFile2, keyFile, pass("foo"), signature.LoadDefaultSV, nil)
if err == nil || err.Error() != "public key in certificate does not match the provided public key" {
t.Fatalf("expected mismatched keys error, got %v", err)
}
// Certificate chain cannot be verified
_, err = signerFromKeyRef(ctx, certFile, chainFile2, keyFile, pass("foo"))
_, err = signerFromKeyRef(ctx, certFile, chainFile2, keyFile, pass("foo"), signature.LoadDefaultSV, nil)
if err == nil || !strings.Contains(err.Error(), "unable to validate certificate chain") {
t.Fatalf("expected chain verification error, got %v", err)
}
// Certificate chain specified without certificate
_, err = signerFromKeyRef(ctx, "", chainFile2, keyFile, pass("foo"))
_, err = signerFromKeyRef(ctx, "", chainFile2, keyFile, pass("foo"), signature.LoadDefaultSV, nil)
if err == nil || !strings.Contains(err.Error(), "no leaf certificate found or provided while specifying chain") {
t.Fatalf("expected no leaf error, got %v", err)
}
Expand All @@ -203,7 +204,7 @@ func Test_signerFromKeyRefFailureEmptyChainFile(t *testing.T) {
t.Fatalf("failed to write chain file: %v", err)
}

_, err = signerFromKeyRef(ctx, certFile, tmpChainFile.Name(), keyFile, pass("foo"))
_, err = signerFromKeyRef(ctx, certFile, tmpChainFile.Name(), keyFile, pass("foo"), signature.LoadDefaultSV, nil)
if err == nil || err.Error() != "no certificates in certificate chain" {
t.Fatalf("expected empty chain error, got %v", err)
}
Expand Down
3 changes: 3 additions & 0 deletions cmd/cosign/cli/signblob.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/sigstore/cosign/v2/cmd/cosign/cli/generate"
"github.com/sigstore/cosign/v2/cmd/cosign/cli/options"
"github.com/sigstore/cosign/v2/cmd/cosign/cli/sign"
"github.com/sigstore/sigstore/pkg/signature"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
Expand Down Expand Up @@ -76,6 +77,8 @@ func SignBlob() *cobra.Command {
FulcioURL: o.Fulcio.URL,
IDToken: o.Fulcio.IdentityToken,
InsecureSkipFulcioVerify: o.Fulcio.InsecureSkipFulcioVerify,
LoadSignerVerifierType: signature.LoadED25519phSV,
LoadSignerVerifierOpts: nil,
RekorURL: o.Rekor.URL,
OIDCIssuer: o.OIDC.Issuer,
OIDCClientID: o.OIDC.ClientID,
Expand Down
2 changes: 1 addition & 1 deletion cmd/cosign/cli/verify/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ func (c *VerifyCommand) Exec(ctx context.Context, images []string) (err error) {
var pubKey signature.Verifier
switch {
case keyRef != "":
pubKey, err = sigs.PublicKeyFromKeyRefWithHashAlgo(ctx, keyRef, c.HashAlgorithm)
pubKey, err = sigs.PublicKeyFromKeyRefWithHashAlgo(ctx, keyRef, c.HashAlgorithm, signature.LoadED25519phSV, nil)
if err != nil {
return fmt.Errorf("loading public key: %w", err)
}
Expand Down
3 changes: 2 additions & 1 deletion cmd/cosign/cli/verify/verify_attestation.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
"github.com/sigstore/cosign/v2/pkg/oci"
"github.com/sigstore/cosign/v2/pkg/policy"
sigs "github.com/sigstore/cosign/v2/pkg/signature"
"github.com/sigstore/sigstore/pkg/signature"
)

// VerifyAttestationCommand verifies a signature on a supplied container image
Expand Down Expand Up @@ -174,7 +175,7 @@ func (c *VerifyAttestationCommand) Exec(ctx context.Context, images []string) (e
// Keys are optional!
switch {
case keyRef != "":
co.SigVerifier, err = sigs.PublicKeyFromKeyRef(ctx, keyRef)
co.SigVerifier, err = sigs.PublicKeyFromKeyRef(ctx, keyRef, signature.LoadDefaultSV, nil)
if err != nil {
return fmt.Errorf("loading public key: %w", err)
}
Expand Down
5 changes: 3 additions & 2 deletions cmd/cosign/cli/verify/verify_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
sigs "github.com/sigstore/cosign/v2/pkg/signature"

"github.com/sigstore/sigstore/pkg/cryptoutils"
"github.com/sigstore/sigstore/pkg/signature"
)

func isb64(data []byte) bool {
Expand Down Expand Up @@ -173,7 +174,7 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error {
// Keys are optional!
switch {
case c.KeyRef != "":
co.SigVerifier, err = sigs.PublicKeyFromKeyRef(ctx, c.KeyRef)
co.SigVerifier, err = sigs.PublicKeyFromKeyRef(ctx, c.KeyRef, signature.LoadED25519phSV, nil)
if err != nil {
return fmt.Errorf("loading public key: %w", err)
}
Expand Down Expand Up @@ -218,7 +219,7 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error {
bundleCert, err := loadCertFromPEM(certBytes)
if err != nil {
// check if cert is actually a public key
co.SigVerifier, err = sigs.LoadPublicKeyRaw(certBytes, crypto.SHA256)
co.SigVerifier, err = sigs.LoadPublicKeyRaw(certBytes, crypto.SHA256, signature.LoadED25519phSV, nil)
if err != nil {
return fmt.Errorf("loading verifier from bundle: %w", err)
}
Expand Down
5 changes: 3 additions & 2 deletions cmd/cosign/cli/verify/verify_blob_attestation.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import (
"github.com/sigstore/cosign/v2/pkg/policy"
sigs "github.com/sigstore/cosign/v2/pkg/signature"
"github.com/sigstore/sigstore/pkg/cryptoutils"
"github.com/sigstore/sigstore/pkg/signature"
)

// VerifyBlobAttestationCommand verifies an attestation on a supplied blob
Expand Down Expand Up @@ -210,7 +211,7 @@ func (c *VerifyBlobAttestationCommand) Exec(ctx context.Context, artifactPath st
opts := make([]static.Option, 0)
switch {
case c.KeyRef != "":
co.SigVerifier, err = sigs.PublicKeyFromKeyRef(ctx, c.KeyRef)
co.SigVerifier, err = sigs.PublicKeyFromKeyRef(ctx, c.KeyRef, signature.LoadDefaultSV, nil)
if err != nil {
return fmt.Errorf("loading public key: %w", err)
}
Expand Down Expand Up @@ -255,7 +256,7 @@ func (c *VerifyBlobAttestationCommand) Exec(ctx context.Context, artifactPath st
bundleCert, err := loadCertFromPEM(certBytes)
if err != nil {
// check if cert is actually a public key
co.SigVerifier, err = sigs.LoadPublicKeyRaw(certBytes, crypto.SHA256)
co.SigVerifier, err = sigs.LoadPublicKeyRaw(certBytes, crypto.SHA256, signature.LoadDefaultSV, nil)
if err != nil {
return fmt.Errorf("loading verifier from bundle: %w", err)
}
Expand Down
22 changes: 13 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ require (
go.step.sm/crypto v0.40.0
golang.org/x/crypto v0.17.0
golang.org/x/oauth2 v0.15.0
golang.org/x/sync v0.5.0
golang.org/x/sync v0.6.0
golang.org/x/term v0.15.0
google.golang.org/api v0.154.0
k8s.io/api v0.28.3
Expand Down Expand Up @@ -147,17 +147,17 @@ require (
github.com/go-jose/go-jose/v3 v3.0.1 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/analysis v0.21.4 // indirect
github.com/go-openapi/analysis v0.22.0 // indirect
github.com/go-openapi/errors v0.21.0 // indirect
github.com/go-openapi/jsonpointer v0.20.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/loads v0.21.2 // indirect
github.com/go-openapi/spec v0.20.11 // indirect
github.com/go-openapi/validate v0.22.3 // indirect
github.com/go-openapi/jsonpointer v0.20.2 // indirect
github.com/go-openapi/jsonreference v0.20.4 // indirect
github.com/go-openapi/loads v0.21.5 // indirect
github.com/go-openapi/spec v0.20.13 // indirect
github.com/go-openapi/validate v0.22.6 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
github.com/golang-jwt/jwt/v5 v5.1.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
Expand Down Expand Up @@ -210,7 +210,7 @@ require (
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.17.0 // indirect
github.com/prometheus/client_golang v1.18.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
Expand Down Expand Up @@ -276,3 +276,7 @@ require (
sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

replace github.com/sigstore/rekor => github.com/trail-of-forks/rekor v0.0.0-20240112162233-2d93686760f8

replace github.com/sigstore/sigstore => github.com/trail-of-forks/sigstore v0.0.0-20240112143627-ef70c23a75c8
Loading

0 comments on commit 976d483

Please sign in to comment.