diff --git a/go.mod b/go.mod index cc95f887..936759b7 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/google/certificate-transparency-go v1.1.8 github.com/in-toto/in-toto-golang v0.9.0 github.com/secure-systems-lab/go-securesystemslib v0.8.0 - github.com/sigstore/protobuf-specs v0.2.1 + github.com/sigstore/protobuf-specs v0.3.0 github.com/sigstore/rekor v1.3.5 github.com/sigstore/sigstore v1.8.2 github.com/sigstore/timestamp-authority v1.2.2 diff --git a/go.sum b/go.sum index 3100f05d..f3115e90 100644 --- a/go.sum +++ b/go.sum @@ -249,8 +249,8 @@ github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI= github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE= -github.com/sigstore/protobuf-specs v0.2.1 h1:KIoM7E3C4uaK092q8YoSj/XSf9720f8dlsbYwwOmgEA= -github.com/sigstore/protobuf-specs v0.2.1/go.mod h1:xPqQGnH/HllKuZ4VFPz/g+78epWM/NLRGl7Fuy45UdE= +github.com/sigstore/protobuf-specs v0.3.0 h1:E49qS++llp4psM+3NNVEb+C4AD422bT9VkOQIPrNLpA= +github.com/sigstore/protobuf-specs v0.3.0/go.mod h1:ynKzXpqr3dUj2Xk9O/5ZUhjnpi0F53DNi5AdH6pS3jc= github.com/sigstore/rekor v1.3.5 h1:QoVXcS7NppKY+rpbEFVHr4evGDZBBSh65X0g8PXoUkQ= github.com/sigstore/rekor v1.3.5/go.mod h1:CWqOk/fmnPwORQmm7SyDgB54GTJizqobbZ7yOP1lvw8= github.com/sigstore/sigstore v1.8.2 h1:0Ttjcn3V0fVQXlYq7+oHaaHkGFIt3ywm7SF4JTU/l8c= diff --git a/pkg/bundle/bundle.go b/pkg/bundle/bundle.go index 0aab8629..bd54575c 100644 --- a/pkg/bundle/bundle.go +++ b/pkg/bundle/bundle.go @@ -35,6 +35,8 @@ import ( const SigstoreBundleMediaType01 = "application/vnd.dev.sigstore.bundle+json;version=0.1" const SigstoreBundleMediaType02 = "application/vnd.dev.sigstore.bundle+json;version=0.2" +const SigstoreBundleMediaType03Legacy = "application/vnd.dev.sigstore.bundle+json;version=0.3" +const SigstoreBundleMediaType03 = "application/vnd.dev.sigstore.bundle.v0.3+json" const IntotoMediaType = "application/vnd.in-toto+json" var ErrValidation = errors.New("validation error") @@ -86,6 +88,12 @@ func (b *ProtobufBundle) validate() error { if len(entries) > 0 && !b.hasInclusionProof { return errors.New("inclusion proof missing in bundle (required for bundle v0.2)") } + case SigstoreBundleMediaType03, SigstoreBundleMediaType03Legacy: + certs := b.Bundle.VerificationMaterial.GetX509CertificateChain() + + if certs != nil { + return errors.New("verification material cannot be X.509 certificate chain (for bundle v0.3)") + } default: return ErrIncorrectMediaType } @@ -137,21 +145,26 @@ func (b *ProtobufBundle) VerificationContent() (verify.VerificationContent, erro switch content := b.VerificationMaterial.GetContent().(type) { case *protobundle.VerificationMaterial_X509CertificateChain: certs := content.X509CertificateChain.GetCertificates() - certificates := make([]*x509.Certificate, len(certs)) - var err error - for i, cert := range content.X509CertificateChain.GetCertificates() { - certificates[i], err = x509.ParseCertificate(cert.RawBytes) - if err != nil { - return nil, ErrValidationError(err) - } - } - if len(certificates) == 0 { + if len(certs) == 0 { return nil, ErrMissingVerificationMaterial } - certChain := &CertificateChain{ - Certificates: certificates, + parsedCert, err := x509.ParseCertificate(certs[0].RawBytes) + if err != nil { + return nil, ErrValidationError(err) + } + cert := &Certificate{ + Certificate: parsedCert, + } + return cert, nil + case *protobundle.VerificationMaterial_Certificate: + parsedCert, err := x509.ParseCertificate(content.Certificate.RawBytes) + if err != nil { + return nil, ErrValidationError(err) + } + cert := &Certificate{ + Certificate: parsedCert, } - return certChain, nil + return cert, nil case *protobundle.VerificationMaterial_PublicKey: pk := &PublicKey{ hint: content.PublicKey.Hint, diff --git a/pkg/bundle/verification_content.go b/pkg/bundle/verification_content.go index 8982ccf0..8e41e791 100644 --- a/pkg/bundle/verification_content.go +++ b/pkg/bundle/verification_content.go @@ -23,8 +23,8 @@ import ( "github.com/sigstore/sigstore-go/pkg/verify" ) -type CertificateChain struct { - Certificates []*x509.Certificate +type Certificate struct { + *x509.Certificate } type PublicKey struct { @@ -35,35 +35,27 @@ func (pk PublicKey) Hint() string { return pk.hint } -func (cc *CertificateChain) CompareKey(key any, _ root.TrustedMaterial) bool { +func (c *Certificate) CompareKey(key any, _ root.TrustedMaterial) bool { x509Key, ok := key.(*x509.Certificate) if !ok { return false } - return cc.Certificates[0].Equal(x509Key) + return c.Certificate.Equal(x509Key) } -func (cc *CertificateChain) ValidAtTime(t time.Time, _ root.TrustedMaterial) bool { - return !(cc.Certificates[0].NotAfter.Before(t) || cc.Certificates[0].NotBefore.After(t)) +func (c *Certificate) ValidAtTime(t time.Time, _ root.TrustedMaterial) bool { + return !(c.Certificate.NotAfter.Before(t) || c.Certificate.NotBefore.After(t)) } -func (cc *CertificateChain) HasCertificate() (x509.Certificate, bool) { - return *cc.Certificates[0], true +func (c *Certificate) HasCertificate() (x509.Certificate, bool) { + return *c.Certificate, true } -func (pk *PublicKey) HasCertificate() (x509.Certificate, bool) { - return x509.Certificate{}, false -} - -func (cc *CertificateChain) HasPublicKey() (verify.PublicKeyProvider, bool) { +func (c *Certificate) HasPublicKey() (verify.PublicKeyProvider, bool) { return PublicKey{}, false } -func (pk *PublicKey) HasPublicKey() (verify.PublicKeyProvider, bool) { - return *pk, true -} - func (pk *PublicKey) CompareKey(key any, tm root.TrustedMaterial) bool { verifier, err := tm.PublicKeyVerifier(pk.hint) if err != nil { @@ -86,3 +78,11 @@ func (pk *PublicKey) ValidAtTime(t time.Time, tm root.TrustedMaterial) bool { } return verifier.ValidAtTime(t) } + +func (pk *PublicKey) HasCertificate() (x509.Certificate, bool) { + return x509.Certificate{}, false +} + +func (pk *PublicKey) HasPublicKey() (verify.PublicKeyProvider, bool) { + return *pk, true +} diff --git a/pkg/root/trusted_root.go b/pkg/root/trusted_root.go index 28d161d7..3101d1f6 100644 --- a/pkg/root/trusted_root.go +++ b/pkg/root/trusted_root.go @@ -154,7 +154,8 @@ func ParseTransparencyLogs(tlogs []*prototrustroot.TransparencyLogInstance) (tra PublicKey: ecKey, SignatureHashFunc: crypto.SHA256, } - case protocommon.PublicKeyDetails_PKCS1_RSA_PKCS1V5: + // This key format is deprecated, but currently in use for Sigstore staging instance + case protocommon.PublicKeyDetails_PKCS1_RSA_PKCS1V5: //nolint:staticcheck key, err := x509.ParsePKCS1PublicKey(tlog.GetPublicKey().GetRawBytes()) if err != nil { return nil, err diff --git a/pkg/testing/ca/ca.go b/pkg/testing/ca/ca.go index e592f1a1..ee1e4cfe 100644 --- a/pkg/testing/ca/ca.go +++ b/pkg/testing/ca/ca.go @@ -477,7 +477,7 @@ type TestEntity struct { } func (e *TestEntity) VerificationContent() (verify.VerificationContent, error) { - return &bundle.CertificateChain{Certificates: e.certChain}, nil + return &bundle.Certificate{Certificate: e.certChain[0]}, nil } func (e *TestEntity) HasInclusionPromise() bool {