From 4b4273838666ab22a5f270511006fe43c63adc85 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Fri, 1 Dec 2023 11:56:40 +0800 Subject: [PATCH 01/38] initial test Signed-off-by: Patrick Zheng --- go.mod | 2 + go.sum | 4 +- notation.go | 3 ++ signer/signer.go | 1 + verifier/helpers.go | 64 ++++++++++++++--------- verifier/truststore/truststore.go | 1 + verifier/verifier.go | 84 ++++++++++++++++++++++++++----- 7 files changed, 120 insertions(+), 39 deletions(-) diff --git a/go.mod b/go.mod index 0fe94875..6bd5e6a9 100644 --- a/go.mod +++ b/go.mod @@ -22,3 +22,5 @@ require ( github.com/x448/float16 v0.8.4 // indirect golang.org/x/sync v0.4.0 // indirect ) + +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20231201035326-ac03000e2df3 diff --git a/go.sum b/go.sum index 5b4b602d..0d314f7e 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-20231201035326-ac03000e2df3 h1:OD7WwvjZ4UjRW6rcG26PYW406zH0BP0y9TpzaGjY6eE= +github.com/Two-Hearts/notation-core-go v0.0.0-20231201035326-ac03000e2df3/go.mod h1:lqk34iYxJ1OpFP3r2gbBKzYIj/1pJ9p7mNULf1KjErY= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -15,8 +17,6 @@ github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOW github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/notaryproject/notation-core-go v1.0.1 h1:01doxjDERbd0vocLQrlJdusKrRLNNn50OJzp0c5I4Cw= -github.com/notaryproject/notation-core-go v1.0.1/go.mod h1:rayl8WlKgS4YxOZgDO0iGGB4Ef515ZFZUFaZDmsPXgE= 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-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= diff --git a/notation.go b/notation.go index ef8593c7..ed59e614 100644 --- a/notation.go +++ b/notation.go @@ -54,6 +54,9 @@ type SignerSignOptions struct { // SigningAgent sets the signing agent name SigningAgent string + + // TSA denotes the TSA server URL + TSAServerURL string } // Signer is a generic interface for signing an artifact. diff --git a/signer/signer.go b/signer/signer.go index cefc7788..556fa696 100644 --- a/signer/signer.go +++ b/signer/signer.go @@ -110,6 +110,7 @@ func (s *genericSigner) Sign(ctx context.Context, desc ocispec.Descriptor, opts SigningTime: time.Now(), SigningScheme: signature.SigningSchemeX509, SigningAgent: signingAgentId, + TSAServerURL: opts.TSAServerURL, } // Add expiry only if ExpiryDuration is not zero diff --git a/verifier/helpers.go b/verifier/helpers.go index dfabadb0..a294c32c 100644 --- a/verifier/helpers.go +++ b/verifier/helpers.go @@ -60,31 +60,7 @@ func loadX509TrustStores(ctx context.Context, scheme signature.SigningScheme, po default: return nil, truststore.TrustStoreError{Msg: fmt.Sprintf("error while loading the trust store, unrecognized signing scheme %q", scheme)} } - - processedStoreSet := set.New[string]() - var certificates []*x509.Certificate - for _, trustStore := range policy.TrustStores { - if processedStoreSet.Contains(trustStore) { - // we loaded this trust store already - continue - } - - storeType, name, found := strings.Cut(trustStore, ":") - if !found { - return nil, truststore.TrustStoreError{Msg: fmt.Sprintf("error while loading the trust store, trust policy statement %q is missing separator in trust store value %q. The required format is :", policy.Name, trustStore)} - } - if typeToLoad != truststore.Type(storeType) { - continue - } - - certs, err := x509TrustStore.GetCertificates(ctx, typeToLoad, name) - if err != nil { - return nil, err - } - certificates = append(certificates, certs...) - processedStoreSet.Add(trustStore) - } - return certificates, nil + return loadX509TrustStoresWithType(ctx, typeToLoad, policy, x509TrustStore) } // isCriticalFailure checks whether a VerificationResult fails the entire @@ -161,3 +137,41 @@ func getVerificationPluginMinVersion(signerInfo *signature.SignerInfo) (string, func isVersionSemverValid(version string) bool { return semVerRegEx.MatchString(version) } + +func loadX509TSATrustStores(ctx context.Context, scheme signature.SigningScheme, policy *trustpolicy.TrustPolicy, x509TrustStore truststore.X509TrustStore) ([]*x509.Certificate, error) { + var typeToLoad truststore.Type + switch scheme { + case signature.SigningSchemeX509: + typeToLoad = truststore.TypeTSA + default: + return nil, truststore.TrustStoreError{Msg: fmt.Sprintf("error while loading the TSA trust store, signing scheme must be notary.x509, but got %s", scheme)} + } + return loadX509TrustStoresWithType(ctx, typeToLoad, policy, x509TrustStore) +} + +func loadX509TrustStoresWithType(ctx context.Context, trustStoreType truststore.Type, policy *trustpolicy.TrustPolicy, x509TrustStore truststore.X509TrustStore) ([]*x509.Certificate, error) { + processedStoreSet := set.New[string]() + var certificates []*x509.Certificate + for _, trustStore := range policy.TrustStores { + if processedStoreSet.Contains(trustStore) { + // we loaded this trust store already + continue + } + + storeType, name, found := strings.Cut(trustStore, ":") + if !found { + return nil, truststore.TrustStoreError{Msg: fmt.Sprintf("error while loading the trust store, trust policy statement %q is missing separator in trust store value %q. The required format is :", policy.Name, trustStore)} + } + if trustStoreType != truststore.Type(storeType) { + continue + } + + certs, err := x509TrustStore.GetCertificates(ctx, trustStoreType, name) + if err != nil { + return nil, err + } + certificates = append(certificates, certs...) + processedStoreSet.Add(trustStore) + } + return certificates, nil +} diff --git a/verifier/truststore/truststore.go b/verifier/truststore/truststore.go index c98b2c6c..a1659573 100644 --- a/verifier/truststore/truststore.go +++ b/verifier/truststore/truststore.go @@ -36,6 +36,7 @@ type Type string const ( TypeCA Type = "ca" TypeSigningAuthority Type = "signingAuthority" + TypeTSA Type = "tsa" ) var ( diff --git a/verifier/verifier.go b/verifier/verifier.go index bf76494e..28898a54 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -28,6 +28,7 @@ import ( "github.com/notaryproject/notation-core-go/revocation" revocationresult "github.com/notaryproject/notation-core-go/revocation/result" "github.com/notaryproject/notation-core-go/signature" + "github.com/notaryproject/notation-core-go/timestamp" "github.com/notaryproject/notation-go" "github.com/notaryproject/notation-go/dir" "github.com/notaryproject/notation-go/internal/envelope" @@ -284,7 +285,7 @@ func (v *verifier) processSignature(ctx context.Context, sigBlob []byte, envelop // verify authentic timestamp logger.Debug("Validating authentic timestamp") - authenticTimestampResult := verifyAuthenticTimestamp(outcome) + authenticTimestampResult := verifyAuthenticTimestamp(ctx, trustPolicy, v.trustStore, outcome) outcome.VerificationResults = append(outcome.VerificationResults, authenticTimestampResult) logVerificationResult(logger, authenticTimestampResult) if isCriticalFailure(authenticTimestampResult) { @@ -512,29 +513,88 @@ func verifyExpiry(outcome *notation.VerificationOutcome) *notation.ValidationRes } } -func verifyAuthenticTimestamp(outcome *notation.VerificationOutcome) *notation.ValidationResult { +func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.TrustPolicy, x509TrustStore truststore.X509TrustStore, outcome *notation.VerificationOutcome) *notation.ValidationResult { invalidTimestamp := false var err error if signerInfo := outcome.EnvelopeContent.SignerInfo; signerInfo.SignedAttributes.SigningScheme == signature.SigningSchemeX509 { + var timeStampLowerLimit time.Time + var timeStampUpperLimit time.Time // TODO verify RFC3161 TSA signature if present (not in RC1) // https://github.com/notaryproject/notation-go/issues/78 if len(signerInfo.UnsignedAttributes.TimestampSignature) == 0 { // if there is no TSA signature, then every certificate should be // valid at the time of verification - now := time.Now() - for _, cert := range signerInfo.CertificateChain { - if now.Before(cert.NotBefore) { - invalidTimestamp = true - err = fmt.Errorf("certificate %q is not valid yet, it will be valid from %q", cert.Subject, cert.NotBefore.Format(time.RFC1123Z)) - break + timeStampLowerLimit = time.Now() + timeStampUpperLimit = timeStampLowerLimit + } else { + trustTSACerts, err := loadX509TSATrustStores(ctx, outcome.EnvelopeContent.SignerInfo.SignedAttributes.SigningScheme, trustPolicy, x509TrustStore) + if err != nil { + return ¬ation.ValidationResult{ + Error: err, + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], + } + } + if len(trustTSACerts) < 1 { + return ¬ation.ValidationResult{ + Error: notation.ErrorVerificationInconclusive{Msg: "no trusted TSA certificate was found to verify authentic timestamp"}, + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], + } + } + signedToken, err := timestamp.ParseSignedToken(signerInfo.UnsignedAttributes.TimestampSignature) + if err != nil { + return ¬ation.ValidationResult{ + Error: err, + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } - if now.After(cert.NotAfter) { - invalidTimestamp = true - err = fmt.Errorf("certificate %q is not valid anymore, it was expired at %q", cert.Subject, cert.NotAfter.Format(time.RFC1123Z)) - break + } + roots := x509.NewCertPool() + for _, cert := range trustTSACerts { + roots.AddCert(cert) + } + opts := x509.VerifyOptions{ + Roots: roots, + } + if _, err := signedToken.Verify(opts); err != nil { + return ¬ation.ValidationResult{ + Error: err, + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } + info, err := signedToken.Info() + if err != nil { + return ¬ation.ValidationResult{ + Error: err, + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], + } + } + if err := info.VerifyContent(signerInfo.Signature); err != nil { + return ¬ation.ValidationResult{ + Error: err, + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], + } + } + ts, accuracy := info.Timestamp() + timeStampLowerLimit = ts.Add(-accuracy) + timeStampUpperLimit = ts.Add(accuracy) + } + for _, cert := range signerInfo.CertificateChain { + if timeStampLowerLimit.Before(cert.NotBefore) { + invalidTimestamp = true + err = fmt.Errorf("certificate %q is not valid yet, it will be valid from %q", cert.Subject, cert.NotBefore.Format(time.RFC1123Z)) + break + } + if timeStampUpperLimit.After(cert.NotAfter) { + invalidTimestamp = true + err = fmt.Errorf("certificate %q is not valid anymore, it was expired at %q", cert.Subject, cert.NotAfter.Format(time.RFC1123Z)) + break + } } } else if signerInfo.SignedAttributes.SigningScheme == signature.SigningSchemeX509SigningAuthority { authenticSigningTime := signerInfo.SignedAttributes.SigningTime From ca5bba24b0980954910fa749603fd20bc20d5495 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Mon, 4 Dec 2023 16:26:11 +0800 Subject: [PATCH 02/38] fix trust store Signed-off-by: Patrick Zheng --- go.mod | 2 +- go.sum | 4 ++-- verifier/truststore/truststore.go | 1 + verifier/verifier.go | 2 ++ 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6bd5e6a9..89f99852 100644 --- a/go.mod +++ b/go.mod @@ -23,4 +23,4 @@ require ( golang.org/x/sync v0.4.0 // indirect ) -replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20231201035326-ac03000e2df3 +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20231204081632-05b04634606c diff --git a/go.sum b/go.sum index 0d314f7e..d1f81fae 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-20231201035326-ac03000e2df3 h1:OD7WwvjZ4UjRW6rcG26PYW406zH0BP0y9TpzaGjY6eE= -github.com/Two-Hearts/notation-core-go v0.0.0-20231201035326-ac03000e2df3/go.mod h1:lqk34iYxJ1OpFP3r2gbBKzYIj/1pJ9p7mNULf1KjErY= +github.com/Two-Hearts/notation-core-go v0.0.0-20231204081632-05b04634606c h1:+T5N99gr+CIWQW7z8a0CNQWNmW0HS2rm2AbLRV8BNdo= +github.com/Two-Hearts/notation-core-go v0.0.0-20231204081632-05b04634606c/go.mod h1:lqk34iYxJ1OpFP3r2gbBKzYIj/1pJ9p7mNULf1KjErY= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/verifier/truststore/truststore.go b/verifier/truststore/truststore.go index a1659573..067f5e63 100644 --- a/verifier/truststore/truststore.go +++ b/verifier/truststore/truststore.go @@ -43,6 +43,7 @@ var ( Types = []Type{ TypeCA, TypeSigningAuthority, + TypeTSA, } ) diff --git a/verifier/verifier.go b/verifier/verifier.go index 28898a54..7eb2801f 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -583,8 +583,10 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus ts, accuracy := info.Timestamp() timeStampLowerLimit = ts.Add(-accuracy) timeStampUpperLimit = ts.Add(accuracy) + fmt.Printf("tsa time range: [%v, %v]\n", timeStampLowerLimit, timeStampUpperLimit) } for _, cert := range signerInfo.CertificateChain { + fmt.Printf("cert validiy time range: [%v, %v]\n", cert.NotBefore, cert.NotAfter) if timeStampLowerLimit.Before(cert.NotBefore) { invalidTimestamp = true err = fmt.Errorf("certificate %q is not valid yet, it will be valid from %q", cert.Subject, cert.NotBefore.Format(time.RFC1123Z)) From 8e6bbdb4fe5201ca0651b3e1e4246cf26a91727c Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Mon, 15 Jan 2024 14:52:24 +0800 Subject: [PATCH 03/38] initial commits Signed-off-by: Patrick Zheng --- go.mod | 2 +- go.sum | 4 ++-- signer/signer.go | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 7ba608e7..c30c8f5f 100644 --- a/go.mod +++ b/go.mod @@ -23,4 +23,4 @@ require ( golang.org/x/sync v0.4.0 // indirect ) -replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20231204081632-05b04634606c +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240115064451-8f41af02bdf0 diff --git a/go.sum b/go.sum index 67785263..7aef88e6 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-20231204081632-05b04634606c h1:+T5N99gr+CIWQW7z8a0CNQWNmW0HS2rm2AbLRV8BNdo= -github.com/Two-Hearts/notation-core-go v0.0.0-20231204081632-05b04634606c/go.mod h1:lqk34iYxJ1OpFP3r2gbBKzYIj/1pJ9p7mNULf1KjErY= +github.com/Two-Hearts/notation-core-go v0.0.0-20240115064451-8f41af02bdf0 h1:0yq4cJuiqusBnu/0+4aacw8MKJRBa91F682V8f7KF7k= +github.com/Two-Hearts/notation-core-go v0.0.0-20240115064451-8f41af02bdf0/go.mod h1:UODkkz67jE/0osUGm8vqDFvdzy10wkXj0qVCfskMoks= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/signer/signer.go b/signer/signer.go index 556fa696..2210c285 100644 --- a/signer/signer.go +++ b/signer/signer.go @@ -124,6 +124,7 @@ func (s *genericSigner) Sign(ctx context.Context, desc ocispec.Descriptor, opts logger.Debugf(" Expiry: %v", signReq.Expiry) logger.Debugf(" SigningScheme: %v", signReq.SigningScheme) logger.Debugf(" SigningAgent: %v", signReq.SigningAgent) + logger.Debugf(" TSAServerURL: %v", signReq.TSAServerURL) // perform signing sigEnv, err := signature.NewEnvelope(opts.SignatureMediaType) From b454646ffe9017138deecf1240af81aefadb60a5 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Mon, 15 Jan 2024 15:01:40 +0800 Subject: [PATCH 04/38] initial commits Signed-off-by: Patrick Zheng --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c30c8f5f..cb036a47 100644 --- a/go.mod +++ b/go.mod @@ -23,4 +23,4 @@ require ( golang.org/x/sync v0.4.0 // indirect ) -replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240115064451-8f41af02bdf0 +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240115065858-01e426868efb diff --git a/go.sum b/go.sum index 7aef88e6..dfc941e1 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-20240115064451-8f41af02bdf0 h1:0yq4cJuiqusBnu/0+4aacw8MKJRBa91F682V8f7KF7k= -github.com/Two-Hearts/notation-core-go v0.0.0-20240115064451-8f41af02bdf0/go.mod h1:UODkkz67jE/0osUGm8vqDFvdzy10wkXj0qVCfskMoks= +github.com/Two-Hearts/notation-core-go v0.0.0-20240115065858-01e426868efb h1:ZMzek1iFSk+A02pgcovmWPv+sMVl4pMGg1Gi3/jhlJY= +github.com/Two-Hearts/notation-core-go v0.0.0-20240115065858-01e426868efb/go.mod h1:UODkkz67jE/0osUGm8vqDFvdzy10wkXj0qVCfskMoks= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= From 9cd5aafaea0cb10bddd06119a96c249fbd59d869 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 23 Jan 2024 12:46:05 +0800 Subject: [PATCH 05/38] updated to use tspclient-go Signed-off-by: Patrick Zheng --- go.mod | 5 ++++- go.sum | 6 ++++-- verifier/verifier.go | 6 +++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index cf43c11f..f0d10e25 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.20 require ( github.com/go-ldap/ldap/v3 v3.4.6 github.com/notaryproject/notation-core-go v1.0.1 + github.com/notaryproject/tspclient-go v0.0.0-20240122083733-a373599795a2 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0-rc5 github.com/veraison/go-cose v1.1.0 @@ -23,4 +24,6 @@ require ( golang.org/x/sync v0.4.0 // indirect ) -replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240115065858-01e426868efb +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240123043947-8ad3eab6de2e + +replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240122092120-2bc44d93e3de diff --git a/go.sum b/go.sum index 72d611e0..8f05c2d8 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,9 @@ 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-20240115065858-01e426868efb h1:ZMzek1iFSk+A02pgcovmWPv+sMVl4pMGg1Gi3/jhlJY= -github.com/Two-Hearts/notation-core-go v0.0.0-20240115065858-01e426868efb/go.mod h1:UODkkz67jE/0osUGm8vqDFvdzy10wkXj0qVCfskMoks= +github.com/Two-Hearts/notation-core-go v0.0.0-20240123043947-8ad3eab6de2e h1:Y8tQ++n4f1F7jRwIFNcbIEMkqHASU2oSRAQToJEEgWw= +github.com/Two-Hearts/notation-core-go v0.0.0-20240123043947-8ad3eab6de2e/go.mod h1:k7FA8ztvUYy8Cj8tkwYsYhtNentRXsA0RdZaj9cyies= +github.com/Two-Hearts/tspclient-go v0.0.0-20240122092120-2bc44d93e3de h1:hVtfF/PdWNEO6lGPE2ljr7zgAehX6At0oao1abpvo9Q= +github.com/Two-Hearts/tspclient-go v0.0.0-20240122092120-2bc44d93e3de/go.mod h1:Pgt9nPf69t08eVXdxjcfxZalElbQocRuP1DGSKZDpMs= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/verifier/verifier.go b/verifier/verifier.go index 3617ef5f..a3cad125 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -28,7 +28,6 @@ import ( "github.com/notaryproject/notation-core-go/revocation" revocationresult "github.com/notaryproject/notation-core-go/revocation/result" "github.com/notaryproject/notation-core-go/signature" - "github.com/notaryproject/notation-core-go/timestamp" "github.com/notaryproject/notation-go" "github.com/notaryproject/notation-go/dir" "github.com/notaryproject/notation-go/internal/envelope" @@ -41,6 +40,7 @@ import ( "github.com/notaryproject/notation-go/plugin/proto" "github.com/notaryproject/notation-go/verifier/trustpolicy" "github.com/notaryproject/notation-go/verifier/truststore" + "github.com/notaryproject/tspclient-go" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "golang.org/x/mod/semver" "oras.land/oras-go/v2/content" @@ -544,7 +544,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - signedToken, err := timestamp.ParseSignedToken(signerInfo.UnsignedAttributes.TimestampSignature) + signedToken, err := tspclient.ParseSignedToken(ctx, signerInfo.UnsignedAttributes.TimestampSignature) if err != nil { return ¬ation.ValidationResult{ Error: err, @@ -559,7 +559,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus opts := x509.VerifyOptions{ Roots: roots, } - if _, err := signedToken.Verify(opts); err != nil { + if _, err := signedToken.Verify(ctx, opts); err != nil { return ¬ation.ValidationResult{ Error: err, Type: trustpolicy.TypeAuthenticTimestamp, From ea97a99e7c3c942126598edeed0a38ee3d0a700d Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 31 Jan 2024 16:36:30 +0800 Subject: [PATCH 06/38] updated tspclient-go Signed-off-by: Patrick Zheng --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 967dd739..ecd43d40 100644 --- a/go.mod +++ b/go.mod @@ -24,6 +24,6 @@ require ( golang.org/x/sync v0.4.0 // indirect ) -replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240123043947-8ad3eab6de2e +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240131082739-3e76750e7e47 -replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240122092120-2bc44d93e3de +replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240131082004-ba595813cc9d diff --git a/go.sum b/go.sum index 8f05c2d8..e3c738ec 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ 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-20240123043947-8ad3eab6de2e h1:Y8tQ++n4f1F7jRwIFNcbIEMkqHASU2oSRAQToJEEgWw= -github.com/Two-Hearts/notation-core-go v0.0.0-20240123043947-8ad3eab6de2e/go.mod h1:k7FA8ztvUYy8Cj8tkwYsYhtNentRXsA0RdZaj9cyies= -github.com/Two-Hearts/tspclient-go v0.0.0-20240122092120-2bc44d93e3de h1:hVtfF/PdWNEO6lGPE2ljr7zgAehX6At0oao1abpvo9Q= -github.com/Two-Hearts/tspclient-go v0.0.0-20240122092120-2bc44d93e3de/go.mod h1:Pgt9nPf69t08eVXdxjcfxZalElbQocRuP1DGSKZDpMs= +github.com/Two-Hearts/notation-core-go v0.0.0-20240131082739-3e76750e7e47 h1:W1nlb5g6XVdyJ46WcUnY91Ja+BCfvvgUeuZYOF1Q5VA= +github.com/Two-Hearts/notation-core-go v0.0.0-20240131082739-3e76750e7e47/go.mod h1:FaerqzzTnQn/bqZhph5WGhrGhFOFRDeghTvXAUG1SZA= +github.com/Two-Hearts/tspclient-go v0.0.0-20240131082004-ba595813cc9d h1:RaFc+6Xkky04Y9DHb4BVhq9M1u3yhdoyccgDzcXwSgw= +github.com/Two-Hearts/tspclient-go v0.0.0-20240131082004-ba595813cc9d/go.mod h1:Pgt9nPf69t08eVXdxjcfxZalElbQocRuP1DGSKZDpMs= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= From fa4eaafc7f2e6236281bc15e1b4e8efa56163474 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Thu, 1 Feb 2024 12:58:27 +0800 Subject: [PATCH 07/38] test Signed-off-by: Patrick Zheng --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index ecd43d40..0c38cc46 100644 --- a/go.mod +++ b/go.mod @@ -24,6 +24,6 @@ require ( golang.org/x/sync v0.4.0 // indirect ) -replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240131082739-3e76750e7e47 +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240201045651-5fc45dcf1f9e replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240131082004-ba595813cc9d diff --git a/go.sum b/go.sum index e3c738ec..789527ce 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-20240131082739-3e76750e7e47 h1:W1nlb5g6XVdyJ46WcUnY91Ja+BCfvvgUeuZYOF1Q5VA= -github.com/Two-Hearts/notation-core-go v0.0.0-20240131082739-3e76750e7e47/go.mod h1:FaerqzzTnQn/bqZhph5WGhrGhFOFRDeghTvXAUG1SZA= +github.com/Two-Hearts/notation-core-go v0.0.0-20240201045651-5fc45dcf1f9e h1:IysWIIIVRtsKXps0UfoiPpcOoWeRVR2eau71WUmihMU= +github.com/Two-Hearts/notation-core-go v0.0.0-20240201045651-5fc45dcf1f9e/go.mod h1:FaerqzzTnQn/bqZhph5WGhrGhFOFRDeghTvXAUG1SZA= github.com/Two-Hearts/tspclient-go v0.0.0-20240131082004-ba595813cc9d h1:RaFc+6Xkky04Y9DHb4BVhq9M1u3yhdoyccgDzcXwSgw= github.com/Two-Hearts/tspclient-go v0.0.0-20240131082004-ba595813cc9d/go.mod h1:Pgt9nPf69t08eVXdxjcfxZalElbQocRuP1DGSKZDpMs= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= From dc9c5fe781907346690e804c5bd0ed27e33e2aa9 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Thu, 1 Feb 2024 13:11:18 +0800 Subject: [PATCH 08/38] update Signed-off-by: Patrick Zheng --- go.mod | 2 +- go.sum | 4 ++-- verifier/verifier.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 0c38cc46..750c1bc7 100644 --- a/go.mod +++ b/go.mod @@ -24,6 +24,6 @@ require ( golang.org/x/sync v0.4.0 // indirect ) -replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240201045651-5fc45dcf1f9e +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240201050938-182af1affc30 replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240131082004-ba595813cc9d diff --git a/go.sum b/go.sum index 789527ce..cc171242 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-20240201045651-5fc45dcf1f9e h1:IysWIIIVRtsKXps0UfoiPpcOoWeRVR2eau71WUmihMU= -github.com/Two-Hearts/notation-core-go v0.0.0-20240201045651-5fc45dcf1f9e/go.mod h1:FaerqzzTnQn/bqZhph5WGhrGhFOFRDeghTvXAUG1SZA= +github.com/Two-Hearts/notation-core-go v0.0.0-20240201050938-182af1affc30 h1:0EE/GVxacnp/KykreEfdzqc1HZcESd6w2Q0Q6IzUneo= +github.com/Two-Hearts/notation-core-go v0.0.0-20240201050938-182af1affc30/go.mod h1:FaerqzzTnQn/bqZhph5WGhrGhFOFRDeghTvXAUG1SZA= github.com/Two-Hearts/tspclient-go v0.0.0-20240131082004-ba595813cc9d h1:RaFc+6Xkky04Y9DHb4BVhq9M1u3yhdoyccgDzcXwSgw= github.com/Two-Hearts/tspclient-go v0.0.0-20240131082004-ba595813cc9d/go.mod h1:Pgt9nPf69t08eVXdxjcfxZalElbQocRuP1DGSKZDpMs= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= diff --git a/verifier/verifier.go b/verifier/verifier.go index a3cad125..4e3b2f23 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -584,7 +584,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus ts, accuracy := info.Timestamp() timeStampLowerLimit = ts.Add(-accuracy) timeStampUpperLimit = ts.Add(accuracy) - fmt.Printf("tsa time range: [%v, %v]\n", timeStampLowerLimit, timeStampUpperLimit) + fmt.Printf("timestamp token time range: [%v, %v]\n", timeStampLowerLimit, timeStampUpperLimit) } for _, cert := range signerInfo.CertificateChain { fmt.Printf("cert validiy time range: [%v, %v]\n", cert.NotBefore, cert.NotAfter) From 3b98cd78ecf46576a156c76556cf2d3136128f63 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Fri, 22 Mar 2024 14:44:32 +0800 Subject: [PATCH 09/38] update sign with timestamping Signed-off-by: Patrick Zheng --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- signer/signer.go | 9 ++++++--- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 2bebcc57..86c544b2 100644 --- a/go.mod +++ b/go.mod @@ -10,14 +10,14 @@ require ( github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0 github.com/veraison/go-cose v1.1.0 - golang.org/x/crypto v0.20.0 + golang.org/x/crypto v0.21.0 golang.org/x/mod v0.15.0 oras.land/oras-go/v2 v2.4.0 ) require ( github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect - github.com/fxamacker/cbor/v2 v2.5.0 // indirect + github.com/fxamacker/cbor/v2 v2.6.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/google/uuid v1.3.1 // indirect @@ -25,6 +25,6 @@ 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-20240201050938-182af1affc30 +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240322064059-bf4ea64638b0 -replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240131082004-ba595813cc9d +replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240322031047-c33159600668 diff --git a/go.sum b/go.sum index aa08be9e..775ad187 100644 --- a/go.sum +++ b/go.sum @@ -1,16 +1,16 @@ 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-20240201050938-182af1affc30 h1:0EE/GVxacnp/KykreEfdzqc1HZcESd6w2Q0Q6IzUneo= -github.com/Two-Hearts/notation-core-go v0.0.0-20240201050938-182af1affc30/go.mod h1:FaerqzzTnQn/bqZhph5WGhrGhFOFRDeghTvXAUG1SZA= -github.com/Two-Hearts/tspclient-go v0.0.0-20240131082004-ba595813cc9d h1:RaFc+6Xkky04Y9DHb4BVhq9M1u3yhdoyccgDzcXwSgw= -github.com/Two-Hearts/tspclient-go v0.0.0-20240131082004-ba595813cc9d/go.mod h1:Pgt9nPf69t08eVXdxjcfxZalElbQocRuP1DGSKZDpMs= +github.com/Two-Hearts/notation-core-go v0.0.0-20240322064059-bf4ea64638b0 h1:CRM7IOv+86vhe82iD8EAGRbi/V+BhTXIEFwGegCP9uE= +github.com/Two-Hearts/notation-core-go v0.0.0-20240322064059-bf4ea64638b0/go.mod h1:cYwg3vrJsiuSC3ID7bG4/q6spGYbBTIr2mqG3ePwrqQ= +github.com/Two-Hearts/tspclient-go v0.0.0-20240322031047-c33159600668 h1:DwEjNM07LP9yYT17LMWEgv4g0UnjmORuyX2aqUgnURE= +github.com/Two-Hearts/tspclient-go v0.0.0-20240322031047-c33159600668/go.mod h1:Pgt9nPf69t08eVXdxjcfxZalElbQocRuP1DGSKZDpMs= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE= -github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= +github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= +github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= 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.6 h1:ert95MdbiG7aWo/oPYp9btL3KJlMPKnP58r09rI8T+A= @@ -40,8 +40,8 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg= -golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= diff --git a/signer/signer.go b/signer/signer.go index 90c1d03e..af693d36 100644 --- a/signer/signer.go +++ b/signer/signer.go @@ -144,9 +144,14 @@ func (s *GenericSigner) Sign(ctx context.Context, desc ocispec.Descriptor, opts return nil, nil, err } + var timestampErr *signature.TimestampError sig, err := sigEnv.Sign(signReq) if err != nil { - return nil, nil, err + if !errors.As(err, ×tampErr) { + return nil, nil, err + } + // warn on timestamping error, but do not fail the signing process + logger.Warnf("Failed to timestamp the signature. Error: %v", timestampErr) } envContent, err := sigEnv.Verify() @@ -156,8 +161,6 @@ func (s *GenericSigner) Sign(ctx context.Context, desc ocispec.Descriptor, opts if err := envelope.ValidatePayloadContentType(&envContent.Payload); err != nil { return nil, nil, err } - - // TODO: re-enable timestamping https://github.com/notaryproject/notation-go/issues/78 return sig, &envContent.SignerInfo, nil } From e5984163c3867f8f0014e20cd7ccdfa9a5548676 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Fri, 22 Mar 2024 16:25:08 +0800 Subject: [PATCH 10/38] update timestamp verification Signed-off-by: Patrick Zheng --- go.mod | 2 +- go.sum | 4 +- verifier/verifier.go | 163 ++++++++++++++++++++++--------------------- 3 files changed, 88 insertions(+), 81 deletions(-) diff --git a/go.mod b/go.mod index 5fb2a354..e8973f3f 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,6 @@ 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-20240322064059-bf4ea64638b0 +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240322074029-e6537801a769 replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240322031047-c33159600668 diff --git a/go.sum b/go.sum index 0dfc6f09..5b61fa77 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-20240322064059-bf4ea64638b0 h1:CRM7IOv+86vhe82iD8EAGRbi/V+BhTXIEFwGegCP9uE= -github.com/Two-Hearts/notation-core-go v0.0.0-20240322064059-bf4ea64638b0/go.mod h1:cYwg3vrJsiuSC3ID7bG4/q6spGYbBTIr2mqG3ePwrqQ= +github.com/Two-Hearts/notation-core-go v0.0.0-20240322074029-e6537801a769 h1:IjW5HyuNFL1rW29o/dCFoO4J5kXGCrEMOwNTwPyd6fs= +github.com/Two-Hearts/notation-core-go v0.0.0-20240322074029-e6537801a769/go.mod h1:cYwg3vrJsiuSC3ID7bG4/q6spGYbBTIr2mqG3ePwrqQ= github.com/Two-Hearts/tspclient-go v0.0.0-20240322031047-c33159600668 h1:DwEjNM07LP9yYT17LMWEgv4g0UnjmORuyX2aqUgnURE= github.com/Two-Hearts/tspclient-go v0.0.0-20240322031047-c33159600668/go.mod h1:Pgt9nPf69t08eVXdxjcfxZalElbQocRuP1DGSKZDpMs= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= diff --git a/verifier/verifier.go b/verifier/verifier.go index d2a1a5de..642ebefc 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -516,111 +516,118 @@ func verifyExpiry(outcome *notation.VerificationOutcome) *notation.ValidationRes } func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.TrustPolicy, x509TrustStore truststore.X509TrustStore, outcome *notation.VerificationOutcome) *notation.ValidationResult { - invalidTimestamp := false - var err error - if signerInfo := outcome.EnvelopeContent.SignerInfo; signerInfo.SignedAttributes.SigningScheme == signature.SigningSchemeX509 { - var timeStampLowerLimit time.Time - var timeStampUpperLimit time.Time - // TODO verify RFC3161 TSA signature if present (not in RC1) - // https://github.com/notaryproject/notation-go/issues/78 + var needTimestamp bool + for _, cert := range signerInfo.CertificateChain { + if time.Now().Before(cert.NotBefore) || time.Now().After(cert.NotAfter) { + // found at least one cert that current time is not in its + // validity period; need timestamp to continue this step + needTimestamp = true + break + } + } + if !needTimestamp { // this step is a success + return ¬ation.ValidationResult{ + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], + } + } if len(signerInfo.UnsignedAttributes.TimestampSignature) == 0 { - // if there is no TSA signature, then every certificate should be - // valid at the time of verification - timeStampLowerLimit = time.Now() - timeStampUpperLimit = timeStampLowerLimit - } else { - trustTSACerts, err := loadX509TSATrustStores(ctx, outcome.EnvelopeContent.SignerInfo.SignedAttributes.SigningScheme, trustPolicy, x509TrustStore) - if err != nil { - return ¬ation.ValidationResult{ - Error: err, - Type: trustpolicy.TypeAuthenticTimestamp, - Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], - } + // if there is no timestamp token, fail this step + return ¬ation.ValidationResult{ + Error: errors.New("current time is not in certificate chain validity period and no timestamp token was found in the signature envelope"), + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } - if len(trustTSACerts) < 1 { - return ¬ation.ValidationResult{ - Error: notation.ErrorVerificationInconclusive{Msg: "no trusted TSA certificate was found to verify authentic timestamp"}, - Type: trustpolicy.TypeAuthenticTimestamp, - Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], - } + } + trustTSACerts, err := loadX509TSATrustStores(ctx, outcome.EnvelopeContent.SignerInfo.SignedAttributes.SigningScheme, trustPolicy, x509TrustStore) + if err != nil { + return ¬ation.ValidationResult{ + Error: err, + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } - signedToken, err := tspclient.ParseSignedToken(ctx, signerInfo.UnsignedAttributes.TimestampSignature) - if err != nil { - return ¬ation.ValidationResult{ - Error: err, - Type: trustpolicy.TypeAuthenticTimestamp, - Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], - } + } + if len(trustTSACerts) < 1 { + return ¬ation.ValidationResult{ + Error: errors.New("no trusted TSA root certificate was found in the trust store"), + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } - roots := x509.NewCertPool() - for _, cert := range trustTSACerts { - roots.AddCert(cert) + } + signedToken, err := tspclient.ParseSignedToken(ctx, signerInfo.UnsignedAttributes.TimestampSignature) + if err != nil { + return ¬ation.ValidationResult{ + Error: err, + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], + } + } + roots := x509.NewCertPool() + for _, cert := range trustTSACerts { + roots.AddCert(cert) + } + opts := x509.VerifyOptions{ + Roots: roots, + } + // TODO: check revocation of cert chain + if _, err := signedToken.Verify(ctx, opts); err != nil { + return ¬ation.ValidationResult{ + Error: err, + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } - opts := x509.VerifyOptions{ - Roots: roots, + } + info, err := signedToken.Info() + if err != nil { + return ¬ation.ValidationResult{ + Error: err, + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } - if _, err := signedToken.Verify(ctx, opts); err != nil { - return ¬ation.ValidationResult{ - Error: err, - Type: trustpolicy.TypeAuthenticTimestamp, - Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], - } + } + if err := info.VerifyContent(signerInfo.Signature); err != nil { + return ¬ation.ValidationResult{ + Error: err, + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } - info, err := signedToken.Info() - if err != nil { + } + // consume the timestamp + ts, accuracy := info.Timestamp() + timeStampLowerLimit := ts.Add(-accuracy) + timeStampUpperLimit := ts.Add(accuracy) + fmt.Printf("timestamp token time range: [%v, %v]\n", timeStampLowerLimit, timeStampUpperLimit) + for _, cert := range signerInfo.CertificateChain { + if timeStampLowerLimit.Before(cert.NotBefore) { return ¬ation.ValidationResult{ - Error: err, + Error: fmt.Errorf("timestamp lower limit %q is before certificate %q validity period , it will be valid from %q", timeStampLowerLimit.Format(time.RFC1123Z), cert.Subject, cert.NotBefore.Format(time.RFC1123Z)), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - if err := info.VerifyContent(signerInfo.Signature); err != nil { + if timeStampUpperLimit.After(cert.NotAfter) { return ¬ation.ValidationResult{ - Error: err, + Error: fmt.Errorf("timestamp upper limit %q is after certificate %q validity period, it was expired at %q", timeStampUpperLimit.Format(time.RFC1123Z), cert.Subject, cert.NotAfter.Format(time.RFC1123Z)), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - ts, accuracy := info.Timestamp() - timeStampLowerLimit = ts.Add(-accuracy) - timeStampUpperLimit = ts.Add(accuracy) - fmt.Printf("timestamp token time range: [%v, %v]\n", timeStampLowerLimit, timeStampUpperLimit) - } - for _, cert := range signerInfo.CertificateChain { - fmt.Printf("cert validiy time range: [%v, %v]\n", cert.NotBefore, cert.NotAfter) - if timeStampLowerLimit.Before(cert.NotBefore) { - invalidTimestamp = true - err = fmt.Errorf("certificate %q is not valid yet, it will be valid from %q", cert.Subject, cert.NotBefore.Format(time.RFC1123Z)) - break - } - if timeStampUpperLimit.After(cert.NotAfter) { - invalidTimestamp = true - err = fmt.Errorf("certificate %q is not valid anymore, it was expired at %q", cert.Subject, cert.NotAfter.Format(time.RFC1123Z)) - break - } } } else if signerInfo.SignedAttributes.SigningScheme == signature.SigningSchemeX509SigningAuthority { authenticSigningTime := signerInfo.SignedAttributes.SigningTime - // TODO use authenticSigningTime from signerInfo - // https://github.com/notaryproject/notation-core-go/issues/38 for _, cert := range signerInfo.CertificateChain { if authenticSigningTime.Before(cert.NotBefore) || authenticSigningTime.After(cert.NotAfter) { - invalidTimestamp = true - err = fmt.Errorf("certificate %q was not valid when the digital signature was produced at %q", cert.Subject, authenticSigningTime.Format(time.RFC1123Z)) - break + return ¬ation.ValidationResult{ + Error: fmt.Errorf("certificate %q was not valid when the digital signature was produced at %q", cert.Subject, authenticSigningTime.Format(time.RFC1123Z)), + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], + } } } } - if invalidTimestamp { - return ¬ation.ValidationResult{ - Error: err, - Type: trustpolicy.TypeAuthenticTimestamp, - Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], - } - } - + // this step is a success return ¬ation.ValidationResult{ Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], From be2ea0e3a52ad7d3ca6d157cf2d19d1adf54b89a Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 27 Mar 2024 16:30:59 +0800 Subject: [PATCH 11/38] updated timestmap Signed-off-by: Patrick Zheng --- go.mod | 8 +++++--- go.sum | 8 ++++---- verifier/verifier.go | 8 ++++---- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index e8973f3f..2a08e992 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/notaryproject/notation-go -go 1.20 +go 1.21 + +toolchain go1.21.4 require ( github.com/go-ldap/ldap/v3 v3.4.6 @@ -25,6 +27,6 @@ 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-20240322074029-e6537801a769 +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240327082239-e085696162b1 -replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240322031047-c33159600668 +replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240327080830-9d2a35b7f3f0 diff --git a/go.sum b/go.sum index 5b61fa77..e94cf25e 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ 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-20240322074029-e6537801a769 h1:IjW5HyuNFL1rW29o/dCFoO4J5kXGCrEMOwNTwPyd6fs= -github.com/Two-Hearts/notation-core-go v0.0.0-20240322074029-e6537801a769/go.mod h1:cYwg3vrJsiuSC3ID7bG4/q6spGYbBTIr2mqG3ePwrqQ= -github.com/Two-Hearts/tspclient-go v0.0.0-20240322031047-c33159600668 h1:DwEjNM07LP9yYT17LMWEgv4g0UnjmORuyX2aqUgnURE= -github.com/Two-Hearts/tspclient-go v0.0.0-20240322031047-c33159600668/go.mod h1:Pgt9nPf69t08eVXdxjcfxZalElbQocRuP1DGSKZDpMs= +github.com/Two-Hearts/notation-core-go v0.0.0-20240327082239-e085696162b1 h1:VFaRt48d2PQ97WY3u4sWWgWpIBHSzid6UjiJG+0Ydcw= +github.com/Two-Hearts/notation-core-go v0.0.0-20240327082239-e085696162b1/go.mod h1:GsHR/83xmdubOk+77PlzIilthZNt+qCY4I9BxMKXbxg= +github.com/Two-Hearts/tspclient-go v0.0.0-20240327080830-9d2a35b7f3f0 h1:EbUo6vzeco2sq3ipHCL7JtsgAwOXNiM7BRRRLVp2o3U= +github.com/Two-Hearts/tspclient-go v0.0.0-20240327080830-9d2a35b7f3f0/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/verifier/verifier.go b/verifier/verifier.go index 642ebefc..6e793ca0 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -570,7 +570,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus opts := x509.VerifyOptions{ Roots: roots, } - // TODO: check revocation of cert chain + // TODO: validate and check revocation of cert chain if _, err := signedToken.Verify(ctx, opts); err != nil { return ¬ation.ValidationResult{ Error: err, @@ -586,15 +586,15 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - if err := info.VerifyContent(signerInfo.Signature); err != nil { + // validate and consume the timestamp + ts, accuracy, err := info.Timestamp(signerInfo.Signature) + if err != nil { return ¬ation.ValidationResult{ Error: err, Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - // consume the timestamp - ts, accuracy := info.Timestamp() timeStampLowerLimit := ts.Add(-accuracy) timeStampUpperLimit := ts.Add(accuracy) fmt.Printf("timestamp token time range: [%v, %v]\n", timeStampLowerLimit, timeStampUpperLimit) From c8f8e4ead7c787922b743f9862bbdf08fbf89ba0 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 27 Mar 2024 16:46:47 +0800 Subject: [PATCH 12/38] updated timestamp Signed-off-by: Patrick Zheng --- verifier/verifier.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/verifier/verifier.go b/verifier/verifier.go index 6e793ca0..f9b5cfff 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -31,6 +31,7 @@ import ( "github.com/notaryproject/notation-core-go/revocation" revocationresult "github.com/notaryproject/notation-core-go/revocation/result" "github.com/notaryproject/notation-core-go/signature" + nx509 "github.com/notaryproject/notation-core-go/x509" "github.com/notaryproject/notation-go" "github.com/notaryproject/notation-go/dir" "github.com/notaryproject/notation-go/internal/envelope" @@ -570,14 +571,24 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus opts := x509.VerifyOptions{ Roots: roots, } - // TODO: validate and check revocation of cert chain - if _, err := signedToken.Verify(ctx, opts); err != nil { + // TODO: check revocation of cert chain + tsaCertChain, err := signedToken.Verify(ctx, opts) + if err != nil { + return ¬ation.ValidationResult{ + Error: err, + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], + } + } + // validate TSA cert chain + if err := nx509.ValidateTimeStampingCertChain(tsaCertChain, nil); err != nil { return ¬ation.ValidationResult{ Error: err, Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } + // get the timestamp token info info, err := signedToken.Info() if err != nil { return ¬ation.ValidationResult{ @@ -586,7 +597,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - // validate and consume the timestamp + // validate the info and consume timestamp ts, accuracy, err := info.Timestamp(signerInfo.Signature) if err != nil { return ¬ation.ValidationResult{ From 200a071d04c065035b77840d614faa8303737cad Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Mon, 8 Apr 2024 11:07:51 +0800 Subject: [PATCH 13/38] added tsa cert chain revocation check Signed-off-by: Patrick Zheng --- go.mod | 2 +- go.sum | 4 +-- verifier/verifier.go | 76 +++++++++++++++++++++++++++++++++++--------- 3 files changed, 64 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index 0fa06802..41d100e9 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,6 @@ 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-20240327082239-e085696162b1 +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240408025912-2338257358ed replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240327080830-9d2a35b7f3f0 diff --git a/go.sum b/go.sum index ef723996..81ab8b82 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-20240327082239-e085696162b1 h1:VFaRt48d2PQ97WY3u4sWWgWpIBHSzid6UjiJG+0Ydcw= -github.com/Two-Hearts/notation-core-go v0.0.0-20240327082239-e085696162b1/go.mod h1:GsHR/83xmdubOk+77PlzIilthZNt+qCY4I9BxMKXbxg= +github.com/Two-Hearts/notation-core-go v0.0.0-20240408025912-2338257358ed h1:9HuLSjZdpwFQXxeL0N/dy/9N1nmxNsqnI6jHiud5Wjo= +github.com/Two-Hearts/notation-core-go v0.0.0-20240408025912-2338257358ed/go.mod h1:GsHR/83xmdubOk+77PlzIilthZNt+qCY4I9BxMKXbxg= github.com/Two-Hearts/tspclient-go v0.0.0-20240327080830-9d2a35b7f3f0 h1:EbUo6vzeco2sq3ipHCL7JtsgAwOXNiM7BRRRLVp2o3U= github.com/Two-Hearts/tspclient-go v0.0.0-20240327080830-9d2a35b7f3f0/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= diff --git a/verifier/verifier.go b/verifier/verifier.go index f9b5cfff..5e58994a 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -517,6 +517,9 @@ func verifyExpiry(outcome *notation.VerificationOutcome) *notation.ValidationRes } func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.TrustPolicy, x509TrustStore truststore.X509TrustStore, outcome *notation.VerificationOutcome) *notation.ValidationResult { + logger := log.GetLogger(ctx) + + // under signing scheme notary.x509 if signerInfo := outcome.EnvelopeContent.SignerInfo; signerInfo.SignedAttributes.SigningScheme == signature.SigningSchemeX509 { var needTimestamp bool for _, cert := range signerInfo.CertificateChain { @@ -571,7 +574,6 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus opts := x509.VerifyOptions{ Roots: roots, } - // TODO: check revocation of cert chain tsaCertChain, err := signedToken.Verify(ctx, opts) if err != nil { return ¬ation.ValidationResult{ @@ -609,6 +611,43 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus timeStampLowerLimit := ts.Add(-accuracy) timeStampUpperLimit := ts.Add(accuracy) fmt.Printf("timestamp token time range: [%v, %v]\n", timeStampLowerLimit, timeStampUpperLimit) + // TSA certificate chain revocation check + revocationClient, err := revocation.New(&http.Client{Timeout: 2 * time.Second}) + if err != nil { + return ¬ation.ValidationResult{ + Error: err, + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], + } + } + certResults, err := revocationClient.Validate(tsaCertChain, timeStampUpperLimit) + if err != nil { + logger.Debug("error while checking revocation status, err: %s", err.Error()) + return ¬ation.ValidationResult{ + Error: err, + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], + } + } + finalResult, problematicCertSubject := revocationFinalResult(certResults, tsaCertChain, logger) + switch finalResult { + case revocationresult.ResultOK: + logger.Debug("no verification impacting errors encountered while checking TSA certificate chain revocation, status is OK") + case revocationresult.ResultRevoked: + return ¬ation.ValidationResult{ + Error: fmt.Errorf("TSA certificate with subject %q is revoked", problematicCertSubject), + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], + } + default: + // revocationresult.ResultUnknown + return ¬ation.ValidationResult{ + Error: fmt.Errorf("TSA certificate with subject %q revocation status is unknown", problematicCertSubject), + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], + } + } + // timestamp core process for _, cert := range signerInfo.CertificateChain { if timeStampLowerLimit.Before(cert.NotBefore) { return ¬ation.ValidationResult{ @@ -626,6 +665,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus } } } else if signerInfo.SignedAttributes.SigningScheme == signature.SigningSchemeX509SigningAuthority { + // under signing scheme notary.x509.signingAuthority authenticSigningTime := signerInfo.SignedAttributes.SigningTime for _, cert := range signerInfo.CertificateChain { if authenticSigningTime.Before(cert.NotBefore) || authenticSigningTime.After(cert.NotAfter) { @@ -673,6 +713,23 @@ func verifyRevocation(outcome *notation.VerificationOutcome, r revocation.Revoca Type: trustpolicy.TypeRevocation, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeRevocation], } + finalResult, problematicCertSubject := revocationFinalResult(certResults, outcome.EnvelopeContent.SignerInfo.CertificateChain, logger) + switch finalResult { + case revocationresult.ResultOK: + logger.Debug("no verification impacting errors encountered while checking revocation, status is OK") + case revocationresult.ResultRevoked: + result.Error = fmt.Errorf("signing certificate with subject %q is revoked", problematicCertSubject) + default: + // revocationresult.ResultUnknown + result.Error = fmt.Errorf("signing certificate with subject %q revocation status is unknown", problematicCertSubject) + } + + return result +} + +// revocationFinalResult returns the final revocation result and problematic +// certificate subject if the final result is not ResultOK +func revocationFinalResult(certResults []*revocationresult.CertRevocationResult, certChain []*x509.Certificate, logger log.Logger) (revocationresult.Result, string) { finalResult := revocationresult.ResultUnknown numOKResults := 0 var problematicCertSubject string @@ -680,14 +737,14 @@ func verifyRevocation(outcome *notation.VerificationOutcome, r revocation.Revoca var revokedCertSubject string for i := len(certResults) - 1; i >= 0; i-- { if len(certResults[i].ServerResults) > 0 && certResults[i].ServerResults[0].Error != nil { - logger.Debugf("error for certificate #%d in chain with subject %v for server %q: %v", (i + 1), outcome.EnvelopeContent.SignerInfo.CertificateChain[i].Subject.String(), certResults[i].ServerResults[0].Server, certResults[i].ServerResults[0].Error) + logger.Debugf("error for certificate #%d in chain with subject %v for server %q: %v", (i + 1), certChain[i].Subject.String(), certResults[i].ServerResults[0].Server, certResults[i].ServerResults[0].Error) } if certResults[i].Result == revocationresult.ResultOK || certResults[i].Result == revocationresult.ResultNonRevokable { numOKResults++ } else { finalResult = certResults[i].Result - problematicCertSubject = outcome.EnvelopeContent.SignerInfo.CertificateChain[i].Subject.String() + problematicCertSubject = certChain[i].Subject.String() if certResults[i].Result == revocationresult.ResultRevoked { revokedFound = true revokedCertSubject = problematicCertSubject @@ -701,18 +758,7 @@ func verifyRevocation(outcome *notation.VerificationOutcome, r revocation.Revoca if numOKResults == len(certResults) { finalResult = revocationresult.ResultOK } - - switch finalResult { - case revocationresult.ResultOK: - logger.Debug("no verification impacting errors encountered while checking revocation, status is OK") - case revocationresult.ResultRevoked: - result.Error = fmt.Errorf("signing certificate with subject %q is revoked", problematicCertSubject) - default: - // revocationresult.ResultUnknown - result.Error = fmt.Errorf("signing certificate with subject %q revocation status is unknown", problematicCertSubject) - } - - return result + return finalResult, problematicCertSubject } func executePlugin(ctx context.Context, installedPlugin pluginframework.VerifyPlugin, trustPolicy *trustpolicy.TrustPolicy, capabilitiesToVerify []pluginframework.Capability, envelopeContent *signature.EnvelopeContent, pluginConfig map[string]string) (*pluginframework.VerifySignatureResponse, error) { From 53ee15c5b70c082b9fc5b47bfc9adf32f2b76e9a Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Mon, 8 Apr 2024 13:39:12 +0800 Subject: [PATCH 14/38] update tsa Signed-off-by: Patrick Zheng --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 41d100e9..50ec0b56 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,6 @@ 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-20240408025912-2338257358ed +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240408053347-db08071e1dba replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240327080830-9d2a35b7f3f0 diff --git a/go.sum b/go.sum index 81ab8b82..8f7b780c 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-20240408025912-2338257358ed h1:9HuLSjZdpwFQXxeL0N/dy/9N1nmxNsqnI6jHiud5Wjo= -github.com/Two-Hearts/notation-core-go v0.0.0-20240408025912-2338257358ed/go.mod h1:GsHR/83xmdubOk+77PlzIilthZNt+qCY4I9BxMKXbxg= +github.com/Two-Hearts/notation-core-go v0.0.0-20240408053347-db08071e1dba h1:NkrPabtr/MVAsD2NZVkJGkbvnOjoG6wCQPvXIPluyqw= +github.com/Two-Hearts/notation-core-go v0.0.0-20240408053347-db08071e1dba/go.mod h1:GsHR/83xmdubOk+77PlzIilthZNt+qCY4I9BxMKXbxg= github.com/Two-Hearts/tspclient-go v0.0.0-20240327080830-9d2a35b7f3f0 h1:EbUo6vzeco2sq3ipHCL7JtsgAwOXNiM7BRRRLVp2o3U= github.com/Two-Hearts/tspclient-go v0.0.0-20240327080830-9d2a35b7f3f0/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= From e5aaefee24f78f69e235112bbce68b98a88fc774 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Mon, 8 Apr 2024 14:13:47 +0800 Subject: [PATCH 15/38] added tsa ocsp check Signed-off-by: Patrick Zheng --- go.mod | 2 +- go.sum | 4 ++-- verifier/verifier.go | 10 +--------- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 50ec0b56..714b5b97 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,6 @@ 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-20240408053347-db08071e1dba +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240408061121-8c59a124c1ff replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240327080830-9d2a35b7f3f0 diff --git a/go.sum b/go.sum index 8f7b780c..4da3fd58 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-20240408053347-db08071e1dba h1:NkrPabtr/MVAsD2NZVkJGkbvnOjoG6wCQPvXIPluyqw= -github.com/Two-Hearts/notation-core-go v0.0.0-20240408053347-db08071e1dba/go.mod h1:GsHR/83xmdubOk+77PlzIilthZNt+qCY4I9BxMKXbxg= +github.com/Two-Hearts/notation-core-go v0.0.0-20240408061121-8c59a124c1ff h1:FiCD0T10oRjvO3ADmrkpaiYBZA1U91SfYEK8UTDqDbQ= +github.com/Two-Hearts/notation-core-go v0.0.0-20240408061121-8c59a124c1ff/go.mod h1:GsHR/83xmdubOk+77PlzIilthZNt+qCY4I9BxMKXbxg= github.com/Two-Hearts/tspclient-go v0.0.0-20240327080830-9d2a35b7f3f0 h1:EbUo6vzeco2sq3ipHCL7JtsgAwOXNiM7BRRRLVp2o3U= github.com/Two-Hearts/tspclient-go v0.0.0-20240327080830-9d2a35b7f3f0/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= diff --git a/verifier/verifier.go b/verifier/verifier.go index 5e58994a..ed27cb03 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -612,15 +612,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus timeStampUpperLimit := ts.Add(accuracy) fmt.Printf("timestamp token time range: [%v, %v]\n", timeStampLowerLimit, timeStampUpperLimit) // TSA certificate chain revocation check - revocationClient, err := revocation.New(&http.Client{Timeout: 2 * time.Second}) - if err != nil { - return ¬ation.ValidationResult{ - Error: err, - Type: trustpolicy.TypeAuthenticTimestamp, - Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], - } - } - certResults, err := revocationClient.Validate(tsaCertChain, timeStampUpperLimit) + certResults, err := revocation.ValidateTimestampCertChain(tsaCertChain, timeStampUpperLimit) if err != nil { logger.Debug("error while checking revocation status, err: %s", err.Error()) return ¬ation.ValidationResult{ From 2e674e4cb276fb982e0798e8ca1a2f10709b09af Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Mon, 8 Apr 2024 15:39:41 +0800 Subject: [PATCH 16/38] updated timestamping Signed-off-by: Patrick Zheng --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 714b5b97..909af822 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,6 @@ 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-20240408061121-8c59a124c1ff +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240408072948-cbde6f956cbe -replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240327080830-9d2a35b7f3f0 +replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240408072521-32657eeb0822 diff --git a/go.sum b/go.sum index 4da3fd58..a1b49112 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ 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-20240408061121-8c59a124c1ff h1:FiCD0T10oRjvO3ADmrkpaiYBZA1U91SfYEK8UTDqDbQ= -github.com/Two-Hearts/notation-core-go v0.0.0-20240408061121-8c59a124c1ff/go.mod h1:GsHR/83xmdubOk+77PlzIilthZNt+qCY4I9BxMKXbxg= -github.com/Two-Hearts/tspclient-go v0.0.0-20240327080830-9d2a35b7f3f0 h1:EbUo6vzeco2sq3ipHCL7JtsgAwOXNiM7BRRRLVp2o3U= -github.com/Two-Hearts/tspclient-go v0.0.0-20240327080830-9d2a35b7f3f0/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= +github.com/Two-Hearts/notation-core-go v0.0.0-20240408072948-cbde6f956cbe h1:BaNFMCJckSyFinHzrDw8K5hADfEp1dmdFHiDg5jb2K0= +github.com/Two-Hearts/notation-core-go v0.0.0-20240408072948-cbde6f956cbe/go.mod h1:etS+BOHG3eXU6yMSxMOjeZjrEQojZMb57/5uALoL6gY= +github.com/Two-Hearts/tspclient-go v0.0.0-20240408072521-32657eeb0822 h1:Fri3XvjQNGCHw7uZINZhk/p6qP9eYdjgyPltUQdB1f4= +github.com/Two-Hearts/tspclient-go v0.0.0-20240408072521-32657eeb0822/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= From 31de40f4956a6f9fe6d1f64f320444fafa9b4dee Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 10 Apr 2024 11:53:20 +0800 Subject: [PATCH 17/38] update Signed-off-by: Patrick Zheng --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 909af822..de270982 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,6 @@ 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-20240408072948-cbde6f956cbe +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240410034234-29bc7737eb3c -replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240408072521-32657eeb0822 +replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240410033505-94c3b3def019 diff --git a/go.sum b/go.sum index a1b49112..e2916252 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ 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-20240408072948-cbde6f956cbe h1:BaNFMCJckSyFinHzrDw8K5hADfEp1dmdFHiDg5jb2K0= -github.com/Two-Hearts/notation-core-go v0.0.0-20240408072948-cbde6f956cbe/go.mod h1:etS+BOHG3eXU6yMSxMOjeZjrEQojZMb57/5uALoL6gY= -github.com/Two-Hearts/tspclient-go v0.0.0-20240408072521-32657eeb0822 h1:Fri3XvjQNGCHw7uZINZhk/p6qP9eYdjgyPltUQdB1f4= -github.com/Two-Hearts/tspclient-go v0.0.0-20240408072521-32657eeb0822/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= +github.com/Two-Hearts/notation-core-go v0.0.0-20240410034234-29bc7737eb3c h1:hr6zVMTS6oEjGuNt7HSAG/41Ck7KQVG+UJxeiF6LHgI= +github.com/Two-Hearts/notation-core-go v0.0.0-20240410034234-29bc7737eb3c/go.mod h1:o3qDLatecAi3cQKnlnTk32mJNoNWovGFMiToV5n8KW4= +github.com/Two-Hearts/tspclient-go v0.0.0-20240410033505-94c3b3def019 h1:7SJ4FlWTmpXssu5J+XI7Fzn50tPsagFMEJSWmqv8nLU= +github.com/Two-Hearts/tspclient-go v0.0.0-20240410033505-94c3b3def019/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= From f4536db71936db371fea06f1cc8b04bbccd7a19f Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Thu, 11 Apr 2024 10:15:50 +0800 Subject: [PATCH 18/38] update Signed-off-by: Patrick Zheng --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index de270982..bc8cbfd6 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,6 @@ 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-20240410034234-29bc7737eb3c +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240411021119-44995cc7a08f replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240410033505-94c3b3def019 diff --git a/go.sum b/go.sum index e2916252..626f83d1 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-20240410034234-29bc7737eb3c h1:hr6zVMTS6oEjGuNt7HSAG/41Ck7KQVG+UJxeiF6LHgI= -github.com/Two-Hearts/notation-core-go v0.0.0-20240410034234-29bc7737eb3c/go.mod h1:o3qDLatecAi3cQKnlnTk32mJNoNWovGFMiToV5n8KW4= +github.com/Two-Hearts/notation-core-go v0.0.0-20240411021119-44995cc7a08f h1:OUQLq7PVUmvVMSuI7RV9IQwcLkqP2fr+DwCo7lMirM0= +github.com/Two-Hearts/notation-core-go v0.0.0-20240411021119-44995cc7a08f/go.mod h1:o3qDLatecAi3cQKnlnTk32mJNoNWovGFMiToV5n8KW4= github.com/Two-Hearts/tspclient-go v0.0.0-20240410033505-94c3b3def019 h1:7SJ4FlWTmpXssu5J+XI7Fzn50tPsagFMEJSWmqv8nLU= github.com/Two-Hearts/tspclient-go v0.0.0-20240410033505-94c3b3def019/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= From 998d79ff0b3c5c5450089adc89f59c15389680c9 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Thu, 11 Apr 2024 14:32:32 +0800 Subject: [PATCH 19/38] added skip tsa cert expire check Signed-off-by: Patrick Zheng --- notation.go | 19 ++++++++++++++++--- verifier/verifier.go | 33 +++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/notation.go b/notation.go index 34ddda88..56860703 100644 --- a/notation.go +++ b/notation.go @@ -319,6 +319,12 @@ type VerifierVerifyOptions struct { // UserMetadata contains key-value pairs that must be present in the // signature. UserMetadata map[string]string + + // SkipTimestampCertificateExpirationCheck skips timestamp certificate + // expiration check during timestamp countersignature verification. The + // time point been stamped still MUST be within timestamp certificate chain's + // validity period, and this check is always enforced. + SkipTimestampCertificateExpirationCheck bool } // Verifier is a generic interface for verifying an artifact. @@ -353,6 +359,12 @@ type VerifyOptions struct { // UserMetadata contains key-value pairs that must be present in the // signature UserMetadata map[string]string + + // SkipTimestampCertificateExpirationCheck skips timestamp certificate + // expiration check during timestamp countersignature verification. The + // time point been stamped still MUST be within timestamp certificate chain's + // validity period, and this check is always enforced. + SkipTimestampCertificateExpirationCheck bool } // Verify performs signature verification on each of the notation supported @@ -376,9 +388,10 @@ func Verify(ctx context.Context, verifier Verifier, repo registry.Repository, ve // opts to be passed in verifier.Verify() opts := VerifierVerifyOptions{ - ArtifactReference: verifyOpts.ArtifactReference, - PluginConfig: verifyOpts.PluginConfig, - UserMetadata: verifyOpts.UserMetadata, + ArtifactReference: verifyOpts.ArtifactReference, + PluginConfig: verifyOpts.PluginConfig, + UserMetadata: verifyOpts.UserMetadata, + SkipTimestampCertificateExpirationCheck: verifyOpts.SkipTimestampCertificateExpirationCheck, } if skipChecker, ok := verifier.(verifySkipper); ok { diff --git a/verifier/verifier.go b/verifier/verifier.go index ed27cb03..8080d9b8 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -157,7 +157,7 @@ func (v *verifier) Verify(ctx context.Context, desc ocispec.Descriptor, signatur logger.Debug("Skipping signature verification") return outcome, nil } - err = v.processSignature(ctx, signature, envelopeMediaType, trustPolicy, pluginConfig, outcome) + err = v.processSignature(ctx, signature, envelopeMediaType, trustPolicy, opts.SkipTimestampCertificateExpirationCheck, pluginConfig, outcome) if err != nil { outcome.Error = err @@ -188,7 +188,7 @@ func (v *verifier) Verify(ctx context.Context, desc ocispec.Descriptor, signatur return outcome, outcome.Error } -func (v *verifier) processSignature(ctx context.Context, sigBlob []byte, envelopeMediaType string, trustPolicy *trustpolicy.TrustPolicy, pluginConfig map[string]string, outcome *notation.VerificationOutcome) error { +func (v *verifier) processSignature(ctx context.Context, sigBlob []byte, envelopeMediaType string, trustPolicy *trustpolicy.TrustPolicy, skipTimestampCertExpirationCheck bool, pluginConfig map[string]string, outcome *notation.VerificationOutcome) error { logger := log.GetLogger(ctx) // verify integrity first. notation will always verify integrity no matter @@ -288,7 +288,7 @@ func (v *verifier) processSignature(ctx context.Context, sigBlob []byte, envelop // verify authentic timestamp logger.Debug("Validating authentic timestamp") - authenticTimestampResult := verifyAuthenticTimestamp(ctx, trustPolicy, v.trustStore, outcome) + authenticTimestampResult := verifyAuthenticTimestamp(ctx, trustPolicy, v.trustStore, skipTimestampCertExpirationCheck, outcome) outcome.VerificationResults = append(outcome.VerificationResults, authenticTimestampResult) logVerificationResult(logger, authenticTimestampResult) if isCriticalFailure(authenticTimestampResult) { @@ -516,7 +516,7 @@ func verifyExpiry(outcome *notation.VerificationOutcome) *notation.ValidationRes } } -func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.TrustPolicy, x509TrustStore truststore.X509TrustStore, outcome *notation.VerificationOutcome) *notation.ValidationResult { +func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.TrustPolicy, x509TrustStore truststore.X509TrustStore, skipTimestampCertExpirationCheck bool, outcome *notation.VerificationOutcome) *notation.ValidationResult { logger := log.GetLogger(ctx) // under signing scheme notary.x509 @@ -571,10 +571,11 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus for _, cert := range trustTSACerts { roots.AddCert(cert) } - opts := x509.VerifyOptions{ + timestampVerifyOpts := x509.VerifyOptions{ Roots: roots, } - tsaCertChain, err := signedToken.Verify(ctx, opts) + // get the timestamp token info + info, err := signedToken.Info() if err != nil { return ¬ation.ValidationResult{ Error: err, @@ -582,16 +583,20 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - // validate TSA cert chain - if err := nx509.ValidateTimeStampingCertChain(tsaCertChain, nil); err != nil { + // validate the info + ts, accuracy, err := info.Timestamp(signerInfo.Signature) + if err != nil { return ¬ation.ValidationResult{ Error: err, Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - // get the timestamp token info - info, err := signedToken.Info() + if skipTimestampCertExpirationCheck { + timestampVerifyOpts.CurrentTime = ts + } + // verify the timestamp countersignature + tsaCertChain, err := signedToken.Verify(ctx, timestampVerifyOpts) if err != nil { return ¬ation.ValidationResult{ Error: err, @@ -599,18 +604,18 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - // validate the info and consume timestamp - ts, accuracy, err := info.Timestamp(signerInfo.Signature) - if err != nil { + // validate timestamp certificate chain + if err := nx509.ValidateTimeStampingCertChain(tsaCertChain, nil); err != nil { return ¬ation.ValidationResult{ Error: err, Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } + // get the timestamp token time range timeStampLowerLimit := ts.Add(-accuracy) timeStampUpperLimit := ts.Add(accuracy) - fmt.Printf("timestamp token time range: [%v, %v]\n", timeStampLowerLimit, timeStampUpperLimit) + logger.Info("timestamp token time range: [%v, %v]\n", timeStampLowerLimit, timeStampUpperLimit) // TSA certificate chain revocation check certResults, err := revocation.ValidateTimestampCertChain(tsaCertChain, timeStampUpperLimit) if err != nil { From 545e1e76454e82f6b4bbcf3ea032292afcb176f8 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Thu, 11 Apr 2024 14:50:42 +0800 Subject: [PATCH 20/38] update Signed-off-by: Patrick Zheng --- notation.go | 26 ++++++++++++-------------- verifier/verifier.go | 10 +++++----- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/notation.go b/notation.go index 56860703..429c4c29 100644 --- a/notation.go +++ b/notation.go @@ -320,11 +320,10 @@ type VerifierVerifyOptions struct { // signature. UserMetadata map[string]string - // SkipTimestampCertificateExpirationCheck skips timestamp certificate - // expiration check during timestamp countersignature verification. The - // time point been stamped still MUST be within timestamp certificate chain's - // validity period, and this check is always enforced. - SkipTimestampCertificateExpirationCheck bool + // VerifyAtTimestampedTime verifies the timestamp countersignature at the + // time point been stamped. This time point MUST be within timestamp + // certificate chain's validity period. + VerifyAtTimestampedTime bool } // Verifier is a generic interface for verifying an artifact. @@ -360,11 +359,10 @@ type VerifyOptions struct { // signature UserMetadata map[string]string - // SkipTimestampCertificateExpirationCheck skips timestamp certificate - // expiration check during timestamp countersignature verification. The - // time point been stamped still MUST be within timestamp certificate chain's - // validity period, and this check is always enforced. - SkipTimestampCertificateExpirationCheck bool + // VerifyAtTimestampedTime verifies the timestamp countersignature at the + // time point been stamped. This time point MUST be within timestamp + // certificate chain's validity period. + VerifyAtTimestampedTime bool } // Verify performs signature verification on each of the notation supported @@ -388,10 +386,10 @@ func Verify(ctx context.Context, verifier Verifier, repo registry.Repository, ve // opts to be passed in verifier.Verify() opts := VerifierVerifyOptions{ - ArtifactReference: verifyOpts.ArtifactReference, - PluginConfig: verifyOpts.PluginConfig, - UserMetadata: verifyOpts.UserMetadata, - SkipTimestampCertificateExpirationCheck: verifyOpts.SkipTimestampCertificateExpirationCheck, + ArtifactReference: verifyOpts.ArtifactReference, + PluginConfig: verifyOpts.PluginConfig, + UserMetadata: verifyOpts.UserMetadata, + VerifyAtTimestampedTime: verifyOpts.VerifyAtTimestampedTime, } if skipChecker, ok := verifier.(verifySkipper); ok { diff --git a/verifier/verifier.go b/verifier/verifier.go index 8080d9b8..453d10e4 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -157,7 +157,7 @@ func (v *verifier) Verify(ctx context.Context, desc ocispec.Descriptor, signatur logger.Debug("Skipping signature verification") return outcome, nil } - err = v.processSignature(ctx, signature, envelopeMediaType, trustPolicy, opts.SkipTimestampCertificateExpirationCheck, pluginConfig, outcome) + err = v.processSignature(ctx, signature, envelopeMediaType, trustPolicy, opts.VerifyAtTimestampedTime, pluginConfig, outcome) if err != nil { outcome.Error = err @@ -188,7 +188,7 @@ func (v *verifier) Verify(ctx context.Context, desc ocispec.Descriptor, signatur return outcome, outcome.Error } -func (v *verifier) processSignature(ctx context.Context, sigBlob []byte, envelopeMediaType string, trustPolicy *trustpolicy.TrustPolicy, skipTimestampCertExpirationCheck bool, pluginConfig map[string]string, outcome *notation.VerificationOutcome) error { +func (v *verifier) processSignature(ctx context.Context, sigBlob []byte, envelopeMediaType string, trustPolicy *trustpolicy.TrustPolicy, verifyAtTimestampedTime bool, pluginConfig map[string]string, outcome *notation.VerificationOutcome) error { logger := log.GetLogger(ctx) // verify integrity first. notation will always verify integrity no matter @@ -288,7 +288,7 @@ func (v *verifier) processSignature(ctx context.Context, sigBlob []byte, envelop // verify authentic timestamp logger.Debug("Validating authentic timestamp") - authenticTimestampResult := verifyAuthenticTimestamp(ctx, trustPolicy, v.trustStore, skipTimestampCertExpirationCheck, outcome) + authenticTimestampResult := verifyAuthenticTimestamp(ctx, trustPolicy, v.trustStore, verifyAtTimestampedTime, outcome) outcome.VerificationResults = append(outcome.VerificationResults, authenticTimestampResult) logVerificationResult(logger, authenticTimestampResult) if isCriticalFailure(authenticTimestampResult) { @@ -516,7 +516,7 @@ func verifyExpiry(outcome *notation.VerificationOutcome) *notation.ValidationRes } } -func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.TrustPolicy, x509TrustStore truststore.X509TrustStore, skipTimestampCertExpirationCheck bool, outcome *notation.VerificationOutcome) *notation.ValidationResult { +func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.TrustPolicy, x509TrustStore truststore.X509TrustStore, verifyAtTimestampedTime bool, outcome *notation.VerificationOutcome) *notation.ValidationResult { logger := log.GetLogger(ctx) // under signing scheme notary.x509 @@ -592,7 +592,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - if skipTimestampCertExpirationCheck { + if verifyAtTimestampedTime { timestampVerifyOpts.CurrentTime = ts } // verify the timestamp countersignature From 527b84a2b66d2e61f4453ef7c786a9717adf6d6f Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 16 Apr 2024 16:41:07 +0800 Subject: [PATCH 21/38] added timestamp trust policy Signed-off-by: Patrick Zheng --- notation.go | 17 +++-------------- verifier/trustpolicy/trustpolicy.go | 17 +++++++++++++++-- verifier/verifier.go | 18 +++++++++++++----- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/notation.go b/notation.go index 429c4c29..34ddda88 100644 --- a/notation.go +++ b/notation.go @@ -319,11 +319,6 @@ type VerifierVerifyOptions struct { // UserMetadata contains key-value pairs that must be present in the // signature. UserMetadata map[string]string - - // VerifyAtTimestampedTime verifies the timestamp countersignature at the - // time point been stamped. This time point MUST be within timestamp - // certificate chain's validity period. - VerifyAtTimestampedTime bool } // Verifier is a generic interface for verifying an artifact. @@ -358,11 +353,6 @@ type VerifyOptions struct { // UserMetadata contains key-value pairs that must be present in the // signature UserMetadata map[string]string - - // VerifyAtTimestampedTime verifies the timestamp countersignature at the - // time point been stamped. This time point MUST be within timestamp - // certificate chain's validity period. - VerifyAtTimestampedTime bool } // Verify performs signature verification on each of the notation supported @@ -386,10 +376,9 @@ func Verify(ctx context.Context, verifier Verifier, repo registry.Repository, ve // opts to be passed in verifier.Verify() opts := VerifierVerifyOptions{ - ArtifactReference: verifyOpts.ArtifactReference, - PluginConfig: verifyOpts.PluginConfig, - UserMetadata: verifyOpts.UserMetadata, - VerifyAtTimestampedTime: verifyOpts.VerifyAtTimestampedTime, + ArtifactReference: verifyOpts.ArtifactReference, + PluginConfig: verifyOpts.PluginConfig, + UserMetadata: verifyOpts.UserMetadata, } if skipChecker, ok := verifier.(verifySkipper); ok { diff --git a/verifier/trustpolicy/trustpolicy.go b/verifier/trustpolicy/trustpolicy.go index b0aaede5..b28ec9dd 100644 --- a/verifier/trustpolicy/trustpolicy.go +++ b/verifier/trustpolicy/trustpolicy.go @@ -134,7 +134,7 @@ var ( } ) -var supportedPolicyVersions = []string{"1.0"} +var supportedPolicyVersions = []string{"1.0", "1.1"} // Document represents a trustPolicy.json document type Document struct { @@ -156,6 +156,9 @@ type TrustPolicy struct { // SignatureVerification setting for this policy statement SignatureVerification SignatureVerification `json:"signatureVerification"` + // TimestampVerification setting for this policy statement + TimestampVerification *TimestampVerification `json:"timestampVerification,omitempty"` + // TrustStores this policy statement uses TrustStores []string `json:"trustStores,omitempty"` @@ -169,6 +172,12 @@ type SignatureVerification struct { Override map[ValidationType]ValidationAction `json:"override,omitempty"` } +// TimestampVerification represents timestamp countersignature verification +// configuration in a trust policy +type TimestampVerification struct { + AtTimestampedTime bool `json:"atTimestampedTime"` +} + // Validate validates a policy document according to its version's rule set. // if any rule is violated, returns an error func (policyDoc *Document) Validate() error { @@ -185,7 +194,6 @@ func (policyDoc *Document) Validate() error { return fmt.Errorf("trust policy document uses unsupported version %q", policyDoc.Version) } - // Validate the policy according to 1.0 rules if len(policyDoc.TrustPolicies) == 0 { return errors.New("trust policy document can not have zero trust policy statements") } @@ -206,6 +214,11 @@ func (policyDoc *Document) Validate() error { return fmt.Errorf("trust policy statement %q has invalid signatureVerification: %w", statement.Name, err) } + // Verify timestamp verification is valid + if statement.TimestampVerification != nil && policyDoc.Version != "1.1" { + return fmt.Errorf("trust policy document version must be 1.1 to support timestamp verification, but got %q", policyDoc.Version) + } + // Any signature verification other than "skip" needs a trust store and // trusted identities if verificationLevel.Name == "skip" { diff --git a/verifier/verifier.go b/verifier/verifier.go index 453d10e4..a07bfd0c 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -157,7 +157,7 @@ func (v *verifier) Verify(ctx context.Context, desc ocispec.Descriptor, signatur logger.Debug("Skipping signature verification") return outcome, nil } - err = v.processSignature(ctx, signature, envelopeMediaType, trustPolicy, opts.VerifyAtTimestampedTime, pluginConfig, outcome) + err = v.processSignature(ctx, signature, envelopeMediaType, trustPolicy, pluginConfig, outcome) if err != nil { outcome.Error = err @@ -188,7 +188,7 @@ func (v *verifier) Verify(ctx context.Context, desc ocispec.Descriptor, signatur return outcome, outcome.Error } -func (v *verifier) processSignature(ctx context.Context, sigBlob []byte, envelopeMediaType string, trustPolicy *trustpolicy.TrustPolicy, verifyAtTimestampedTime bool, pluginConfig map[string]string, outcome *notation.VerificationOutcome) error { +func (v *verifier) processSignature(ctx context.Context, sigBlob []byte, envelopeMediaType string, trustPolicy *trustpolicy.TrustPolicy, pluginConfig map[string]string, outcome *notation.VerificationOutcome) error { logger := log.GetLogger(ctx) // verify integrity first. notation will always verify integrity no matter @@ -288,7 +288,7 @@ func (v *verifier) processSignature(ctx context.Context, sigBlob []byte, envelop // verify authentic timestamp logger.Debug("Validating authentic timestamp") - authenticTimestampResult := verifyAuthenticTimestamp(ctx, trustPolicy, v.trustStore, verifyAtTimestampedTime, outcome) + authenticTimestampResult := verifyAuthenticTimestamp(ctx, trustPolicy, v.trustStore, outcome) outcome.VerificationResults = append(outcome.VerificationResults, authenticTimestampResult) logVerificationResult(logger, authenticTimestampResult) if isCriticalFailure(authenticTimestampResult) { @@ -516,7 +516,7 @@ func verifyExpiry(outcome *notation.VerificationOutcome) *notation.ValidationRes } } -func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.TrustPolicy, x509TrustStore truststore.X509TrustStore, verifyAtTimestampedTime bool, outcome *notation.VerificationOutcome) *notation.ValidationResult { +func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.TrustPolicy, x509TrustStore truststore.X509TrustStore, outcome *notation.VerificationOutcome) *notation.ValidationResult { logger := log.GetLogger(ctx) // under signing scheme notary.x509 @@ -544,6 +544,14 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } + if trustPolicy.TimestampVerification == nil { + // if there is no timestamp verification configuration in trust policy + return ¬ation.ValidationResult{ + Error: errors.New("current time is not in certificate chain validity period and no timestamp verification configuration was found in trust policy"), + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], + } + } trustTSACerts, err := loadX509TSATrustStores(ctx, outcome.EnvelopeContent.SignerInfo.SignedAttributes.SigningScheme, trustPolicy, x509TrustStore) if err != nil { return ¬ation.ValidationResult{ @@ -592,7 +600,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - if verifyAtTimestampedTime { + if trustPolicy.TimestampVerification.AtTimestampedTime { timestampVerifyOpts.CurrentTime = ts } // verify the timestamp countersignature From 1e21a3d0356e7061bd52eb389ba729c81d402cbd Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 17 Apr 2024 11:19:36 +0800 Subject: [PATCH 22/38] update Signed-off-by: Patrick Zheng --- verifier/trustpolicy/trustpolicy.go | 1 + 1 file changed, 1 insertion(+) diff --git a/verifier/trustpolicy/trustpolicy.go b/verifier/trustpolicy/trustpolicy.go index b28ec9dd..015553e3 100644 --- a/verifier/trustpolicy/trustpolicy.go +++ b/verifier/trustpolicy/trustpolicy.go @@ -407,6 +407,7 @@ func (t *TrustPolicy) clone() *TrustPolicy { return &TrustPolicy{ Name: t.Name, SignatureVerification: t.SignatureVerification, + TimestampVerification: t.TimestampVerification, RegistryScopes: append([]string(nil), t.RegistryScopes...), TrustedIdentities: append([]string(nil), t.TrustedIdentities...), TrustStores: append([]string(nil), t.TrustStores...), From 27a5b3565c7e5fd328363ec27343151c1da41640 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 17 Apr 2024 12:46:03 +0800 Subject: [PATCH 23/38] update Signed-off-by: Patrick Zheng --- verifier/trustpolicy/trustpolicy.go | 8 ++++++++ verifier/verifier.go | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/verifier/trustpolicy/trustpolicy.go b/verifier/trustpolicy/trustpolicy.go index 015553e3..112719f8 100644 --- a/verifier/trustpolicy/trustpolicy.go +++ b/verifier/trustpolicy/trustpolicy.go @@ -166,6 +166,14 @@ type TrustPolicy struct { TrustedIdentities []string `json:"trustedIdentities,omitempty"` } +func (t *TrustPolicy) String() string { + policyJson, err := json.Marshal(t) + if err != nil { + return "" + } + return string(policyJson) +} + // SignatureVerification represents verification configuration in a trust policy type SignatureVerification struct { VerificationLevel string `json:"level"` diff --git a/verifier/verifier.go b/verifier/verifier.go index a07bfd0c..36478a54 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -144,7 +144,7 @@ func (v *verifier) Verify(ctx context.Context, desc ocispec.Descriptor, signatur if err != nil { return nil, notation.ErrorNoApplicableTrustPolicy{Msg: err.Error()} } - logger.Infof("Trust policy configuration: %+v", trustPolicy) + logger.Infof("Trust policy configuration: %q", trustPolicy.String()) // ignore the error since we already validated the policy document verificationLevel, _ := trustPolicy.SignatureVerification.GetVerificationLevel() @@ -623,7 +623,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus // get the timestamp token time range timeStampLowerLimit := ts.Add(-accuracy) timeStampUpperLimit := ts.Add(accuracy) - logger.Info("timestamp token time range: [%v, %v]\n", timeStampLowerLimit, timeStampUpperLimit) + logger.Infof("timestamp token time range: [%v, %v]\n", timeStampLowerLimit, timeStampUpperLimit) // TSA certificate chain revocation check certResults, err := revocation.ValidateTimestampCertChain(tsaCertChain, timeStampUpperLimit) if err != nil { @@ -656,7 +656,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus for _, cert := range signerInfo.CertificateChain { if timeStampLowerLimit.Before(cert.NotBefore) { return ¬ation.ValidationResult{ - Error: fmt.Errorf("timestamp lower limit %q is before certificate %q validity period , it will be valid from %q", timeStampLowerLimit.Format(time.RFC1123Z), cert.Subject, cert.NotBefore.Format(time.RFC1123Z)), + Error: fmt.Errorf("timestamp lower limit %q is before certificate %q validity period, it will be valid from %q", timeStampLowerLimit.Format(time.RFC1123Z), cert.Subject, cert.NotBefore.Format(time.RFC1123Z)), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } From 90424bd1cdb54418e895a4f5efdc0d98a2181d3a Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 17 Apr 2024 13:01:45 +0800 Subject: [PATCH 24/38] update Signed-off-by: Patrick Zheng --- verifier/trustpolicy/trustpolicy.go | 7 ++----- verifier/verifier.go | 4 ++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/verifier/trustpolicy/trustpolicy.go b/verifier/trustpolicy/trustpolicy.go index 112719f8..dc1b1efb 100644 --- a/verifier/trustpolicy/trustpolicy.go +++ b/verifier/trustpolicy/trustpolicy.go @@ -166,12 +166,9 @@ type TrustPolicy struct { TrustedIdentities []string `json:"trustedIdentities,omitempty"` } +// String returns print out of TrustPolicy as a string func (t *TrustPolicy) String() string { - policyJson, err := json.Marshal(t) - if err != nil { - return "" - } - return string(policyJson) + return fmt.Sprintf("Name: %s, RegistryScopes: %v, SignatureVerification: %+v, TimestampVerification: %+v, TrustStores: %v, TrustedIdentities: %v", t.Name, t.RegistryScopes, t.SignatureVerification, t.TimestampVerification, t.TrustStores, t.TrustedIdentities) } // SignatureVerification represents verification configuration in a trust policy diff --git a/verifier/verifier.go b/verifier/verifier.go index 36478a54..eb0e6a44 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -144,7 +144,7 @@ func (v *verifier) Verify(ctx context.Context, desc ocispec.Descriptor, signatur if err != nil { return nil, notation.ErrorNoApplicableTrustPolicy{Msg: err.Error()} } - logger.Infof("Trust policy configuration: %q", trustPolicy.String()) + logger.Infof("Trust policy configuration: %+v", trustPolicy) // ignore the error since we already validated the policy document verificationLevel, _ := trustPolicy.SignatureVerification.GetVerificationLevel() @@ -623,7 +623,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus // get the timestamp token time range timeStampLowerLimit := ts.Add(-accuracy) timeStampUpperLimit := ts.Add(accuracy) - logger.Infof("timestamp token time range: [%v, %v]\n", timeStampLowerLimit, timeStampUpperLimit) + logger.Infof("timestamp token time range: [%v, %v]", timeStampLowerLimit, timeStampUpperLimit) // TSA certificate chain revocation check certResults, err := revocation.ValidateTimestampCertChain(tsaCertChain, timeStampUpperLimit) if err != nil { From d7a03968d75f38809c66959a85d50de9d3d86ba2 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 17 Apr 2024 16:57:55 +0800 Subject: [PATCH 25/38] timestamp trust policy Signed-off-by: Patrick Zheng --- verifier/trustpolicy/trustpolicy.go | 3 ++- verifier/verifier.go | 16 ++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/verifier/trustpolicy/trustpolicy.go b/verifier/trustpolicy/trustpolicy.go index dc1b1efb..e5297e78 100644 --- a/verifier/trustpolicy/trustpolicy.go +++ b/verifier/trustpolicy/trustpolicy.go @@ -180,7 +180,8 @@ type SignatureVerification struct { // TimestampVerification represents timestamp countersignature verification // configuration in a trust policy type TimestampVerification struct { - AtTimestampedTime bool `json:"atTimestampedTime"` + Enable bool `json:"enable,omitempty"` + ExpiryRelaxed bool `json:"expiryRelaxed,omitempty"` } // Validate validates a policy document according to its version's rule set. diff --git a/verifier/verifier.go b/verifier/verifier.go index eb0e6a44..92866c06 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -521,16 +521,16 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus // under signing scheme notary.x509 if signerInfo := outcome.EnvelopeContent.SignerInfo; signerInfo.SignedAttributes.SigningScheme == signature.SigningSchemeX509 { - var needTimestamp bool + var requireTimestampVerification bool for _, cert := range signerInfo.CertificateChain { if time.Now().Before(cert.NotBefore) || time.Now().After(cert.NotAfter) { // found at least one cert that current time is not in its - // validity period; need timestamp to continue this step - needTimestamp = true + // validity period; require timestamp to continue this step + requireTimestampVerification = true break } } - if !needTimestamp { // this step is a success + if !requireTimestampVerification { // this step is a success return ¬ation.ValidationResult{ Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], @@ -544,10 +544,10 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - if trustPolicy.TimestampVerification == nil { - // if there is no timestamp verification configuration in trust policy + if trustPolicy.TimestampVerification == nil || !trustPolicy.TimestampVerification.Enable { + // if timestamp verification is disabled in trust policy return ¬ation.ValidationResult{ - Error: errors.New("current time is not in certificate chain validity period and no timestamp verification configuration was found in trust policy"), + Error: errors.New("current time is not in certificate chain validity period and timestamp verification is disabled in trust policy"), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } @@ -600,7 +600,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - if trustPolicy.TimestampVerification.AtTimestampedTime { + if trustPolicy.TimestampVerification.ExpiryRelaxed { timestampVerifyOpts.CurrentTime = ts } // verify the timestamp countersignature From 12ac6b696d7facd01b84e02514d0d9c04bf069bd Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Thu, 18 Apr 2024 13:02:30 +0800 Subject: [PATCH 26/38] update Signed-off-by: Patrick Zheng --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index bc8cbfd6..54bcabc6 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,6 @@ 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-20240411021119-44995cc7a08f +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240418044922-14d05519328b replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240410033505-94c3b3def019 diff --git a/go.sum b/go.sum index 626f83d1..70efd74f 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-20240411021119-44995cc7a08f h1:OUQLq7PVUmvVMSuI7RV9IQwcLkqP2fr+DwCo7lMirM0= -github.com/Two-Hearts/notation-core-go v0.0.0-20240411021119-44995cc7a08f/go.mod h1:o3qDLatecAi3cQKnlnTk32mJNoNWovGFMiToV5n8KW4= +github.com/Two-Hearts/notation-core-go v0.0.0-20240418044922-14d05519328b h1:a27dSIOWWw7rJSD2ebmWUYjwhhhPnIaMGlqPl9OuCmI= +github.com/Two-Hearts/notation-core-go v0.0.0-20240418044922-14d05519328b/go.mod h1:o3qDLatecAi3cQKnlnTk32mJNoNWovGFMiToV5n8KW4= github.com/Two-Hearts/tspclient-go v0.0.0-20240410033505-94c3b3def019 h1:7SJ4FlWTmpXssu5J+XI7Fzn50tPsagFMEJSWmqv8nLU= github.com/Two-Hearts/tspclient-go v0.0.0-20240410033505-94c3b3def019/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= From 6e363033966121d09cab90298c73703a02f11fe0 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Thu, 18 Apr 2024 13:06:03 +0800 Subject: [PATCH 27/38] update Signed-off-by: Patrick Zheng --- verifier/verifier.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/verifier/verifier.go b/verifier/verifier.go index 92866c06..9c3d3666 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -545,7 +545,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus } } if trustPolicy.TimestampVerification == nil || !trustPolicy.TimestampVerification.Enable { - // if timestamp verification is disabled in trust policy + // if timestamp verification is disabled by trust policy return ¬ation.ValidationResult{ Error: errors.New("current time is not in certificate chain validity period and timestamp verification is disabled in trust policy"), Type: trustpolicy.TypeAuthenticTimestamp, @@ -652,7 +652,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - // timestamp core process + // timestamp validation core process for _, cert := range signerInfo.CertificateChain { if timeStampLowerLimit.Before(cert.NotBefore) { return ¬ation.ValidationResult{ From bea674c16d59c2676d5a04de35d3a8b56528cca2 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Thu, 18 Apr 2024 13:22:57 +0800 Subject: [PATCH 28/38] error msg Signed-off-by: Patrick Zheng --- verifier/verifier.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/verifier/verifier.go b/verifier/verifier.go index 9c3d3666..1207c099 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -522,11 +522,13 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus // under signing scheme notary.x509 if signerInfo := outcome.EnvelopeContent.SignerInfo; signerInfo.SignedAttributes.SigningScheme == signature.SigningSchemeX509 { var requireTimestampVerification bool + var invalidCertificate *x509.Certificate for _, cert := range signerInfo.CertificateChain { if time.Now().Before(cert.NotBefore) || time.Now().After(cert.NotAfter) { // found at least one cert that current time is not in its // validity period; require timestamp to continue this step requireTimestampVerification = true + invalidCertificate = cert break } } @@ -539,7 +541,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus if len(signerInfo.UnsignedAttributes.TimestampSignature) == 0 { // if there is no timestamp token, fail this step return ¬ation.ValidationResult{ - Error: errors.New("current time is not in certificate chain validity period and no timestamp token was found in the signature envelope"), + Error: fmt.Errorf("current time is not in certificate %q validity period [%q, %q] and no timestamp token was found in the signature envelope", invalidCertificate.Subject, invalidCertificate.NotBefore.Format(time.RFC1123Z), invalidCertificate.NotAfter.Format(time.RFC1123Z)), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } @@ -547,7 +549,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus if trustPolicy.TimestampVerification == nil || !trustPolicy.TimestampVerification.Enable { // if timestamp verification is disabled by trust policy return ¬ation.ValidationResult{ - Error: errors.New("current time is not in certificate chain validity period and timestamp verification is disabled in trust policy"), + Error: fmt.Errorf("current time is not in certificate %q validity period [%q, %q] and timestamp verification is disabled by trust policy", invalidCertificate.Subject, invalidCertificate.NotBefore.Format(time.RFC1123Z), invalidCertificate.NotAfter.Format(time.RFC1123Z)), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } From a510cbf82e696ca36b9d069c37db287db4cf59f5 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 8 May 2024 16:42:11 +0800 Subject: [PATCH 29/38] updated per spec Signed-off-by: Patrick Zheng --- go.mod | 6 ++-- go.sum | 11 +++--- verifier/trustpolicy/trustpolicy.go | 23 +------------ verifier/verifier.go | 53 ++++++++++++----------------- 4 files changed, 32 insertions(+), 61 deletions(-) diff --git a/go.mod b/go.mod index 111e7715..a90b67ab 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0 github.com/veraison/go-cose v1.1.0 - golang.org/x/crypto v0.21.0 + golang.org/x/crypto v0.22.0 golang.org/x/mod v0.17.0 oras.land/oras-go/v2 v2.5.0 ) @@ -25,6 +25,6 @@ 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-20240418044922-14d05519328b +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240508074737-fc1cb3d28098 -replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240410033505-94c3b3def019 +replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240508074024-ec1725d6dc9b diff --git a/go.sum b/go.sum index 4527d6f5..85446a04 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ 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-20240418044922-14d05519328b h1:a27dSIOWWw7rJSD2ebmWUYjwhhhPnIaMGlqPl9OuCmI= -github.com/Two-Hearts/notation-core-go v0.0.0-20240418044922-14d05519328b/go.mod h1:o3qDLatecAi3cQKnlnTk32mJNoNWovGFMiToV5n8KW4= -github.com/Two-Hearts/tspclient-go v0.0.0-20240410033505-94c3b3def019 h1:7SJ4FlWTmpXssu5J+XI7Fzn50tPsagFMEJSWmqv8nLU= -github.com/Two-Hearts/tspclient-go v0.0.0-20240410033505-94c3b3def019/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= +github.com/Two-Hearts/notation-core-go v0.0.0-20240508074737-fc1cb3d28098 h1:xfyYkDuH7MXz5+Pd5wvRSlARyDUp9UM7I23OzlbIMsA= +github.com/Two-Hearts/notation-core-go v0.0.0-20240508074737-fc1cb3d28098/go.mod h1:wkaaIh2fMRBO3j48U/F64tZOCqcYkuKOiA9o7ERkXXU= +github.com/Two-Hearts/tspclient-go v0.0.0-20240508074024-ec1725d6dc9b h1:pNICDsr2or3iCRyjB8UnrG/N7mhP6H6yIfx3F8Zkcqk= +github.com/Two-Hearts/tspclient-go v0.0.0-20240508074024-ec1725d6dc9b/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= 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= @@ -61,8 +61,9 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= diff --git a/verifier/trustpolicy/trustpolicy.go b/verifier/trustpolicy/trustpolicy.go index e5297e78..bc74432d 100644 --- a/verifier/trustpolicy/trustpolicy.go +++ b/verifier/trustpolicy/trustpolicy.go @@ -134,7 +134,7 @@ var ( } ) -var supportedPolicyVersions = []string{"1.0", "1.1"} +var supportedPolicyVersions = []string{"1.0"} // Document represents a trustPolicy.json document type Document struct { @@ -156,9 +156,6 @@ type TrustPolicy struct { // SignatureVerification setting for this policy statement SignatureVerification SignatureVerification `json:"signatureVerification"` - // TimestampVerification setting for this policy statement - TimestampVerification *TimestampVerification `json:"timestampVerification,omitempty"` - // TrustStores this policy statement uses TrustStores []string `json:"trustStores,omitempty"` @@ -166,24 +163,12 @@ type TrustPolicy struct { TrustedIdentities []string `json:"trustedIdentities,omitempty"` } -// String returns print out of TrustPolicy as a string -func (t *TrustPolicy) String() string { - return fmt.Sprintf("Name: %s, RegistryScopes: %v, SignatureVerification: %+v, TimestampVerification: %+v, TrustStores: %v, TrustedIdentities: %v", t.Name, t.RegistryScopes, t.SignatureVerification, t.TimestampVerification, t.TrustStores, t.TrustedIdentities) -} - // SignatureVerification represents verification configuration in a trust policy type SignatureVerification struct { VerificationLevel string `json:"level"` Override map[ValidationType]ValidationAction `json:"override,omitempty"` } -// TimestampVerification represents timestamp countersignature verification -// configuration in a trust policy -type TimestampVerification struct { - Enable bool `json:"enable,omitempty"` - ExpiryRelaxed bool `json:"expiryRelaxed,omitempty"` -} - // Validate validates a policy document according to its version's rule set. // if any rule is violated, returns an error func (policyDoc *Document) Validate() error { @@ -220,11 +205,6 @@ func (policyDoc *Document) Validate() error { return fmt.Errorf("trust policy statement %q has invalid signatureVerification: %w", statement.Name, err) } - // Verify timestamp verification is valid - if statement.TimestampVerification != nil && policyDoc.Version != "1.1" { - return fmt.Errorf("trust policy document version must be 1.1 to support timestamp verification, but got %q", policyDoc.Version) - } - // Any signature verification other than "skip" needs a trust store and // trusted identities if verificationLevel.Name == "skip" { @@ -413,7 +393,6 @@ func (t *TrustPolicy) clone() *TrustPolicy { return &TrustPolicy{ Name: t.Name, SignatureVerification: t.SignatureVerification, - TimestampVerification: t.TimestampVerification, RegistryScopes: append([]string(nil), t.RegistryScopes...), TrustedIdentities: append([]string(nil), t.TrustedIdentities...), TrustStores: append([]string(nil), t.TrustStores...), diff --git a/verifier/verifier.go b/verifier/verifier.go index 1207c099..2ad119c1 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -330,13 +330,13 @@ func (v *verifier) processSignature(ctx context.Context, sigBlob []byte, envelop return err } - return processPluginResponse(logger, capabilitiesToVerify, response, outcome) + return processPluginResponse(capabilitiesToVerify, response, outcome) } } return nil } -func processPluginResponse(logger log.Logger, capabilitiesToVerify []pluginframework.Capability, response *pluginframework.VerifySignatureResponse, outcome *notation.VerificationOutcome) error { +func processPluginResponse(capabilitiesToVerify []pluginframework.Capability, response *pluginframework.VerifySignatureResponse, outcome *notation.VerificationOutcome) error { verificationPluginName, err := getVerificationPlugin(&outcome.EnvelopeContent.SignerInfo) if err != nil { return err @@ -538,18 +538,11 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } + invalidCertErrMsg := fmt.Sprintf("current time is not in certificate %q validity period [%q, %q]", invalidCertificate.Subject, invalidCertificate.NotBefore.Format(time.RFC1123Z), invalidCertificate.NotAfter.Format(time.RFC1123Z)) if len(signerInfo.UnsignedAttributes.TimestampSignature) == 0 { // if there is no timestamp token, fail this step return ¬ation.ValidationResult{ - Error: fmt.Errorf("current time is not in certificate %q validity period [%q, %q] and no timestamp token was found in the signature envelope", invalidCertificate.Subject, invalidCertificate.NotBefore.Format(time.RFC1123Z), invalidCertificate.NotAfter.Format(time.RFC1123Z)), - Type: trustpolicy.TypeAuthenticTimestamp, - Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], - } - } - if trustPolicy.TimestampVerification == nil || !trustPolicy.TimestampVerification.Enable { - // if timestamp verification is disabled by trust policy - return ¬ation.ValidationResult{ - Error: fmt.Errorf("current time is not in certificate %q validity period [%q, %q] and timestamp verification is disabled by trust policy", invalidCertificate.Subject, invalidCertificate.NotBefore.Format(time.RFC1123Z), invalidCertificate.NotAfter.Format(time.RFC1123Z)), + Error: errors.New(invalidCertErrMsg + ", and no timestamp countersignature was found in the signature envelope"), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } @@ -557,14 +550,14 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus trustTSACerts, err := loadX509TSATrustStores(ctx, outcome.EnvelopeContent.SignerInfo.SignedAttributes.SigningScheme, trustPolicy, x509TrustStore) if err != nil { return ¬ation.ValidationResult{ - Error: err, + Error: fmt.Errorf(invalidCertErrMsg+", and timestamp verification is disabled with error: %w", err), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } if len(trustTSACerts) < 1 { return ¬ation.ValidationResult{ - Error: errors.New("no trusted TSA root certificate was found in the trust store"), + Error: errors.New(invalidCertErrMsg + ", and no trusted TSA root certificate was found in the trust store"), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } @@ -572,7 +565,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus signedToken, err := tspclient.ParseSignedToken(ctx, signerInfo.UnsignedAttributes.TimestampSignature) if err != nil { return ¬ation.ValidationResult{ - Error: err, + Error: fmt.Errorf(invalidCertErrMsg+", and failed to parse timestamp countersignature with error: %w", err), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } @@ -588,36 +581,35 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus info, err := signedToken.Info() if err != nil { return ¬ation.ValidationResult{ - Error: err, + Error: fmt.Errorf(invalidCertErrMsg+", and failed to get timestamp information with error: %w", err), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - // validate the info + // validate the info and get the timestamp ts, accuracy, err := info.Timestamp(signerInfo.Signature) if err != nil { return ¬ation.ValidationResult{ - Error: err, + Error: fmt.Errorf(invalidCertErrMsg+", and failed to get timestamp from timestamp countersignature with error: %w", err), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - if trustPolicy.TimestampVerification.ExpiryRelaxed { - timestampVerifyOpts.CurrentTime = ts - } + // verify the timestamp countersignature at the time point been stamped + timestampVerifyOpts.CurrentTime = ts // verify the timestamp countersignature tsaCertChain, err := signedToken.Verify(ctx, timestampVerifyOpts) if err != nil { return ¬ation.ValidationResult{ - Error: err, + Error: fmt.Errorf(invalidCertErrMsg+", and failed to verify the timestamp countersignature with error: %w", err), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - // validate timestamp certificate chain + // validate timestamping certificate chain if err := nx509.ValidateTimeStampingCertChain(tsaCertChain, nil); err != nil { return ¬ation.ValidationResult{ - Error: err, + Error: fmt.Errorf(invalidCertErrMsg+", and failed to validate the timestamping certificate chain with error: %w", err), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } @@ -626,12 +618,11 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus timeStampLowerLimit := ts.Add(-accuracy) timeStampUpperLimit := ts.Add(accuracy) logger.Infof("timestamp token time range: [%v, %v]", timeStampLowerLimit, timeStampUpperLimit) - // TSA certificate chain revocation check - certResults, err := revocation.ValidateTimestampCertChain(tsaCertChain, timeStampUpperLimit) + // perform the timestamping certificate chain revocation check + certResults, err := revocation.ValidateTimestampCertChain(tsaCertChain, timeStampUpperLimit, &http.Client{Timeout: 2 * time.Second}) if err != nil { - logger.Debug("error while checking revocation status, err: %s", err.Error()) return ¬ation.ValidationResult{ - Error: err, + Error: fmt.Errorf(invalidCertErrMsg+", and timestamping certificate chain revocation check failed with error: %w", err), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } @@ -639,22 +630,22 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus finalResult, problematicCertSubject := revocationFinalResult(certResults, tsaCertChain, logger) switch finalResult { case revocationresult.ResultOK: - logger.Debug("no verification impacting errors encountered while checking TSA certificate chain revocation, status is OK") + logger.Debug("no verification impacting errors encountered while checking timestamping certificate chain revocation, status is OK") case revocationresult.ResultRevoked: return ¬ation.ValidationResult{ - Error: fmt.Errorf("TSA certificate with subject %q is revoked", problematicCertSubject), + Error: fmt.Errorf(invalidCertErrMsg+", and timestamping certificate with subject %q is revoked", problematicCertSubject), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } default: // revocationresult.ResultUnknown return ¬ation.ValidationResult{ - Error: fmt.Errorf("TSA certificate with subject %q revocation status is unknown", problematicCertSubject), + Error: fmt.Errorf(invalidCertErrMsg+", and timestamping certificate with subject %q revocation status is unknown", problematicCertSubject), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - // timestamp validation core process + // core process for _, cert := range signerInfo.CertificateChain { if timeStampLowerLimit.Before(cert.NotBefore) { return ¬ation.ValidationResult{ From de71d3441d098f0794536bb18720dc914f5cb211 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 8 May 2024 16:48:13 +0800 Subject: [PATCH 30/38] updated per spec Signed-off-by: Patrick Zheng --- verifier/trustpolicy/trustpolicy.go | 1 + 1 file changed, 1 insertion(+) diff --git a/verifier/trustpolicy/trustpolicy.go b/verifier/trustpolicy/trustpolicy.go index bc74432d..b0aaede5 100644 --- a/verifier/trustpolicy/trustpolicy.go +++ b/verifier/trustpolicy/trustpolicy.go @@ -185,6 +185,7 @@ func (policyDoc *Document) Validate() error { return fmt.Errorf("trust policy document uses unsupported version %q", policyDoc.Version) } + // Validate the policy according to 1.0 rules if len(policyDoc.TrustPolicies) == 0 { return errors.New("trust policy document can not have zero trust policy statements") } From cde5adb39abfac160931dc4a94b9c63c49e51914 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Fri, 10 May 2024 16:16:50 +0800 Subject: [PATCH 31/38] updated tspclient-go Signed-off-by: Patrick Zheng --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 1f724f33..dfc2fc07 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,6 @@ 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-20240508074737-fc1cb3d28098 +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240510081223-bf89fbfde06f -replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240508074024-ec1725d6dc9b +replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240510080813-e58c4f362fa4 diff --git a/go.sum b/go.sum index af3a4a03..bdd6573d 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ 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-20240508074737-fc1cb3d28098 h1:xfyYkDuH7MXz5+Pd5wvRSlARyDUp9UM7I23OzlbIMsA= -github.com/Two-Hearts/notation-core-go v0.0.0-20240508074737-fc1cb3d28098/go.mod h1:wkaaIh2fMRBO3j48U/F64tZOCqcYkuKOiA9o7ERkXXU= -github.com/Two-Hearts/tspclient-go v0.0.0-20240508074024-ec1725d6dc9b h1:pNICDsr2or3iCRyjB8UnrG/N7mhP6H6yIfx3F8Zkcqk= -github.com/Two-Hearts/tspclient-go v0.0.0-20240508074024-ec1725d6dc9b/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= +github.com/Two-Hearts/notation-core-go v0.0.0-20240510081223-bf89fbfde06f h1:0qJ4YyR0q7SYv9N1VMafb5823SpxI7AGuYnSlvEcTjo= +github.com/Two-Hearts/notation-core-go v0.0.0-20240510081223-bf89fbfde06f/go.mod h1:KDiMLnM1MHQRMeiPM622MN0MBb9Hz6xRU4/O9qDOics= +github.com/Two-Hearts/tspclient-go v0.0.0-20240510080813-e58c4f362fa4 h1:jtwluHassbSXeXjloQ5FCJJ1hOhN/DCnAztY8Cr6if0= +github.com/Two-Hearts/tspclient-go v0.0.0-20240510080813-e58c4f362fa4/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= 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= From d13d60c64b5f9e4b464874c4e9b4788ee55ef0ae Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 4 Jun 2024 16:26:08 +0800 Subject: [PATCH 32/38] updated timestamping Signed-off-by: Patrick Zheng --- go.mod | 4 ++-- go.sum | 8 ++++---- verifier/helpers.go | 15 +++++++++++++++ verifier/verifier.go | 25 ++++++++++++++++++++----- 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 9824f250..6b63819d 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,6 @@ 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-20240510081223-bf89fbfde06f +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240604074342-99b519049ef9 -replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240510080813-e58c4f362fa4 +replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240604030442-e5d82db3a4d4 diff --git a/go.sum b/go.sum index 9b41f8fb..c0ddc38a 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ 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-20240510081223-bf89fbfde06f h1:0qJ4YyR0q7SYv9N1VMafb5823SpxI7AGuYnSlvEcTjo= -github.com/Two-Hearts/notation-core-go v0.0.0-20240510081223-bf89fbfde06f/go.mod h1:KDiMLnM1MHQRMeiPM622MN0MBb9Hz6xRU4/O9qDOics= -github.com/Two-Hearts/tspclient-go v0.0.0-20240510080813-e58c4f362fa4 h1:jtwluHassbSXeXjloQ5FCJJ1hOhN/DCnAztY8Cr6if0= -github.com/Two-Hearts/tspclient-go v0.0.0-20240510080813-e58c4f362fa4/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= +github.com/Two-Hearts/notation-core-go v0.0.0-20240604074342-99b519049ef9 h1:gMwiXl+IGOeVhF4KUHbfqbvqZsgONcqPtzfYBexFKRE= +github.com/Two-Hearts/notation-core-go v0.0.0-20240604074342-99b519049ef9/go.mod h1:uk5VrENYWqPdnnBOZCEk1XEfilOscHJckfhaWzuMJlU= +github.com/Two-Hearts/tspclient-go v0.0.0-20240604030442-e5d82db3a4d4 h1:WCm4ObRL++IM3gVexV7evDbhzk2c4iAZYJmlTWIBOnQ= +github.com/Two-Hearts/tspclient-go v0.0.0-20240604030442-e5d82db3a4d4/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= 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/helpers.go b/verifier/helpers.go index 43ddb7ce..057239e1 100644 --- a/verifier/helpers.go +++ b/verifier/helpers.go @@ -168,3 +168,18 @@ func loadX509TrustStoresWithType(ctx context.Context, trustStoreType truststore. } return certificates, nil } + +// isTSATrustStoreInPolicy checks if tsa trust store is configured in +// trust policy +func isTSATrustStoreInPolicy(policy *trustpolicy.TrustPolicy) (bool, error) { + for _, trustStore := range policy.TrustStores { + storeType, _, found := strings.Cut(trustStore, ":") + if !found { + return false, truststore.TrustStoreError{Msg: fmt.Sprintf("invalid trust policy statement: %q is missing separator in trust store value %q. The required format is :", policy.Name, trustStore)} + } + if truststore.Type(storeType) == truststore.TypeTSA { + return true, nil + } + } + return false, nil +} diff --git a/verifier/verifier.go b/verifier/verifier.go index 7192abad..996fdd2a 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -525,19 +525,19 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus timeStampLowerLimit := time.Now() timeStampUpperLimit := timeStampLowerLimit // check if tsa trust store is configured in trust policy - trustTSACerts, err := loadX509TSATrustStores(ctx, outcome.EnvelopeContent.SignerInfo.SignedAttributes.SigningScheme, trustPolicy, x509TrustStore) + tsaEnabled, err := isTSATrustStoreInPolicy(trustPolicy) if err != nil { return ¬ation.ValidationResult{ - Error: fmt.Errorf("failed to load tsa trust store with error: %w", err), + Error: fmt.Errorf("failed to check tsa trust store configuration in turst policy with error: %w", err), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - if len(trustTSACerts) < 1 { + if !tsaEnabled { performTimestampVerification = false } // check based on 'verifyTimestamp' field - if trustPolicy.SignatureVerification.VerifyTimestamp == trustpolicy.OptionAfterCertExpiry { + if performTimestampVerification && trustPolicy.SignatureVerification.VerifyTimestamp == trustpolicy.OptionAfterCertExpiry { // check if signing cert chain has expired var expired bool for _, cert := range signerInfo.CertificateChain { @@ -586,7 +586,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus } // 2. Verify the timestamp countersignature logger.Info("Verifying the timestamp countersignature...") - signedToken, err := tspclient.ParseSignedToken(ctx, signerInfo.UnsignedAttributes.TimestampSignature) + signedToken, err := tspclient.ParseSignedToken(signerInfo.UnsignedAttributes.TimestampSignature) if err != nil { return ¬ation.ValidationResult{ Error: fmt.Errorf("failed to parse timestamp countersignature with error: %w", err), @@ -611,6 +611,21 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus } } roots := x509.NewCertPool() + trustTSACerts, err := loadX509TSATrustStores(ctx, outcome.EnvelopeContent.SignerInfo.SignedAttributes.SigningScheme, trustPolicy, x509TrustStore) + if err != nil { + return ¬ation.ValidationResult{ + Error: fmt.Errorf("failed to load tsa trust store with error: %w", err), + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], + } + } + if len(trustTSACerts) < 1 { + return ¬ation.ValidationResult{ + Error: errors.New("no TSA root cert found in trust store"), + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], + } + } for _, cert := range trustTSACerts { roots.AddCert(cert) } From c5ececc222963ea61137557f3c804ea72f5e8ca1 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 4 Jun 2024 16:32:02 +0800 Subject: [PATCH 33/38] updated timestamping Signed-off-by: Patrick Zheng --- verifier/verifier.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/verifier/verifier.go b/verifier/verifier.go index 996fdd2a..8ac2919a 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -521,6 +521,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus // under signing scheme notary.x509 if signerInfo := outcome.EnvelopeContent.SignerInfo; signerInfo.SignedAttributes.SigningScheme == signature.SigningSchemeX509 { + logger.Info("under signing scheme notary.x509...") performTimestampVerification := true timeStampLowerLimit := time.Now() timeStampUpperLimit := timeStampLowerLimit @@ -569,6 +570,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus } } } + // this step is a success return ¬ation.ValidationResult{ Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], @@ -700,6 +702,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus } } else if signerInfo.SignedAttributes.SigningScheme == signature.SigningSchemeX509SigningAuthority { // under signing scheme notary.x509.signingAuthority + logger.Info("under signing scheme notary.x509.signingAuthority...") authenticSigningTime := signerInfo.SignedAttributes.SigningTime for _, cert := range signerInfo.CertificateChain { if authenticSigningTime.Before(cert.NotBefore) || authenticSigningTime.After(cert.NotAfter) { From d8f19cfde887c089cbc32aa4de3bb37ecc818743 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 4 Jun 2024 16:50:03 +0800 Subject: [PATCH 34/38] updated 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 8ac2919a..8a3668b2 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -521,7 +521,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus // under signing scheme notary.x509 if signerInfo := outcome.EnvelopeContent.SignerInfo; signerInfo.SignedAttributes.SigningScheme == signature.SigningSchemeX509 { - logger.Info("under signing scheme notary.x509...") + logger.Info("Under signing scheme notary.x509...") performTimestampVerification := true timeStampLowerLimit := time.Now() timeStampUpperLimit := timeStampLowerLimit @@ -666,7 +666,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus finalResult, problematicCertSubject := revocationFinalResult(certResults, tsaCertChain, logger) switch finalResult { case revocationresult.ResultOK: - logger.Debug("no verification impacting errors encountered while checking timestamping certificate chain revocation, status is OK") + logger.Debug("No verification impacting errors encountered while checking timestamping certificate chain revocation, status is OK") case revocationresult.ResultRevoked: return ¬ation.ValidationResult{ Error: fmt.Errorf("timestamping certificate with subject %q is revoked", problematicCertSubject), @@ -683,7 +683,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus } // 5. Check the timestamp against the signing certificate chain logger.Info("Checking the timestamp against the signing certificate chain...") - logger.Infof("timestamp range: [%v, %v]", timeStampLowerLimit, timeStampUpperLimit) + logger.Infof("Timestamp range: [%v, %v]", timeStampLowerLimit, timeStampUpperLimit) for _, cert := range signerInfo.CertificateChain { if timeStampLowerLimit.Before(cert.NotBefore) { return ¬ation.ValidationResult{ @@ -702,7 +702,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus } } else if signerInfo.SignedAttributes.SigningScheme == signature.SigningSchemeX509SigningAuthority { // under signing scheme notary.x509.signingAuthority - logger.Info("under signing scheme notary.x509.signingAuthority...") + logger.Info("Under signing scheme notary.x509.signingAuthority...") authenticSigningTime := signerInfo.SignedAttributes.SigningTime for _, cert := range signerInfo.CertificateChain { if authenticSigningTime.Before(cert.NotBefore) || authenticSigningTime.After(cert.NotAfter) { @@ -733,12 +733,12 @@ func verifyRevocation(outcome *notation.VerificationOutcome, r revocation.Revoca authenticSigningTime, err := outcome.EnvelopeContent.SignerInfo.AuthenticSigningTime() if err != nil { - logger.Debugf("not using authentic signing time due to error retrieving AuthenticSigningTime, err: %v", err) + logger.Debugf("Not using authentic signing time due to error retrieving AuthenticSigningTime, err: %v", err) authenticSigningTime = time.Time{} } certResults, err := r.Validate(outcome.EnvelopeContent.SignerInfo.CertificateChain, authenticSigningTime) if err != nil { - logger.Debug("error while checking revocation status, err: %s", err.Error()) + logger.Debug("Error while checking revocation status, err: %s", err.Error()) return ¬ation.ValidationResult{ Type: trustpolicy.TypeRevocation, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeRevocation], @@ -753,7 +753,7 @@ func verifyRevocation(outcome *notation.VerificationOutcome, r revocation.Revoca finalResult, problematicCertSubject := revocationFinalResult(certResults, outcome.EnvelopeContent.SignerInfo.CertificateChain, logger) switch finalResult { case revocationresult.ResultOK: - logger.Debug("no verification impacting errors encountered while checking revocation, status is OK") + logger.Debug("No verification impacting errors encountered while checking revocation, status is OK") case revocationresult.ResultRevoked: result.Error = fmt.Errorf("signing certificate with subject %q is revoked", problematicCertSubject) default: @@ -774,7 +774,7 @@ func revocationFinalResult(certResults []*revocationresult.CertRevocationResult, var revokedCertSubject string for i := len(certResults) - 1; i >= 0; i-- { if len(certResults[i].ServerResults) > 0 && certResults[i].ServerResults[0].Error != nil { - logger.Debugf("error for certificate #%d in chain with subject %v for server %q: %v", (i + 1), certChain[i].Subject.String(), certResults[i].ServerResults[0].Server, certResults[i].ServerResults[0].Error) + logger.Debugf("Error for certificate #%d in chain with subject %v for server %q: %v", (i + 1), certChain[i].Subject.String(), certResults[i].ServerResults[0].Server, certResults[i].ServerResults[0].Error) } if certResults[i].Result == revocationresult.ResultOK || certResults[i].Result == revocationresult.ResultNonRevokable { From f1497b1f9233d29c8c6acc17e92ccd3d7d20cc83 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 11 Jun 2024 13:43:16 +0800 Subject: [PATCH 35/38] update Signed-off-by: Patrick Zheng --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6b63819d..0e3c8e13 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,6 @@ 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-20240604074342-99b519049ef9 +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240611053818-29d77ead8420 replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240604030442-e5d82db3a4d4 diff --git a/go.sum b/go.sum index c0ddc38a..cd74d385 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-20240604074342-99b519049ef9 h1:gMwiXl+IGOeVhF4KUHbfqbvqZsgONcqPtzfYBexFKRE= -github.com/Two-Hearts/notation-core-go v0.0.0-20240604074342-99b519049ef9/go.mod h1:uk5VrENYWqPdnnBOZCEk1XEfilOscHJckfhaWzuMJlU= +github.com/Two-Hearts/notation-core-go v0.0.0-20240611053818-29d77ead8420 h1:csyLPcBqLKcgEqyqjEsbCplRxcMk9P1oHuP3ECzitwk= +github.com/Two-Hearts/notation-core-go v0.0.0-20240611053818-29d77ead8420/go.mod h1:uk5VrENYWqPdnnBOZCEk1XEfilOscHJckfhaWzuMJlU= github.com/Two-Hearts/tspclient-go v0.0.0-20240604030442-e5d82db3a4d4 h1:WCm4ObRL++IM3gVexV7evDbhzk2c4iAZYJmlTWIBOnQ= github.com/Two-Hearts/tspclient-go v0.0.0-20240604030442-e5d82db3a4d4/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI= From ee0b91b980f5d6643cddbade9ee36659f419941a Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 11 Jun 2024 17:22:36 +0800 Subject: [PATCH 36/38] build cert chain from tsa token Signed-off-by: Patrick Zheng --- go.mod | 2 +- go.sum | 4 ++-- signer/signer.go | 7 +------ verifier/verifier.go | 34 ++++++++++++++++++++++++---------- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index 3676e570..c9c2acdc 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,6 @@ 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-20240611053818-29d77ead8420 +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240611085403-02dce641a74d replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240604030442-e5d82db3a4d4 diff --git a/go.sum b/go.sum index 48196521..2341a25a 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-20240611053818-29d77ead8420 h1:csyLPcBqLKcgEqyqjEsbCplRxcMk9P1oHuP3ECzitwk= -github.com/Two-Hearts/notation-core-go v0.0.0-20240611053818-29d77ead8420/go.mod h1:uk5VrENYWqPdnnBOZCEk1XEfilOscHJckfhaWzuMJlU= +github.com/Two-Hearts/notation-core-go v0.0.0-20240611085403-02dce641a74d h1:Jang//VKYgXC2lxp7E2YaTk+FpsAmUSEs9NVrNBrAHE= +github.com/Two-Hearts/notation-core-go v0.0.0-20240611085403-02dce641a74d/go.mod h1:uk5VrENYWqPdnnBOZCEk1XEfilOscHJckfhaWzuMJlU= github.com/Two-Hearts/tspclient-go v0.0.0-20240604030442-e5d82db3a4d4 h1:WCm4ObRL++IM3gVexV7evDbhzk2c4iAZYJmlTWIBOnQ= github.com/Two-Hearts/tspclient-go v0.0.0-20240604030442-e5d82db3a4d4/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI= diff --git a/signer/signer.go b/signer/signer.go index af693d36..8db490d1 100644 --- a/signer/signer.go +++ b/signer/signer.go @@ -144,14 +144,9 @@ func (s *GenericSigner) Sign(ctx context.Context, desc ocispec.Descriptor, opts return nil, nil, err } - var timestampErr *signature.TimestampError sig, err := sigEnv.Sign(signReq) if err != nil { - if !errors.As(err, ×tampErr) { - return nil, nil, err - } - // warn on timestamping error, but do not fail the signing process - logger.Warnf("Failed to timestamp the signature. Error: %v", timestampErr) + return nil, nil, err } envContent, err := sigEnv.Verify() diff --git a/verifier/verifier.go b/verifier/verifier.go index 8a3668b2..eab6b3cb 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -612,7 +612,16 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - roots := x509.NewCertPool() + tsaCertChain, err := signedToken.Verify(ctx, x509.VerifyOptions{ + CurrentTime: ts, + }) + if err != nil { + return ¬ation.ValidationResult{ + Error: fmt.Errorf("failed to verify the timestamp countersignature with error: %w", err), + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], + } + } trustTSACerts, err := loadX509TSATrustStores(ctx, outcome.EnvelopeContent.SignerInfo.SignedAttributes.SigningScheme, trustPolicy, x509TrustStore) if err != nil { return ¬ation.ValidationResult{ @@ -623,21 +632,26 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus } if len(trustTSACerts) < 1 { return ¬ation.ValidationResult{ - Error: errors.New("no TSA root cert found in trust store"), + Error: errors.New("no trusted TSA certificate found in trust store"), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - for _, cert := range trustTSACerts { - roots.AddCert(cert) + var foundTrustedCert bool + for _, trust := range trustTSACerts { + for _, cert := range tsaCertChain { + if trust.Equal(cert) { + foundTrustedCert = true + break + } + } + if foundTrustedCert { + break + } } - tsaCertChain, err := signedToken.Verify(ctx, x509.VerifyOptions{ - Roots: roots, - CurrentTime: ts, - }) - if err != nil { + if !foundTrustedCert { return ¬ation.ValidationResult{ - Error: fmt.Errorf("failed to verify the timestamp countersignature with error: %w", err), + Error: errors.New("failed to verify the timestamp countersignature with error: tsa certificate chain does not contain trusted certificate in trust store"), Type: trustpolicy.TypeAuthenticTimestamp, Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } From 3cdb0b204de5e00b663a74b9d8e5373af57f70cb Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Tue, 11 Jun 2024 18:45:01 +0800 Subject: [PATCH 37/38] update Signed-off-by: Patrick Zheng --- verifier/verifier.go | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/verifier/verifier.go b/verifier/verifier.go index eab6b3cb..54029612 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -622,6 +622,17 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } + // 3. Validate timestamping certificate chain + logger.Info("Validating timestamping certificate chain...") + if err := nx509.ValidateTimeStampingCertChain(tsaCertChain, nil); err != nil { + return ¬ation.ValidationResult{ + Error: fmt.Errorf("failed to validate the timestamping certificate chain with error: %w", err), + Type: trustpolicy.TypeAuthenticTimestamp, + Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], + } + } + // 4. Check authenticity of the TSA against trust store + logger.Info("Checking TSA authenticity against the trust store...") trustTSACerts, err := loadX509TSATrustStores(ctx, outcome.EnvelopeContent.SignerInfo.SignedAttributes.SigningScheme, trustPolicy, x509TrustStore) if err != nil { return ¬ation.ValidationResult{ @@ -656,16 +667,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - // 3. Validate timestamping certificate chain - logger.Info("Validating timestamping certificate chain...") - if err := nx509.ValidateTimeStampingCertChain(tsaCertChain, nil); err != nil { - return ¬ation.ValidationResult{ - Error: fmt.Errorf("failed to validate the timestamping certificate chain with error: %w", err), - Type: trustpolicy.TypeAuthenticTimestamp, - Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], - } - } - // 4. Perform the timestamping certificate chain revocation check + // 5. Perform the timestamping certificate chain revocation check logger.Info("Checking timestamping certificate chain revocation...") timeStampLowerLimit = ts.Add(-accuracy) timeStampUpperLimit = ts.Add(accuracy) @@ -695,7 +697,7 @@ func verifyAuthenticTimestamp(ctx context.Context, trustPolicy *trustpolicy.Trus Action: outcome.VerificationLevel.Enforcement[trustpolicy.TypeAuthenticTimestamp], } } - // 5. Check the timestamp against the signing certificate chain + // 6. Check the timestamp against the signing certificate chain logger.Info("Checking the timestamp against the signing certificate chain...") logger.Infof("Timestamp range: [%v, %v]", timeStampLowerLimit, timeStampUpperLimit) for _, cert := range signerInfo.CertificateChain { From 09075e730c2a3c42abbaaee681c98b21209187ef Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Fri, 14 Jun 2024 09:09:02 +0800 Subject: [PATCH 38/38] update Signed-off-by: Patrick Zheng --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index c9c2acdc..c0fd9407 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,6 @@ 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-20240611085403-02dce641a74d +replace github.com/notaryproject/notation-core-go => github.com/Two-Hearts/notation-core-go v0.0.0-20240614010738-f309851427d4 -replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240604030442-e5d82db3a4d4 +replace github.com/notaryproject/tspclient-go => github.com/Two-Hearts/tspclient-go v0.0.0-20240614004631-5aa21481e88c diff --git a/go.sum b/go.sum index 2341a25a..e7c57354 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ 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-20240611085403-02dce641a74d h1:Jang//VKYgXC2lxp7E2YaTk+FpsAmUSEs9NVrNBrAHE= -github.com/Two-Hearts/notation-core-go v0.0.0-20240611085403-02dce641a74d/go.mod h1:uk5VrENYWqPdnnBOZCEk1XEfilOscHJckfhaWzuMJlU= -github.com/Two-Hearts/tspclient-go v0.0.0-20240604030442-e5d82db3a4d4 h1:WCm4ObRL++IM3gVexV7evDbhzk2c4iAZYJmlTWIBOnQ= -github.com/Two-Hearts/tspclient-go v0.0.0-20240604030442-e5d82db3a4d4/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= +github.com/Two-Hearts/notation-core-go v0.0.0-20240614010738-f309851427d4 h1:uWhmi+pelmgrU9nskvHj0iaoXfYzBrbCjT+jEUdiTbI= +github.com/Two-Hearts/notation-core-go v0.0.0-20240614010738-f309851427d4/go.mod h1:MOqk8+9Hpx4b5tbUireNZfXX2ioWw3p+tUpgJSVIf3E= +github.com/Two-Hearts/tspclient-go v0.0.0-20240614004631-5aa21481e88c h1:IL7bEELXuO9QhjkhERYBaQD7stFeT7/pgNtXtvXi+mk= +github.com/Two-Hearts/tspclient-go v0.0.0-20240614004631-5aa21481e88c/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs= 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=