diff --git a/pkg/bundle/bundle.go b/pkg/bundle/bundle.go index 0aab8629..2dd50cdc 100644 --- a/pkg/bundle/bundle.go +++ b/pkg/bundle/bundle.go @@ -35,6 +35,7 @@ import ( const SigstoreBundleMediaType01 = "application/vnd.dev.sigstore.bundle+json;version=0.1" const SigstoreBundleMediaType02 = "application/vnd.dev.sigstore.bundle+json;version=0.2" +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 +87,11 @@ 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: + cert := b.Bundle.VerificationMaterial.GetCertificate() + if cert == nil { + return errors.New("verification material must be single X.509 certificate (required for bundle v0.3)") + } default: return ErrIncorrectMediaType } @@ -136,22 +142,33 @@ 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) + var parsedCert *x509.Certificate + for i, eachCert := range content.X509CertificateChain.GetCertificates() { + thisCert, err := x509.ParseCertificate(eachCert.RawBytes) if err != nil { return nil, ErrValidationError(err) } + + if i == 0 { + parsedCert = thisCert + } } - if len(certificates) == 0 { + if parsedCert == nil { return nil, ErrMissingVerificationMaterial } - certChain := &CertificateChain{ - Certificates: certificates, + 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/testing/ca/ca.go b/pkg/testing/ca/ca.go index 553e6df3..e920188a 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 {