Skip to content

Commit

Permalink
Include URI for CA verified timestamps
Browse files Browse the repository at this point in the history
Signed-off-by: Colleen Murphy <colleenmurphy@google.com>
  • Loading branch information
cmurphy committed Aug 12, 2024
1 parent d19dc5b commit 21ca238
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 14 deletions.
5 changes: 4 additions & 1 deletion pkg/root/trusted_root.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ type CertificateAuthority struct {
Leaf *x509.Certificate
ValidityPeriodStart time.Time
ValidityPeriodEnd time.Time
URI string
}

type TransparencyLog struct {
Expand Down Expand Up @@ -267,7 +268,9 @@ func ParseCertificateAuthority(certAuthority *prototrustroot.CertificateAuthorit
}
}

// TODO: Should we inspect/enforce ca.Subject and ca.Uri?
certificateAuthority.URI = certAuthority.Uri

// TODO: Should we inspect/enforce ca.Subject?
// TODO: Handle validity period (ca.ValidFor)

return certificateAuthority, nil
Expand Down
4 changes: 2 additions & 2 deletions pkg/verify/signed_entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,7 @@ func (v *SignedEntityVerifier) VerifyObserverTimestamps(entity SignedEntity, log
return nil, err
}
for _, vts := range verifiedSignedTimestamps {
verifiedTimestamps = append(verifiedTimestamps, TimestampVerificationResult{Type: "TimestampAuthority", URI: "TODO", Timestamp: vts})
verifiedTimestamps = append(verifiedTimestamps, TimestampVerificationResult{Type: "TimestampAuthority", URI: vts.URI, Timestamp: vts.Time})
}
}

Expand All @@ -719,7 +719,7 @@ func (v *SignedEntityVerifier) VerifyObserverTimestamps(entity SignedEntity, log
// append all timestamps
verifiedTimestamps = append(verifiedTimestamps, logTimestamps...)
for _, vts := range verifiedSignedTimestamps {
verifiedTimestamps = append(verifiedTimestamps, TimestampVerificationResult{Type: "TimestampAuthority", URI: "TODO", Timestamp: vts})
verifiedTimestamps = append(verifiedTimestamps, TimestampVerificationResult{Type: "TimestampAuthority", URI: vts.URI, Timestamp: vts.Time})
}
}

Expand Down
4 changes: 4 additions & 0 deletions pkg/verify/signed_entity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ func TestEntitySignedByPublicGoodWithTlogVerifiesSuccessfully(t *testing.T) {
assert.NotNil(t, res.Signature.Certificate)
assert.Equal(t, "https://github.com/sigstore/sigstore-js/.github/workflows/release.yml@refs/heads/main", res.Signature.Certificate.SubjectAlternativeName)
assert.NotEmpty(t, res.VerifiedTimestamps)
for _, vts := range res.VerifiedTimestamps[1:] { // TODO: URI for TLog is still "TODO"
assert.NotEmpty(t, vts.Timestamp)
assert.Equal(t, "", vts.URI)
}

// verifies with integrated timestamp threshold too
v, err = verify.NewSignedEntityVerifier(tr, verify.WithTransparencyLog(1), verify.WithIntegratedTimestamps(1))
Expand Down
25 changes: 15 additions & 10 deletions pkg/verify/tsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,14 @@ import (
"github.com/sigstore/sigstore-go/pkg/root"
)

type Timestamp struct {
Time time.Time
URI string
}

// VerifyTimestampAuthority verifies that the given entity has been timestamped
// by a trusted timestamp authority and that the timestamp is valid.
func VerifyTimestampAuthority(entity SignedEntity, trustedMaterial root.TrustedMaterial) ([]time.Time, error) { //nolint:revive
func VerifyTimestampAuthority(entity SignedEntity, trustedMaterial root.TrustedMaterial) ([]Timestamp, error) { //nolint:revive
signedTimestamps, err := entity.Timestamps()
if err != nil {
return nil, err
Expand All @@ -55,7 +60,7 @@ func VerifyTimestampAuthority(entity SignedEntity, trustedMaterial root.TrustedM
return nil, err
}

verifiedTimestamps := []time.Time{}
verifiedTimestamps := []Timestamp{}
for _, timestamp := range signedTimestamps {
verifiedSignedTimestamp, err := verifySignedTimestamp(timestamp, signatureBytes, trustedMaterial, verificationContent)

Expand All @@ -75,7 +80,7 @@ func VerifyTimestampAuthority(entity SignedEntity, trustedMaterial root.TrustedM
//
// The threshold parameter is the number of unique timestamps that must be
// verified.
func VerifyTimestampAuthorityWithThreshold(entity SignedEntity, trustedMaterial root.TrustedMaterial, threshold int) ([]time.Time, error) { //nolint:revive
func VerifyTimestampAuthorityWithThreshold(entity SignedEntity, trustedMaterial root.TrustedMaterial, threshold int) ([]Timestamp, error) { //nolint:revive
verifiedTimestamps, err := VerifyTimestampAuthority(entity, trustedMaterial)
if err != nil {
return nil, err
Expand All @@ -86,7 +91,7 @@ func VerifyTimestampAuthorityWithThreshold(entity SignedEntity, trustedMaterial
return verifiedTimestamps, nil
}

func verifySignedTimestamp(signedTimestamp []byte, dsseSignatureBytes []byte, trustedMaterial root.TrustedMaterial, verificationContent VerificationContent) (time.Time, error) {
func verifySignedTimestamp(signedTimestamp []byte, dsseSignatureBytes []byte, trustedMaterial root.TrustedMaterial, verificationContent VerificationContent) (Timestamp, error) {
certAuthorities := trustedMaterial.TimestampingAuthorities()

// Iterate through TSA certificate authorities to find one that verifies
Expand All @@ -98,27 +103,27 @@ func verifySignedTimestamp(signedTimestamp []byte, dsseSignatureBytes []byte, tr
}

// Ensure timestamp responses are from trusted sources
timestamp, err := tsaverification.VerifyTimestampResponse(signedTimestamp, bytes.NewReader(dsseSignatureBytes), trustedRootVerificationOptions)
stamp, err := tsaverification.VerifyTimestampResponse(signedTimestamp, bytes.NewReader(dsseSignatureBytes), trustedRootVerificationOptions)
if err != nil {
continue
}

if !ca.ValidityPeriodStart.IsZero() && timestamp.Time.Before(ca.ValidityPeriodStart) {
if !ca.ValidityPeriodStart.IsZero() && stamp.Time.Before(ca.ValidityPeriodStart) {
continue
}
if !ca.ValidityPeriodEnd.IsZero() && timestamp.Time.After(ca.ValidityPeriodEnd) {
if !ca.ValidityPeriodEnd.IsZero() && stamp.Time.After(ca.ValidityPeriodEnd) {
continue
}

// Check tlog entry time against bundle certificates
// TODO: technically no longer needed since we check the cert validity period in the main Verify loop
if !verificationContent.ValidAtTime(timestamp.Time, trustedMaterial) {
if !verificationContent.ValidAtTime(stamp.Time, trustedMaterial) {
continue
}

// All above verification successful, so return nil
return timestamp.Time, nil
return Timestamp{Time: stamp.Time, URI: ca.URI}, nil
}

return time.Time{}, errors.New("unable to verify signed timestamps")
return Timestamp{}, errors.New("unable to verify signed timestamps")
}
2 changes: 1 addition & 1 deletion pkg/verify/tsa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func TestTimestampAuthorityVerifierWithoutThreshold(t *testing.T) {
virtualSigstore2, err := ca.NewVirtualSigstore()
assert.NoError(t, err)

var ts []time.Time
var ts []verify.Timestamp

// expect one verified timestamp
ts, err = verify.VerifyTimestampAuthority(entity, virtualSigstore)
Expand Down

0 comments on commit 21ca238

Please sign in to comment.