Skip to content

Commit d2f8dc1

Browse files
authored
Use default Verifier for the public key contained in a certificate (closes #74) (#424)
* pkg/verify: load default Verifier given a public key Signed-off-by: Riccardo Schirone <[email protected]> * REMOVE ME: update protobuf-specs/sigstore to trails Signed-off-by: Riccardo Schirone <[email protected]> * pkg/verify: try to verify some key types with multiple algos Signed-off-by: Riccardo Schirone <[email protected]> * REMOVE ME: update to trail repos Signed-off-by: Riccardo Schirone <[email protected]> * REMOVE ME: update to trail repos 2 Signed-off-by: Riccardo Schirone <[email protected]> * REMOVE ME: update to trail repos 3 Signed-off-by: Riccardo Schirone <[email protected]> * pkg/verify: fix lint Signed-off-by: Riccardo Schirone <[email protected]> * allow to enable/disable fallback verifications Signed-off-by: Riccardo Schirone <[email protected]> * fix lint Signed-off-by: Riccardo Schirone <[email protected]> * perform the version check in sigstore-go Signed-off-by: Riccardo Schirone <[email protected]> * fix lint Signed-off-by: Riccardo Schirone <[email protected]> * pkg/verify: make sure to support 0.1/0.2/0.3 Signed-off-by: Riccardo Schirone <[email protected]> * update deps Signed-off-by: Riccardo Schirone <[email protected]> * rename NewVirtualSigstoreCustom Signed-off-by: Riccardo Schirone <[email protected]> * pkg/bundle: fix linting Signed-off-by: Riccardo Schirone <[email protected]> * Use ed25519ph when hashedrekord, ed25519 for dsse Signed-off-by: Riccardo Schirone <[email protected]> --------- Signed-off-by: Riccardo Schirone <[email protected]>
1 parent 3838ecd commit d2f8dc1

File tree

7 files changed

+355
-39
lines changed

7 files changed

+355
-39
lines changed

pkg/bundle/bundle.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func NewProtobufBundle(b *protobundle.Bundle) (*ProtobufBundle, error) {
8080
}
8181

8282
func (b *Bundle) validate() error {
83-
bundleVersion, err := getBundleVersion(b.MediaType)
83+
bundleVersion, err := b.Version()
8484
if err != nil {
8585
return fmt.Errorf("error getting bundle version: %w", err)
8686
}
@@ -152,6 +152,10 @@ func MediaTypeString(version string) (string, error) {
152152
return mtString, nil
153153
}
154154

155+
func (b *Bundle) Version() (string, error) {
156+
return getBundleVersion(b.MediaType)
157+
}
158+
155159
func getBundleVersion(mediaType string) (string, error) {
156160
switch mediaType {
157161
case mediaTypeBase + "+json;version=0.1":
@@ -369,7 +373,7 @@ func (b *Bundle) Timestamps() ([][]byte, error) {
369373

370374
// MinVersion returns true if the bundle version is greater than or equal to the expected version.
371375
func (b *Bundle) MinVersion(expectVersion string) bool {
372-
version, err := getBundleVersion(b.MediaType)
376+
version, err := b.Version()
373377
if err != nil {
374378
return false
375379
}

pkg/sign/transparency_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func (m *mockRekor) CreateLogEntry(_ *entries.CreateLogEntryParams, _ ...entries
4747
return nil, err
4848
}
4949

50-
signer, err := signature.LoadECDSASignerVerifier(leafPrivKey, crypto.SHA256)
50+
signer, err := signature.LoadSignerVerifier(leafPrivKey, crypto.SHA256)
5151
if err != nil {
5252
return nil, err
5353
}

pkg/testing/ca/ca.go

+88-24
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"crypto/ecdsa"
2222
"crypto/elliptic"
2323
"crypto/rand"
24+
"crypto/rsa"
2425
"crypto/sha256"
2526
"crypto/x509"
2627
"crypto/x509/pkix"
@@ -38,6 +39,7 @@ import (
3839
"github.com/go-openapi/runtime"
3940
"github.com/go-openapi/swag"
4041
"github.com/secure-systems-lab/go-securesystemslib/dsse"
42+
v1 "github.com/sigstore/protobuf-specs/gen/pb-go/common/v1"
4143
"github.com/sigstore/rekor/pkg/generated/models"
4244
"github.com/sigstore/rekor/pkg/pki"
4345
"github.com/sigstore/rekor/pkg/types"
@@ -56,16 +58,17 @@ import (
5658
)
5759

5860
type VirtualSigstore struct {
59-
fulcioCA *root.FulcioCertificateAuthority
60-
fulcioIntermediateKey *ecdsa.PrivateKey
61-
tsaCA *root.SigstoreTimestampingAuthority
62-
tsaLeafKey *ecdsa.PrivateKey
63-
rekorKey *ecdsa.PrivateKey
64-
ctlogKey *ecdsa.PrivateKey
65-
publicKeyVerifier map[string]root.TimeConstrainedVerifier
61+
fulcioCA *root.FulcioCertificateAuthority
62+
fulcioIntermediateKey *ecdsa.PrivateKey
63+
tsaCA *root.SigstoreTimestampingAuthority
64+
tsaLeafKey *ecdsa.PrivateKey
65+
rekorKey *ecdsa.PrivateKey
66+
ctlogKey *ecdsa.PrivateKey
67+
publicKeyVerifier map[string]root.TimeConstrainedVerifier
68+
signingAlgorithmDetails signature.AlgorithmDetails
6669
}
6770

68-
func NewVirtualSigstore() (*VirtualSigstore, error) {
71+
func NewVirtualSigstoreWithSigningAlg(signingKeyDetails v1.PublicKeyDetails) (*VirtualSigstore, error) {
6972
ss := &VirtualSigstore{fulcioCA: &root.FulcioCertificateAuthority{}, tsaCA: &root.SigstoreTimestampingAuthority{}}
7073

7174
rootCert, rootKey, err := GenerateRootCa()
@@ -109,10 +112,18 @@ func NewVirtualSigstore() (*VirtualSigstore, error) {
109112
if err != nil {
110113
return nil, err
111114
}
115+
ss.signingAlgorithmDetails, err = signature.GetAlgorithmDetails(signingKeyDetails)
116+
if err != nil {
117+
return nil, err
118+
}
112119

113120
return ss, nil
114121
}
115122

123+
func NewVirtualSigstore() (*VirtualSigstore, error) {
124+
return NewVirtualSigstoreWithSigningAlg(v1.PublicKeyDetails_PKIX_ECDSA_P256_SHA_256)
125+
}
126+
116127
// getLogID calculates the digest of a PKIX-encoded public key
117128
func getLogID(pub crypto.PublicKey) (string, error) {
118129
pubBytes, err := x509.MarshalPKIXPublicKey(pub)
@@ -147,8 +158,25 @@ func (ca *VirtualSigstore) RekorSignPayload(payload tlog.RekorPayload) ([]byte,
147158
return bundleSig, nil
148159
}
149160

150-
func (ca *VirtualSigstore) GenerateLeafCert(identity, issuer string) (*x509.Certificate, *ecdsa.PrivateKey, error) {
151-
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
161+
func (ca *VirtualSigstore) GenerateLeafCert(identity, issuer string) (*x509.Certificate, crypto.PrivateKey, error) {
162+
var privKey crypto.PrivateKey
163+
var err error
164+
switch ca.signingAlgorithmDetails.GetKeyType() {
165+
case signature.ECDSA:
166+
var curve *elliptic.Curve
167+
curve, err = ca.signingAlgorithmDetails.GetECDSACurve()
168+
if err != nil {
169+
return nil, nil, err
170+
}
171+
privKey, err = ecdsa.GenerateKey(*curve, rand.Reader)
172+
case signature.RSA:
173+
var keySize signature.RSAKeySize
174+
keySize, err = ca.signingAlgorithmDetails.GetRSAKeySize()
175+
if err != nil {
176+
return nil, nil, err
177+
}
178+
privKey, err = rsa.GenerateKey(rand.Reader, int(keySize))
179+
}
152180
if err != nil {
153181
return nil, nil, err
154182
}
@@ -171,7 +199,7 @@ func (ca *VirtualSigstore) AttestAtTime(identity, issuer string, envelopeBody []
171199
return nil, err
172200
}
173201

174-
signer, err := signature.LoadECDSASignerVerifier(leafPrivKey, crypto.SHA256)
202+
signer, err := signature.LoadSignerFromAlgorithmDetails(leafPrivKey, ca.signingAlgorithmDetails)
175203
if err != nil {
176204
return nil, err
177205
}
@@ -213,21 +241,42 @@ func (ca *VirtualSigstore) AttestAtTime(identity, issuer string, envelopeBody []
213241
}
214242

215243
func (ca *VirtualSigstore) Sign(identity, issuer string, artifact []byte) (*TestEntity, error) {
216-
return ca.SignAtTime(identity, issuer, artifact, time.Now().Add(5*time.Minute))
244+
return ca.SignAtTimeWithVersion(identity, issuer, artifact, time.Now().Add(5*time.Minute), "v0.3")
245+
}
246+
247+
func (ca *VirtualSigstore) SignWithVersion(identity, issuer string, artifact []byte, version string) (*TestEntity, error) {
248+
return ca.SignAtTimeWithVersion(identity, issuer, artifact, time.Now().Add(5*time.Minute), version)
217249
}
218250

219251
func (ca *VirtualSigstore) SignAtTime(identity, issuer string, artifact []byte, integratedTime time.Time) (*TestEntity, error) {
252+
return ca.SignAtTimeWithVersion(identity, issuer, artifact, integratedTime, "v0.3")
253+
}
254+
255+
func (ca *VirtualSigstore) SignAtTimeWithVersion(identity, issuer string, artifact []byte, integratedTime time.Time, version string) (*TestEntity, error) {
220256
leafCert, leafPrivKey, err := ca.GenerateLeafCert(identity, issuer)
221257
if err != nil {
222258
return nil, err
223259
}
224260

225-
signer, err := signature.LoadECDSASignerVerifier(leafPrivKey, crypto.SHA256)
261+
signer, err := signature.LoadSignerFromAlgorithmDetails(leafPrivKey, ca.signingAlgorithmDetails)
226262
if err != nil {
227263
return nil, err
228264
}
229265

230-
digest := sha256.Sum256(artifact)
266+
hashType := ca.signingAlgorithmDetails.GetHashType()
267+
hasher := hashType.New()
268+
hasher.Write(artifact)
269+
digest := hasher.Sum(nil)
270+
271+
var digestString string
272+
switch hashType {
273+
case crypto.SHA256:
274+
digestString = "SHA2_256"
275+
case crypto.SHA384:
276+
digestString = "SHA2_384"
277+
case crypto.SHA512:
278+
digestString = "SHA2_512"
279+
}
231280
sig, err := signer.SignMessage(bytes.NewReader(artifact))
232281
if err != nil {
233282
return nil, err
@@ -246,8 +295,9 @@ func (ca *VirtualSigstore) SignAtTime(identity, issuer string, artifact []byte,
246295
return &TestEntity{
247296
certChain: []*x509.Certificate{leafCert, ca.fulcioCA.Intermediates[0], ca.fulcioCA.Root},
248297
timestamps: [][]byte{tsr},
249-
messageSignature: bundle.NewMessageSignature(digest[:], "SHA2_256", sig),
298+
messageSignature: bundle.NewMessageSignature(digest, digestString, sig),
250299
tlogEntries: []*tlog.Entry{entry},
300+
version: version,
251301
}, nil
252302
}
253303

@@ -262,7 +312,7 @@ func (ca *VirtualSigstore) GenerateTlogEntry(leafCert *x509.Certificate, envelop
262312
return nil, err
263313
}
264314

265-
rekorBody, err := generateRekorEntry(intoto.KIND, intoto.New().DefaultVersion(), envelopeBytes, leafCertPem, sig)
315+
rekorBody, err := generateRekorEntry(intoto.KIND, intoto.New().DefaultVersion(), envelopeBytes, leafCertPem, sig, ca.signingAlgorithmDetails)
266316
if err != nil {
267317
return nil, err
268318
}
@@ -327,7 +377,7 @@ func (ca *VirtualSigstore) generateTlogEntryHashedRekord(leafCert *x509.Certific
327377
return nil, err
328378
}
329379

330-
rekorBody, err := generateRekorEntry(hashedrekord.KIND, hashedrekord.New().DefaultVersion(), artifact, leafCertPem, sig)
380+
rekorBody, err := generateRekorEntry(hashedrekord.KIND, hashedrekord.New().DefaultVersion(), artifact, leafCertPem, sig, ca.signingAlgorithmDetails)
331381
if err != nil {
332382
return nil, err
333383
}
@@ -366,9 +416,9 @@ func (ca *VirtualSigstore) PublicKeyVerifier(keyID string) (root.TimeConstrained
366416
return v, nil
367417
}
368418

369-
func generateRekorEntry(kind, version string, artifact []byte, cert []byte, sig []byte) (string, error) {
419+
func generateRekorEntry(kind, version string, artifact []byte, cert []byte, sig []byte, algorithmDetails signature.AlgorithmDetails) (string, error) {
370420
// Generate the Rekor Entry
371-
entryImpl, err := createEntry(context.Background(), kind, version, artifact, cert, sig)
421+
entryImpl, err := createEntry(context.Background(), kind, version, artifact, cert, sig, algorithmDetails)
372422
if err != nil {
373423
return "", err
374424
}
@@ -379,7 +429,7 @@ func generateRekorEntry(kind, version string, artifact []byte, cert []byte, sig
379429
return base64.StdEncoding.EncodeToString(entryBytes), nil
380430
}
381431

382-
func createEntry(ctx context.Context, kind, apiVersion string, blobBytes, certBytes, sigBytes []byte) (types.EntryImpl, error) {
432+
func createEntry(ctx context.Context, kind, apiVersion string, blobBytes, certBytes, sigBytes []byte, algorithmDetails signature.AlgorithmDetails) (types.EntryImpl, error) {
383433
props := types.ArtifactProperties{
384434
PublicKeyBytes: [][]byte{certBytes},
385435
PKIFormat: string(pki.X509),
@@ -389,8 +439,12 @@ func createEntry(ctx context.Context, kind, apiVersion string, blobBytes, certBy
389439
props.ArtifactBytes = blobBytes
390440
props.SignatureBytes = sigBytes
391441
case hashedrekord.KIND:
392-
blobHash := sha256.Sum256(blobBytes)
393-
props.ArtifactHash = strings.ToLower(hex.EncodeToString(blobHash[:]))
442+
hashType := algorithmDetails.GetHashType()
443+
hasher := hashType.New()
444+
hasher.Write(blobBytes)
445+
blobHash := hasher.Sum(nil)
446+
447+
props.ArtifactHash = strings.ToLower(hex.EncodeToString(blobHash))
394448
props.SignatureBytes = sigBytes
395449
default:
396450
return nil, fmt.Errorf("unexpected entry kind: %s", kind)
@@ -513,6 +567,7 @@ type TestEntity struct {
513567
messageSignature *bundle.MessageSignature
514568
timestamps [][]byte
515569
tlogEntries []*tlog.Entry
570+
version string
516571
}
517572

518573
func (e *TestEntity) VerificationContent() (verify.VerificationContent, error) {
@@ -523,6 +578,10 @@ func (e *TestEntity) HasInclusionPromise() bool {
523578
return true
524579
}
525580

581+
func (e *TestEntity) Version() (string, error) {
582+
return e.version, nil
583+
}
584+
526585
func (e *TestEntity) HasInclusionProof() bool {
527586
for _, tlog := range e.tlogEntries {
528587
if tlog.HasInclusionProof() {
@@ -645,7 +704,7 @@ func GenerateTSAIntermediate(rootTemplate *x509.Certificate, rootPriv crypto.Sig
645704
return cert, priv, nil
646705
}
647706

648-
func GenerateLeafCert(subject string, oidcIssuer string, expiration time.Time, priv *ecdsa.PrivateKey,
707+
func GenerateLeafCert(subject string, oidcIssuer string, expiration time.Time, priv crypto.PrivateKey,
649708
parentTemplate *x509.Certificate, parentPriv crypto.Signer) (*x509.Certificate, error) {
650709
certTemplate := &x509.Certificate{
651710
SerialNumber: big.NewInt(1),
@@ -664,7 +723,12 @@ func GenerateLeafCert(subject string, oidcIssuer string, expiration time.Time, p
664723
},
665724
}
666725

667-
cert, err := createCertificate(certTemplate, parentTemplate, &priv.PublicKey, parentPriv)
726+
signer, ok := priv.(crypto.Signer)
727+
if !ok {
728+
return nil, fmt.Errorf("private key does not implement crypto.Signer")
729+
}
730+
731+
cert, err := createCertificate(certTemplate, parentTemplate, signer.Public(), parentPriv)
668732
if err != nil {
669733
return nil, err
670734
}

pkg/verify/interface.go

+9
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,18 @@ type VerificationProvider interface {
5151
VerificationContent() (VerificationContent, error)
5252
}
5353

54+
type VersionProvider interface {
55+
Version() (string, error)
56+
}
57+
5458
type SignedEntity interface {
5559
HasInclusionPromise
5660
HasInclusionProof
5761
SignatureProvider
5862
SignedTimestampProvider
5963
TlogEntryProvider
6064
VerificationProvider
65+
VersionProvider
6166
}
6267

6368
type VerificationContent interface {
@@ -119,3 +124,7 @@ func (b *BaseSignedEntity) Timestamps() ([][]byte, error) {
119124
func (b *BaseSignedEntity) TlogEntries() ([]*tlog.Entry, error) {
120125
return nil, errNotImplemented
121126
}
127+
128+
func (b *BaseSignedEntity) Version() (string, error) {
129+
return "", errNotImplemented
130+
}

0 commit comments

Comments
 (0)