From ab65d835fb3cf5214ad22baa8876cc46b03c3deb Mon Sep 17 00:00:00 2001 From: Zach Steindler Date: Thu, 12 Dec 2024 08:23:43 -0500 Subject: [PATCH] Adds a check to ensure SCT time is while a CT log key was valid Fixes #178 (#350) Signed-off-by: Zach Steindler --- pkg/verify/sct.go | 12 ++++++++++++ pkg/verify/sct_test.go | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/pkg/verify/sct.go b/pkg/verify/sct.go index 64e2600..bf447c2 100644 --- a/pkg/verify/sct.go +++ b/pkg/verify/sct.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" + ct "github.com/google/certificate-transparency-go" "github.com/google/certificate-transparency-go/ctutil" ctx509 "github.com/google/certificate-transparency-go/x509" "github.com/google/certificate-transparency-go/x509util" @@ -58,6 +59,17 @@ func VerifySignedCertificateTimestamp(chains [][]*x509.Certificate, threshold in continue } + // Ensure sct is within ctlog validity window + sctTime := ct.TimestampToTime(sct.Timestamp) + if !key.ValidityPeriodStart.IsZero() && sctTime.Before(key.ValidityPeriodStart) { + // skip entries that were before ctlog key start time + continue + } + if !key.ValidityPeriodEnd.IsZero() && sctTime.After(key.ValidityPeriodEnd) { + // skip entries that were after ctlog key end time + continue + } + for _, chain := range chains { fulcioChain := make([]*ctx509.Certificate, len(leafCTCert)) copy(fulcioChain, leafCTCert) diff --git a/pkg/verify/sct_test.go b/pkg/verify/sct_test.go index 2ef224e..0f031c1 100644 --- a/pkg/verify/sct_test.go +++ b/pkg/verify/sct_test.go @@ -25,6 +25,7 @@ import ( "encoding/hex" "math/big" "testing" + "time" ct "github.com/google/certificate-transparency-go" "github.com/google/certificate-transparency-go/tls" @@ -123,7 +124,9 @@ func TestVerifySignedCertificateTimestamp(t *testing.T) { trustedMaterial: &fakeTrustedMaterial{ transparencyLog: map[string]*root.TransparencyLog{ hex.EncodeToString(logID[:]): { - PublicKey: &privateKey.PublicKey, + PublicKey: &privateKey.PublicKey, + ValidityPeriodStart: time.UnixMilli(12344), + ValidityPeriodEnd: time.UnixMilli(12346), }, }, cas: []root.CertificateAuthority{ @@ -314,6 +317,35 @@ func TestVerifySignedCertificateTimestamp(t *testing.T) { threshold: 0, trustedMaterial: &fakeTrustedMaterial{}, }, + { + name: "sct not valid for ctlog key time range", + getCertFn: func() *x509.Certificate { + return embedSCTs(t, privateKey, skid, createBaseCert(t, privateKey, skid, big.NewInt(1)), []ct.SignedCertificateTimestamp{ + { + SCTVersion: ct.V1, + Timestamp: 12345, + LogID: ct.LogID{KeyID: logID}, + }, + }) + }, + chain: []*x509.Certificate{caCert}, + threshold: 1, + trustedMaterial: &fakeTrustedMaterial{ + transparencyLog: map[string]*root.TransparencyLog{ + hex.EncodeToString(logID[:]): { + PublicKey: &privateKey.PublicKey, + ValidityPeriodStart: time.UnixMilli(10), + ValidityPeriodEnd: time.UnixMilli(10000), + }, + }, + cas: []root.CertificateAuthority{ + &root.FulcioCertificateAuthority{ + Root: caCert, + }, + }, + }, + wantErr: true, + }, { name: "threshold of 2 with 2 valid scts", getCertFn: func() *x509.Certificate {