Skip to content

Commit ae1382e

Browse files
committed
Used ED25519ph algorithm with sign/verify commands
Signed-off-by: Riccardo Schirone <riccardo.schirone@trailofbits.com>
1 parent 95dff84 commit ae1382e

File tree

5 files changed

+75
-38
lines changed

5 files changed

+75
-38
lines changed

cmd/cosign/cli/sign/sign.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ func SignCmd(ro *options.RootOptions, ko options.KeyOpts, signOpts options.SignO
138138
ctx, cancel := context.WithTimeout(context.Background(), ro.Timeout)
139139
defer cancel()
140140

141-
sv, err := SignerFromKeyOpts(ctx, signOpts.Cert, signOpts.CertChain, ko)
141+
sv, err := signerFromKeyOptsWithSVOpts(ctx, "", "", ko, signature.WithED25519ph())
142142
if err != nil {
143143
return fmt.Errorf("getting signer: %w", err)
144144
}
@@ -261,7 +261,12 @@ func signDigest(ctx context.Context, digest name.Digest, payload []byte, ko opti
261261
if err != nil {
262262
return err
263263
}
264-
s = irekor.NewSigner(s, rClient)
264+
265+
hashAlgorithm, err := getHashAlgorithmFromSignerVerifier(sv)
266+
if err != nil {
267+
return err
268+
}
269+
s = irekor.NewSigner(s, rClient, hashAlgorithm)
265270
}
266271

267272
ociSig, _, err := s.Sign(ctx, bytes.NewReader(payload))

cmd/cosign/cli/verify/verify.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ func (c *VerifyCommand) Exec(ctx context.Context, images []string) (err error) {
218218
var pubKey signature.Verifier
219219
switch {
220220
case keyRef != "":
221-
pubKey, err = sigs.PublicKeyFromKeyRefWithHashAlgo(ctx, keyRef, c.HashAlgorithm)
221+
pubKey, err = sigs.PublicKeyFromKeyRefWithOpts(ctx, keyRef, c.HashAlgorithm, signature.WithED25519ph())
222222
if err != nil {
223223
return fmt.Errorf("loading public key: %w", err)
224224
}
@@ -251,7 +251,7 @@ func (c *VerifyCommand) Exec(ctx context.Context, images []string) (err error) {
251251
if err != nil {
252252
return fmt.Errorf("getting Fulcio intermediates: %w", err)
253253
}
254-
pubKey, err = cosign.ValidateAndUnpackCert(cert, co)
254+
pubKey, err = cosign.ValidateAndUnpackCertWithOpts(cert, co, cosign.WithSignerVerifierOptions(signature.WithED25519ph()))
255255
if err != nil {
256256
return err
257257
}
@@ -261,7 +261,7 @@ func (c *VerifyCommand) Exec(ctx context.Context, images []string) (err error) {
261261
if err != nil {
262262
return err
263263
}
264-
pubKey, err = cosign.ValidateAndUnpackCertWithChain(cert, chain, co)
264+
pubKey, err = cosign.ValidateAndUnpackCertWithOpts(cert, co, cosign.WithChain(chain), cosign.WithSignerVerifierOptions(signature.WithED25519ph()))
265265
if err != nil {
266266
return err
267267
}

internal/pkg/cosign/rekor/signer.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ package rekor
1717
import (
1818
"context"
1919
"crypto"
20-
"crypto/sha256"
2120
"encoding/base64"
2221
"fmt"
2322
"io"
@@ -49,7 +48,8 @@ func uploadToTlog(rekorBytes []byte, rClient *client.Rekor, upload tlogUploadFn)
4948
type signerWrapper struct {
5049
inner cosign.Signer
5150

52-
rClient *client.Rekor
51+
rClient *client.Rekor
52+
hashAlgorithm crypto.Hash
5353
}
5454

5555
var _ cosign.Signer = (*signerWrapper)(nil)
@@ -91,11 +91,11 @@ func (rs *signerWrapper) Sign(ctx context.Context, payload io.Reader) (oci.Signa
9191
}
9292

9393
bundle, err := uploadToTlog(rekorBytes, rs.rClient, func(r *client.Rekor, b []byte) (*models.LogEntryAnon, error) {
94-
checkSum := sha256.New()
94+
checkSum := cosignv1.NewCryptoNamedHash(rs.hashAlgorithm)
9595
if _, err := checkSum.Write(payloadBytes); err != nil {
9696
return nil, err
9797
}
98-
return cosignv1.TLogUpload(ctx, r, sigBytes, checkSum, b)
98+
return cosignv1.TLogUploadWithCustomHash(ctx, r, sigBytes, checkSum, b)
9999
})
100100
if err != nil {
101101
return nil, nil, err
@@ -110,9 +110,10 @@ func (rs *signerWrapper) Sign(ctx context.Context, payload io.Reader) (oci.Signa
110110
}
111111

112112
// NewSigner returns a `cosign.Signer` which uploads the signature to Rekor
113-
func NewSigner(inner cosign.Signer, rClient *client.Rekor) cosign.Signer {
113+
func NewSigner(inner cosign.Signer, rClient *client.Rekor, hashAlgorithm crypto.Hash) cosign.Signer {
114114
return &signerWrapper{
115-
inner: inner,
116-
rClient: rClient,
115+
inner: inner,
116+
rClient: rClient,
117+
hashAlgorithm: hashAlgorithm,
117118
}
118119
}

internal/pkg/cosign/rekor/signer_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func TestSigner(t *testing.T) {
5656
}}},
5757
}
5858

59-
testSigner := NewSigner(payloadSigner, &mClient)
59+
testSigner := NewSigner(payloadSigner, &mClient, crypto.SHA256)
6060

6161
testPayload := "test payload"
6262

pkg/cosign/verify.go

Lines changed: 56 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,33 @@ type CheckOpts struct {
165165
ExperimentalOCI11 bool
166166
}
167167

168+
type validateCertOpts struct {
169+
chain []*x509.Certificate
170+
svOpts []signature.SignerVerifierOption
171+
}
172+
173+
type ValidateAndUnpackCertOption func(*validateCertOpts)
174+
175+
func WithChain(chain []*x509.Certificate) ValidateAndUnpackCertOption {
176+
return func(o *validateCertOpts) {
177+
o.chain = chain
178+
}
179+
}
180+
181+
func WithSignerVerifierOptions(svOpts ...signature.SignerVerifierOption) ValidateAndUnpackCertOption {
182+
return func(o *validateCertOpts) {
183+
o.svOpts = svOpts
184+
}
185+
}
186+
187+
func makeValidateAndUnpackCertOpts(opts ...ValidateAndUnpackCertOption) *validateCertOpts {
188+
o := &validateCertOpts{}
189+
for _, opt := range opts {
190+
opt(o)
191+
}
192+
return o
193+
}
194+
168195
// This is a substitutable signature verification function that can be used for verifying
169196
// attestations of blobs.
170197
type signatureVerificationFn func(
@@ -223,11 +250,35 @@ func ValidateAndUnpackCert(cert *x509.Certificate, co *CheckOpts) (signature.Ver
223250
return ValidateAndUnpackCertWithOpts(cert, co)
224251
}
225252

253+
// ValidateAndUnpackCertWithChain creates a Verifier from a certificate. Verifies that the certificate
254+
// chains up to the provided root. Chain should start with the parent of the certificate and end with the root.
255+
// Optionally verifies the subject and issuer of the certificate.
256+
func ValidateAndUnpackCertWithChain(cert *x509.Certificate, chain []*x509.Certificate, co *CheckOpts) (signature.Verifier, error) {
257+
return ValidateAndUnpackCertWithOpts(cert, co, WithChain(chain))
258+
}
259+
226260
// ValidateAndUnpackCertWithOpts creates a Verifier from a certificate. Verifies that the certificate
227261
// chains up to a trusted root. Optionally verifies the subject and issuer of the certificate.
228-
// Accept SignerVerifier options to customize the verifier.
229-
func ValidateAndUnpackCertWithOpts(cert *x509.Certificate, co *CheckOpts, svOpts ...signature.SignerVerifierOption) (signature.Verifier, error) {
230-
verifier, err := signature.LoadVerifierWithOpts(cert.PublicKey, crypto.SHA256, svOpts...)
262+
// Accept chain and signerVerifierOptions as optional parameters.
263+
func ValidateAndUnpackCertWithOpts(cert *x509.Certificate, co *CheckOpts, opts ...ValidateAndUnpackCertOption) (signature.Verifier, error) {
264+
o := makeValidateAndUnpackCertOpts(opts...)
265+
266+
if o.chain != nil {
267+
if len(o.chain) == 0 {
268+
return nil, errors.New("no chain provided to validate certificate")
269+
}
270+
rootPool := x509.NewCertPool()
271+
rootPool.AddCert(o.chain[len(o.chain)-1])
272+
co.RootCerts = rootPool
273+
274+
subPool := x509.NewCertPool()
275+
for _, c := range o.chain[:len(o.chain)-1] {
276+
subPool.AddCert(c)
277+
}
278+
co.IntermediateCerts = subPool
279+
}
280+
281+
verifier, err := signature.LoadVerifierWithOpts(cert.PublicKey, crypto.SHA256, o.svOpts...)
231282
if err != nil {
232283
return nil, fmt.Errorf("invalid certificate found on signature: %w", err)
233284
}
@@ -411,26 +462,6 @@ func validateCertExtensions(ce CertExtensions, co *CheckOpts) error {
411462
return nil
412463
}
413464

414-
// ValidateAndUnpackCertWithChain creates a Verifier from a certificate. Verifies that the certificate
415-
// chains up to the provided root. Chain should start with the parent of the certificate and end with the root.
416-
// Optionally verifies the subject and issuer of the certificate.
417-
func ValidateAndUnpackCertWithChain(cert *x509.Certificate, chain []*x509.Certificate, co *CheckOpts) (signature.Verifier, error) {
418-
if len(chain) == 0 {
419-
return nil, errors.New("no chain provided to validate certificate")
420-
}
421-
rootPool := x509.NewCertPool()
422-
rootPool.AddCert(chain[len(chain)-1])
423-
co.RootCerts = rootPool
424-
425-
subPool := x509.NewCertPool()
426-
for _, c := range chain[:len(chain)-1] {
427-
subPool.AddCert(c)
428-
}
429-
co.IntermediateCerts = subPool
430-
431-
return ValidateAndUnpackCert(cert, co)
432-
}
433-
434465
func tlogValidateEntry(ctx context.Context, client *client.Rekor, rekorPubKeys *TrustedTransparencyLogPubKeys,
435466
sig oci.Signature, pem []byte) (*models.LogEntryAnon, error) {
436467
b64sig, err := sig.Base64Signature()
@@ -741,7 +772,7 @@ func verifyInternal(ctx context.Context, sig oci.Signature, h v1.Hash,
741772
co.IntermediateCerts = pool
742773
}
743774
}
744-
verifier, err = ValidateAndUnpackCertWithOpts(cert, co, svOpts...)
775+
verifier, err = ValidateAndUnpackCertWithOpts(cert, co, WithSignerVerifierOptions(svOpts...))
745776
if err != nil {
746777
return false, err
747778
}
@@ -824,7 +855,7 @@ func VerifyBlobSignature(ctx context.Context, sig oci.Signature, co *CheckOpts)
824855

825856
// VerifyImageSignature verifies a signature
826857
func VerifyImageSignature(ctx context.Context, sig oci.Signature, h v1.Hash, co *CheckOpts) (bundleVerified bool, err error) {
827-
return verifyInternal(ctx, sig, h, verifyOCISignature, co)
858+
return verifyInternal(ctx, sig, h, verifyOCISignature, co, signature.WithED25519ph())
828859
}
829860

830861
func loadSignatureFromFile(ctx context.Context, sigRef string, signedImgRef name.Reference, co *CheckOpts) (oci.Signatures, error) {

0 commit comments

Comments
 (0)