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) }