From 4b4273838666ab22a5f270511006fe43c63adc85 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Fri, 1 Dec 2023 11:56:40 +0800 Subject: [PATCH 01/13] 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/13] 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/13] 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/13] 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/13] 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/13] 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/13] 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/13] 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/13] 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/13] 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/13] 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/13] 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/13] 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) {