From ca5f6efa42c15c763d52e7d172f65b963cd04278 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 5 Nov 2024 15:58:22 +0800 Subject: [PATCH 1/5] timestamping Signed-off-by: Patrick Zheng --- go.mod | 6 +++-- go.sum | 12 ++++----- .../TimeStampTokenWithInvalidTSTInfo.p7s | Bin 6578 -> 0 bytes verifier/timestamp_test.go | 23 +----------------- verifier/verifier.go | 18 +++++++------- 5 files changed, 20 insertions(+), 39 deletions(-) delete mode 100644 verifier/testdata/timestamp/countersignature/TimeStampTokenWithInvalidTSTInfo.p7s diff --git a/go.mod b/go.mod index bb911658..f9e9c140 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/go-ldap/ldap/v3 v3.4.8 github.com/notaryproject/notation-core-go v1.2.0-rc.1 github.com/notaryproject/notation-plugin-framework-go v1.0.0 - github.com/notaryproject/tspclient-go v0.2.0 + github.com/notaryproject/tspclient-go v0.2.1-0.20241030015323-90a141e7525c github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0 github.com/veraison/go-cose v1.3.0 @@ -19,8 +19,10 @@ require ( github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect - github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang-jwt/jwt/v4 v4.5.1 // indirect github.com/google/uuid v1.6.0 // indirect github.com/x448/float16 v0.8.4 // indirect golang.org/x/sync v0.6.0 // indirect ) + +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20241105072808-caaaa979c2ab diff --git a/go.sum b/go.sum index 68396e3f..c4755eac 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= +github.com/Two-Hearts/notation-core-go v0.0.0-20241105072808-caaaa979c2ab h1:asI6dQgIRcYe7nOTT6qSuJK7hv38OT6wnTaoHSNfHLo= +github.com/Two-Hearts/notation-core-go v0.0.0-20241105072808-caaaa979c2ab/go.mod h1:phjvE2bqHsLfJMqMUYqRCqNIH3TQ4GCcFQuEVyQTpDg= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -11,8 +13,8 @@ github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-ldap/ldap/v3 v3.4.8 h1:loKJyspcRezt2Q3ZRMq2p/0v8iOurlmeXDPw6fikSvQ= github.com/go-ldap/ldap/v3 v3.4.8/go.mod h1:qS3Sjlu76eHfHGpUdWkAXQTw4beih+cHsco2jXlIXrk= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= -github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= +github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= @@ -32,12 +34,10 @@ github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh6 github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= -github.com/notaryproject/notation-core-go v1.2.0-rc.1 h1:VMFlG+9a1JoNAQ3M96g8iqCq0cDRtE7XBaiTD8Ouvqw= -github.com/notaryproject/notation-core-go v1.2.0-rc.1/go.mod h1:b/70rA4OgOHlg0A7pb8zTWKJadFO6781zS3a37KHEJQ= github.com/notaryproject/notation-plugin-framework-go v1.0.0 h1:6Qzr7DGXoCgXEQN+1gTZWuJAZvxh3p8Lryjn5FaLzi4= github.com/notaryproject/notation-plugin-framework-go v1.0.0/go.mod h1:RqWSrTOtEASCrGOEffq0n8pSg2KOgKYiWqFWczRSics= -github.com/notaryproject/tspclient-go v0.2.0 h1:g/KpQGmyk/h7j60irIRG1mfWnibNOzJ8WhLqAzuiQAQ= -github.com/notaryproject/tspclient-go v0.2.0/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= +github.com/notaryproject/tspclient-go v0.2.1-0.20241030015323-90a141e7525c h1:bX6gGxFw9+DShmYTgbD+vr6neF1SoXIMUU2fDgdLsfA= +github.com/notaryproject/tspclient-go v0.2.1-0.20241030015323-90a141e7525c/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= diff --git a/verifier/testdata/timestamp/countersignature/TimeStampTokenWithInvalidTSTInfo.p7s b/verifier/testdata/timestamp/countersignature/TimeStampTokenWithInvalidTSTInfo.p7s deleted file mode 100644 index 153ea92f420c97b73ca803085d437cbf20b75c94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6578 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 sQMDesSKe1|{558%HALhpY0LlUassI20 diff --git a/verifier/timestamp_test.go b/verifier/timestamp_test.go index f7eb90ec..fd87ce84 100644 --- a/verifier/timestamp_test.go +++ b/verifier/timestamp_test.go @@ -216,28 +216,7 @@ func TestAuthenticTimestamp(t *testing.T) { VerificationLevel: trustpolicy.LevelStrict, } authenticTimestampResult := verifyAuthenticTimestamp(context.Background(), dummyTrustPolicy.Name, dummyTrustPolicy.TrustStores, dummyTrustPolicy.SignatureVerification, trustStore, revocationTimestampingValidator, outcome) - expectedErrMsg := "failed to parse timestamp countersignature with error: unexpected content type: 1.2.840.113549.1.7.1" - if err := authenticTimestampResult.Error; err == nil || err.Error() != expectedErrMsg { - t.Fatalf("expected %s, but got %s", expectedErrMsg, err) - } - }) - - t.Run("verify Authentic Timestamp failed due to invalid TSTInfo", func(t *testing.T) { - signedToken, err := os.ReadFile("testdata/timestamp/countersignature/TimeStampTokenWithInvalidTSTInfo.p7s") - if err != nil { - t.Fatalf("failed to get signedToken: %v", err) - } - envContent, err := parseEnvContent("testdata/timestamp/sigEnv/withoutTimestamp.sig", jws.MediaTypeEnvelope) - if err != nil { - t.Fatalf("failed to get signature envelope content: %v", err) - } - envContent.SignerInfo.UnsignedAttributes.TimestampSignature = signedToken - outcome := ¬ation.VerificationOutcome{ - EnvelopeContent: envContent, - VerificationLevel: trustpolicy.LevelStrict, - } - authenticTimestampResult := verifyAuthenticTimestamp(context.Background(), dummyTrustPolicy.Name, dummyTrustPolicy.TrustStores, dummyTrustPolicy.SignatureVerification, trustStore, revocationTimestampingValidator, outcome) - expectedErrMsg := "failed to get the timestamp TSTInfo with error: cannot unmarshal TSTInfo from timestamp token: asn1: structure error: tags don't match (23 vs {class:0 tag:16 length:3 isCompound:true}) {optional:false explicit:false application:false private:false defaultValue: tag: stringType:0 timeType:24 set:false omitEmpty:false} Time @89" + expectedErrMsg := "failed to parse timestamp countersignature with error: unexpected content type: 1.2.840.113549.1.7.1. Expected to be id-ct-TSTInfo (1.2.840.113549.1.9.16.1.4)" if err := authenticTimestampResult.Error; err == nil || err.Error() != expectedErrMsg { t.Fatalf("expected %s, but got %s", expectedErrMsg, err) } diff --git a/verifier/verifier.go b/verifier/verifier.go index 6811b489..80522d0e 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -1032,14 +1032,6 @@ func verifyTimestamp(ctx context.Context, policyName string, trustStores []strin if err != nil { return fmt.Errorf("failed to parse timestamp countersignature with error: %w", err) } - info, err := signedToken.Info() - if err != nil { - return fmt.Errorf("failed to get the timestamp TSTInfo with error: %w", err) - } - timestamp, err := info.Validate(signerInfo.Signature) - if err != nil { - return fmt.Errorf("failed to get timestamp from timestamp countersignature with error: %w", err) - } trustTSACerts, err := loadX509TSATrustStores(ctx, outcome.EnvelopeContent.SignerInfo.SignedAttributes.SigningScheme, policyName, trustStores, x509TrustStore) if err != nil { return fmt.Errorf("failed to load tsa trust store with error: %w", err) @@ -1052,7 +1044,7 @@ func verifyTimestamp(ctx context.Context, policyName string, trustStores []strin rootCertPool.AddCert(trustedCerts) } tsaCertChain, err := signedToken.Verify(ctx, x509.VerifyOptions{ - CurrentTime: timestamp.Value, + CurrentTime: signerInfo.SignedAttributes.SigningTime, Roots: rootCertPool, }) if err != nil { @@ -1068,6 +1060,14 @@ func verifyTimestamp(ctx context.Context, policyName string, trustStores []strin // 4. Check the timestamp against the signing certificate chain logger.Debug("Checking the timestamp against the signing certificate chain...") + info, err := signedToken.Info() + if err != nil { + return fmt.Errorf("failed to get the timestamp TSTInfo with error: %w", err) + } + timestamp, err := info.Validate(signerInfo.Signature) + if err != nil { + return fmt.Errorf("failed to get timestamp from timestamp countersignature with error: %w", err) + } logger.Debugf("Timestamp range: %s", timestamp.Format(time.RFC3339)) for _, cert := range signerInfo.CertificateChain { if !timestamp.BoundedAfter(cert.NotBefore) { From 298f8f67965c479b42ece71ee4932bd6b993c9a4 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 5 Nov 2024 16:29:56 +0800 Subject: [PATCH 2/5] update Signed-off-by: Patrick Zheng --- verifier/crl/crl.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/verifier/crl/crl.go b/verifier/crl/crl.go index f1e576b9..da91e193 100644 --- a/verifier/crl/crl.go +++ b/verifier/crl/crl.go @@ -88,38 +88,38 @@ func (c *FileCache) Get(ctx context.Context, url string) (*corecrl.Bundle, error logger.Debugf("CRL file cache miss. Key %q does not exist", url) return nil, corecrl.ErrCacheMiss } - logger.Debugf("failed to get crl bundle from file cache with key %q: %w", url, err) + logger.Debugf("failed to get crl bundle from file cache with key %q: %s", url, err) return nil, fmt.Errorf("failed to get crl bundle from file cache with key %q: %w", url, err) } // decode content to crl Bundle var content fileCacheContent if err := json.Unmarshal(contentBytes, &content); err != nil { - logger.Debugf("failed to decode file retrieved from file cache: %w", err) + logger.Debugf("failed to decode file retrieved from file cache: %s", err) return nil, fmt.Errorf("failed to decode file retrieved from file cache: %w", err) } var bundle corecrl.Bundle bundle.BaseCRL, err = x509.ParseRevocationList(content.BaseCRL) if err != nil { - logger.Debugf("failed to parse base CRL of file retrieved from file cache: %w", err) + logger.Debugf("failed to parse base CRL of file retrieved from file cache: %s", err) return nil, fmt.Errorf("failed to parse base CRL of file retrieved from file cache: %w", err) } if content.DeltaCRL != nil { bundle.DeltaCRL, err = x509.ParseRevocationList(content.DeltaCRL) if err != nil { - logger.Debugf("failed to parse delta CRL of file retrieved from file cache: %w", err) + logger.Debugf("failed to parse delta CRL of file retrieved from file cache: %s", err) return nil, fmt.Errorf("failed to parse delta CRL of file retrieved from file cache: %w", err) } } // check expiry if err := checkExpiry(ctx, bundle.BaseCRL.NextUpdate); err != nil { - logger.Debugf("check BaseCRL expiry failed: %w", err) + logger.Debugf("check BaseCRL expiry failed: %s", err) return nil, err } if bundle.DeltaCRL != nil { if err := checkExpiry(ctx, bundle.DeltaCRL.NextUpdate); err != nil { - logger.Debugf("check DeltaCRL expiry failed: %w", err) + logger.Debugf("check DeltaCRL expiry failed: %s", err) return nil, err } } @@ -150,11 +150,11 @@ func (c *FileCache) Set(ctx context.Context, url string, bundle *corecrl.Bundle) } contentBytes, err := json.Marshal(content) if err != nil { - logger.Debugf("failed to store crl bundle in file cache: %w", err) + logger.Debugf("failed to store crl bundle in file cache: %s", err) return fmt.Errorf("failed to store crl bundle in file cache: %w", err) } if err := file.WriteFile(c.root, filepath.Join(c.root, c.fileName(url)), contentBytes); err != nil { - logger.Debugf("failed to store crl bundle in file cache: %w", err) + logger.Debugf("failed to store crl bundle in file cache: %s", err) return fmt.Errorf("failed to store crl bundle in file cache: %w", err) } return nil From 0adc91e78b06ded18cf24c494364be20b3e16711 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 6 Nov 2024 14:58:57 +0800 Subject: [PATCH 3/5] timestamping Signed-off-by: Patrick Zheng --- go.mod | 2 +- go.sum | 4 +- verifier/crl/crl.go | 16 +++---- .../TimeStampTokenWithInvalidTSTInfo.p7s | Bin 0 -> 6578 bytes verifier/timestamp_test.go | 44 ++++++++++++++++++ verifier/verifier.go | 21 +++++---- 6 files changed, 67 insertions(+), 20 deletions(-) create mode 100644 verifier/testdata/timestamp/countersignature/TimeStampTokenWithInvalidTSTInfo.p7s diff --git a/go.mod b/go.mod index f9e9c140..bd7a36f9 100644 --- a/go.mod +++ b/go.mod @@ -25,4 +25,4 @@ require ( golang.org/x/sync v0.6.0 // indirect ) -replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20241105072808-caaaa979c2ab +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20241106062005-5fa7538ad30c diff --git a/go.sum b/go.sum index c4755eac..94b553c1 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= -github.com/Two-Hearts/notation-core-go v0.0.0-20241105072808-caaaa979c2ab h1:asI6dQgIRcYe7nOTT6qSuJK7hv38OT6wnTaoHSNfHLo= -github.com/Two-Hearts/notation-core-go v0.0.0-20241105072808-caaaa979c2ab/go.mod h1:phjvE2bqHsLfJMqMUYqRCqNIH3TQ4GCcFQuEVyQTpDg= +github.com/Two-Hearts/notation-core-go v0.0.0-20241106062005-5fa7538ad30c h1:yArAi0ufqOs4OtxeLntL9DQuJ9Lz9C23B1gEJcgqrJw= +github.com/Two-Hearts/notation-core-go v0.0.0-20241106062005-5fa7538ad30c/go.mod h1:phjvE2bqHsLfJMqMUYqRCqNIH3TQ4GCcFQuEVyQTpDg= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/verifier/crl/crl.go b/verifier/crl/crl.go index da91e193..f1e576b9 100644 --- a/verifier/crl/crl.go +++ b/verifier/crl/crl.go @@ -88,38 +88,38 @@ func (c *FileCache) Get(ctx context.Context, url string) (*corecrl.Bundle, error logger.Debugf("CRL file cache miss. Key %q does not exist", url) return nil, corecrl.ErrCacheMiss } - logger.Debugf("failed to get crl bundle from file cache with key %q: %s", url, err) + logger.Debugf("failed to get crl bundle from file cache with key %q: %w", url, err) return nil, fmt.Errorf("failed to get crl bundle from file cache with key %q: %w", url, err) } // decode content to crl Bundle var content fileCacheContent if err := json.Unmarshal(contentBytes, &content); err != nil { - logger.Debugf("failed to decode file retrieved from file cache: %s", err) + logger.Debugf("failed to decode file retrieved from file cache: %w", err) return nil, fmt.Errorf("failed to decode file retrieved from file cache: %w", err) } var bundle corecrl.Bundle bundle.BaseCRL, err = x509.ParseRevocationList(content.BaseCRL) if err != nil { - logger.Debugf("failed to parse base CRL of file retrieved from file cache: %s", err) + logger.Debugf("failed to parse base CRL of file retrieved from file cache: %w", err) return nil, fmt.Errorf("failed to parse base CRL of file retrieved from file cache: %w", err) } if content.DeltaCRL != nil { bundle.DeltaCRL, err = x509.ParseRevocationList(content.DeltaCRL) if err != nil { - logger.Debugf("failed to parse delta CRL of file retrieved from file cache: %s", err) + logger.Debugf("failed to parse delta CRL of file retrieved from file cache: %w", err) return nil, fmt.Errorf("failed to parse delta CRL of file retrieved from file cache: %w", err) } } // check expiry if err := checkExpiry(ctx, bundle.BaseCRL.NextUpdate); err != nil { - logger.Debugf("check BaseCRL expiry failed: %s", err) + logger.Debugf("check BaseCRL expiry failed: %w", err) return nil, err } if bundle.DeltaCRL != nil { if err := checkExpiry(ctx, bundle.DeltaCRL.NextUpdate); err != nil { - logger.Debugf("check DeltaCRL expiry failed: %s", err) + logger.Debugf("check DeltaCRL expiry failed: %w", err) return nil, err } } @@ -150,11 +150,11 @@ func (c *FileCache) Set(ctx context.Context, url string, bundle *corecrl.Bundle) } contentBytes, err := json.Marshal(content) if err != nil { - logger.Debugf("failed to store crl bundle in file cache: %s", err) + logger.Debugf("failed to store crl bundle in file cache: %w", err) return fmt.Errorf("failed to store crl bundle in file cache: %w", err) } if err := file.WriteFile(c.root, filepath.Join(c.root, c.fileName(url)), contentBytes); err != nil { - logger.Debugf("failed to store crl bundle in file cache: %s", err) + logger.Debugf("failed to store crl bundle in file cache: %w", err) return fmt.Errorf("failed to store crl bundle in file cache: %w", err) } return nil diff --git a/verifier/testdata/timestamp/countersignature/TimeStampTokenWithInvalidTSTInfo.p7s b/verifier/testdata/timestamp/countersignature/TimeStampTokenWithInvalidTSTInfo.p7s new file mode 100644 index 0000000000000000000000000000000000000000..153ea92f420c97b73ca803085d437cbf20b75c94 GIT binary patch literal 6578 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 sQMDesSKe1|{558%HALhpY0LlUassI20 literal 0 HcmV?d00001 diff --git a/verifier/timestamp_test.go b/verifier/timestamp_test.go index fd87ce84..d782fed1 100644 --- a/verifier/timestamp_test.go +++ b/verifier/timestamp_test.go @@ -222,6 +222,27 @@ func TestAuthenticTimestamp(t *testing.T) { } }) + t.Run("verify Authentic Timestamp failed due to invalid TSTInfo", func(t *testing.T) { + signedToken, err := os.ReadFile("testdata/timestamp/countersignature/TimeStampTokenWithInvalidTSTInfo.p7s") + if err != nil { + t.Fatalf("failed to get signedToken: %v", err) + } + envContent, err := parseEnvContent("testdata/timestamp/sigEnv/withoutTimestamp.sig", jws.MediaTypeEnvelope) + if err != nil { + t.Fatalf("failed to get signature envelope content: %v", err) + } + envContent.SignerInfo.UnsignedAttributes.TimestampSignature = signedToken + outcome := ¬ation.VerificationOutcome{ + EnvelopeContent: envContent, + VerificationLevel: trustpolicy.LevelStrict, + } + authenticTimestampResult := verifyAuthenticTimestamp(context.Background(), dummyTrustPolicy.Name, dummyTrustPolicy.TrustStores, dummyTrustPolicy.SignatureVerification, trustStore, revocationTimestampingValidator, outcome) + expectedErrMsg := "failed to get the timestamp TSTInfo with error: cannot unmarshal TSTInfo from timestamp token: asn1: structure error: tags don't match (23 vs {class:0 tag:16 length:3 isCompound:true}) {optional:false explicit:false application:false private:false defaultValue: tag: stringType:0 timeType:24 set:false omitEmpty:false} Time @89" + if err := authenticTimestampResult.Error; err == nil || err.Error() != expectedErrMsg { + t.Fatalf("expected %s, but got %s", expectedErrMsg, err) + } + }) + t.Run("verify Authentic Timestamp failed due to failed to validate TSTInfo", func(t *testing.T) { signedToken, err := os.ReadFile("testdata/timestamp/countersignature/TimeStampToken.p7s") if err != nil { @@ -266,6 +287,29 @@ func TestAuthenticTimestamp(t *testing.T) { } }) + t.Run("verify Authentic Timestamp failed due to signing time after timestamp value", func(t *testing.T) { + signedToken, err := os.ReadFile("testdata/timestamp/countersignature/TimeStampToken.p7s") + if err != nil { + t.Fatalf("failed to get signedToken: %v", err) + } + envContent, err := parseEnvContent("testdata/timestamp/sigEnv/withoutTimestamp.sig", jws.MediaTypeEnvelope) + if err != nil { + t.Fatalf("failed to get signature envelope content: %v", err) + } + envContent.SignerInfo.UnsignedAttributes.TimestampSignature = signedToken + envContent.SignerInfo.Signature = []byte("notation") + envContent.SignerInfo.SignedAttributes.SigningTime = time.Date(3000, time.November, 10, 23, 0, 0, 0, time.UTC) + outcome := ¬ation.VerificationOutcome{ + EnvelopeContent: envContent, + VerificationLevel: trustpolicy.LevelStrict, + } + authenticTimestampResult := verifyAuthenticTimestamp(context.Background(), dummyTrustPolicy.Name, dummyTrustPolicy.TrustStores, dummyTrustPolicy.SignatureVerification, trustStore, revocationTimestampingValidator, outcome) + expectedErrMsg := "timestamp range [2021-09-17T14:09:09Z, 2021-09-17T14:09:11Z] is not bounded after the signing time \"3000-11-10 23:00:00 +0000 UTC\"" + if err := authenticTimestampResult.Error; err == nil || err.Error() != expectedErrMsg { + t.Fatalf("expected %s, but got %s", expectedErrMsg, err) + } + }) + t.Run("verify Authentic Timestamp failed due to trust store does not exist", func(t *testing.T) { dummyTrustPolicy := &trustpolicy.TrustPolicy{ Name: "test-timestamp", diff --git a/verifier/verifier.go b/verifier/verifier.go index 80522d0e..c896b0f6 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -1043,13 +1043,24 @@ func verifyTimestamp(ctx context.Context, policyName string, trustStores []strin for _, trustedCerts := range trustTSACerts { rootCertPool.AddCert(trustedCerts) } + info, err := signedToken.Info() + if err != nil { + return fmt.Errorf("failed to get the timestamp TSTInfo with error: %w", err) + } + timestamp, err := info.Validate(signerInfo.Signature) + if err != nil { + return fmt.Errorf("failed to get timestamp from timestamp countersignature with error: %w", err) + } tsaCertChain, err := signedToken.Verify(ctx, x509.VerifyOptions{ - CurrentTime: signerInfo.SignedAttributes.SigningTime, + CurrentTime: timestamp.Value, Roots: rootCertPool, }) if err != nil { return fmt.Errorf("failed to verify the timestamp countersignature with error: %w", err) } + if !timestamp.BoundedAfter(signerInfo.SignedAttributes.SigningTime) { + return fmt.Errorf("timestamp range %s is not bounded after the signing time %q", timestamp.Format(time.RFC3339), signerInfo.SignedAttributes.SigningTime) + } // 3. Validate timestamping certificate chain logger.Debug("Validating timestamping certificate chain...") @@ -1060,14 +1071,6 @@ func verifyTimestamp(ctx context.Context, policyName string, trustStores []strin // 4. Check the timestamp against the signing certificate chain logger.Debug("Checking the timestamp against the signing certificate chain...") - info, err := signedToken.Info() - if err != nil { - return fmt.Errorf("failed to get the timestamp TSTInfo with error: %w", err) - } - timestamp, err := info.Validate(signerInfo.Signature) - if err != nil { - return fmt.Errorf("failed to get timestamp from timestamp countersignature with error: %w", err) - } logger.Debugf("Timestamp range: %s", timestamp.Format(time.RFC3339)) for _, cert := range signerInfo.CertificateChain { if !timestamp.BoundedAfter(cert.NotBefore) { From 18ead3de76e2b8d7bc4fae3034baba0bdfd2087c Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 12 Nov 2024 10:15:52 +0800 Subject: [PATCH 4/5] timestamping Signed-off-by: Patrick Zheng --- go.mod | 4 +--- go.sum | 4 ++-- verifier/timestamp_test.go | 2 +- verifier/verifier.go | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 18110a08..58c96323 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.22.0 require ( github.com/go-ldap/ldap/v3 v3.4.8 - github.com/notaryproject/notation-core-go v1.2.0-rc.1 + github.com/notaryproject/notation-core-go v1.2.0-rc.1.0.20241112001243-33af15a18954 github.com/notaryproject/notation-plugin-framework-go v1.0.0 github.com/notaryproject/tspclient-go v0.2.1-0.20241030015323-90a141e7525c github.com/opencontainers/go-digest v1.0.0 @@ -24,5 +24,3 @@ require ( github.com/x448/float16 v0.8.4 // indirect golang.org/x/sync v0.6.0 // indirect ) - -replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20241106062005-5fa7538ad30c diff --git a/go.sum b/go.sum index 58a215f1..32ffce72 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= -github.com/Two-Hearts/notation-core-go v0.0.0-20241106062005-5fa7538ad30c h1:yArAi0ufqOs4OtxeLntL9DQuJ9Lz9C23B1gEJcgqrJw= -github.com/Two-Hearts/notation-core-go v0.0.0-20241106062005-5fa7538ad30c/go.mod h1:phjvE2bqHsLfJMqMUYqRCqNIH3TQ4GCcFQuEVyQTpDg= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -34,6 +32,8 @@ github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh6 github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= +github.com/notaryproject/notation-core-go v1.2.0-rc.1.0.20241112001243-33af15a18954 h1:UbjH/ePjxU8jcYMca9NVYqU8Qcr7pP1SKDWCxl++ToA= +github.com/notaryproject/notation-core-go v1.2.0-rc.1.0.20241112001243-33af15a18954/go.mod h1:phjvE2bqHsLfJMqMUYqRCqNIH3TQ4GCcFQuEVyQTpDg= github.com/notaryproject/notation-plugin-framework-go v1.0.0 h1:6Qzr7DGXoCgXEQN+1gTZWuJAZvxh3p8Lryjn5FaLzi4= github.com/notaryproject/notation-plugin-framework-go v1.0.0/go.mod h1:RqWSrTOtEASCrGOEffq0n8pSg2KOgKYiWqFWczRSics= github.com/notaryproject/tspclient-go v0.2.1-0.20241030015323-90a141e7525c h1:bX6gGxFw9+DShmYTgbD+vr6neF1SoXIMUU2fDgdLsfA= diff --git a/verifier/timestamp_test.go b/verifier/timestamp_test.go index d782fed1..22c75660 100644 --- a/verifier/timestamp_test.go +++ b/verifier/timestamp_test.go @@ -304,7 +304,7 @@ func TestAuthenticTimestamp(t *testing.T) { VerificationLevel: trustpolicy.LevelStrict, } authenticTimestampResult := verifyAuthenticTimestamp(context.Background(), dummyTrustPolicy.Name, dummyTrustPolicy.TrustStores, dummyTrustPolicy.SignatureVerification, trustStore, revocationTimestampingValidator, outcome) - expectedErrMsg := "timestamp range [2021-09-17T14:09:09Z, 2021-09-17T14:09:11Z] is not bounded after the signing time \"3000-11-10 23:00:00 +0000 UTC\"" + expectedErrMsg := "timestamp [2021-09-17T14:09:09Z, 2021-09-17T14:09:11Z] is not bounded after the signing time \"3000-11-10 23:00:00 +0000 UTC\"" if err := authenticTimestampResult.Error; err == nil || err.Error() != expectedErrMsg { t.Fatalf("expected %s, but got %s", expectedErrMsg, err) } diff --git a/verifier/verifier.go b/verifier/verifier.go index c896b0f6..cddb5382 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -1059,7 +1059,7 @@ func verifyTimestamp(ctx context.Context, policyName string, trustStores []strin return fmt.Errorf("failed to verify the timestamp countersignature with error: %w", err) } if !timestamp.BoundedAfter(signerInfo.SignedAttributes.SigningTime) { - return fmt.Errorf("timestamp range %s is not bounded after the signing time %q", timestamp.Format(time.RFC3339), signerInfo.SignedAttributes.SigningTime) + return fmt.Errorf("timestamp %s is not bounded after the signing time %q", timestamp.Format(time.RFC3339), signerInfo.SignedAttributes.SigningTime) } // 3. Validate timestamping certificate chain From 18a82755e31a789410813e8202f6bd5973ced3c8 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 12 Nov 2024 10:18:45 +0800 Subject: [PATCH 5/5] timestamping Signed-off-by: Patrick Zheng --- verifier/verifier.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/verifier/verifier.go b/verifier/verifier.go index cddb5382..b16ead32 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -1032,6 +1032,14 @@ func verifyTimestamp(ctx context.Context, policyName string, trustStores []strin if err != nil { return fmt.Errorf("failed to parse timestamp countersignature with error: %w", err) } + info, err := signedToken.Info() + if err != nil { + return fmt.Errorf("failed to get the timestamp TSTInfo with error: %w", err) + } + timestamp, err := info.Validate(signerInfo.Signature) + if err != nil { + return fmt.Errorf("failed to get timestamp from timestamp countersignature with error: %w", err) + } trustTSACerts, err := loadX509TSATrustStores(ctx, outcome.EnvelopeContent.SignerInfo.SignedAttributes.SigningScheme, policyName, trustStores, x509TrustStore) if err != nil { return fmt.Errorf("failed to load tsa trust store with error: %w", err) @@ -1043,14 +1051,6 @@ func verifyTimestamp(ctx context.Context, policyName string, trustStores []strin for _, trustedCerts := range trustTSACerts { rootCertPool.AddCert(trustedCerts) } - info, err := signedToken.Info() - if err != nil { - return fmt.Errorf("failed to get the timestamp TSTInfo with error: %w", err) - } - timestamp, err := info.Validate(signerInfo.Signature) - if err != nil { - return fmt.Errorf("failed to get timestamp from timestamp countersignature with error: %w", err) - } tsaCertChain, err := signedToken.Verify(ctx, x509.VerifyOptions{ CurrentTime: timestamp.Value, Roots: rootCertPool,