VYPR
Medium severity4.0NVD Advisory· Published Jan 13, 2025· Updated Apr 15, 2026

CVE-2024-56138

CVE-2024-56138

Description

notion-go is a collection of libraries for supporting sign and verify OCI artifacts. Based on Notary Project specifications. This issue was identified during Quarkslab's audit of the timestamp feature. During the timestamp signature generation, the revocation status of the certificate(s) used to generate the timestamp signature was not verified. During timestamp signature generation, notation-go did not check the revocation status of the certificate chain used by the TSA. This oversight creates a vulnerability that could be exploited through a Man-in-The-Middle attack. An attacker could potentially use a compromised, intermediate, or revoked leaf certificate to generate a malicious countersignature, which would then be accepted and stored by notation. This could lead to denial of service scenarios, particularly in CI/CD environments during signature verification processes because timestamp signature would fail due to the presence of a revoked certificate(s) potentially disrupting operations. This issue has been addressed in release version 1.3.0-rc.2 and all users are advised to upgrade. There are no known workarounds for this vulnerability.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/notaryproject/notation-goGo
>= 1.2.0-beta.1, < 1.3.0-rc.21.3.0-rc.2

Patches

3
e99be1954a15

fix: enable timestamping cert chain revocation check during signing (#482)

https://github.com/notaryproject/notation-goPatrick ZhengDec 2, 2024via ghsa
7 files changed · +62 15
  • example_signWithTimestmap_test.go+14 3 modified
    @@ -21,6 +21,8 @@ import (
     
     	"oras.land/oras-go/v2/registry/remote"
     
    +	"github.com/notaryproject/notation-core-go/revocation"
    +	"github.com/notaryproject/notation-core-go/revocation/purpose"
     	"github.com/notaryproject/notation-core-go/testhelper"
     	"github.com/notaryproject/notation-go"
     	"github.com/notaryproject/notation-go/registry"
    @@ -77,12 +79,21 @@ func Example_signWithTimestamp() {
     	tsaRootCAs := x509.NewCertPool()
     	tsaRootCAs.AddCert(tsaRootCert)
     
    +	// enable timestamping certificate chain revocation check
    +	tsaRevocationValidator, err := revocation.NewWithOptions(revocation.Options{
    +		CertChainPurpose: purpose.Timestamping,
    +	})
    +	if err != nil {
    +		panic(err) // Handle error
    +	}
    +
     	// exampleSignOptions is an example of notation.SignOptions.
     	exampleSignOptions := notation.SignOptions{
     		SignerSignOptions: notation.SignerSignOptions{
    -			SignatureMediaType: exampleSignatureMediaType,
    -			Timestamper:        httpTimestamper,
    -			TSARootCAs:         tsaRootCAs,
    +			SignatureMediaType:     exampleSignatureMediaType,
    +			Timestamper:            httpTimestamper,
    +			TSARootCAs:             tsaRootCAs,
    +			TSARevocationValidator: tsaRevocationValidator,
     		},
     		ArtifactReference: exampleArtifactReference,
     	}
    
  • .github/.codecov.yml+3 0 modified
    @@ -14,5 +14,8 @@
     coverage:
       status:
         project:
    +      default:
    +        target: 80%
    +    patch:
           default:
             target: 80%
    \ No newline at end of file
    
  • go.mod+1 1 modified
    @@ -4,7 +4,7 @@ go 1.22.0
     
     require (
     	github.com/go-ldap/ldap/v3 v3.4.8
    -	github.com/notaryproject/notation-core-go v1.2.0-rc.1.0.20241112001243-33af15a18954
    +	github.com/notaryproject/notation-core-go v1.2.0-rc.1.0.20241129024749-95d89543c9f9
     	github.com/notaryproject/notation-plugin-framework-go v1.0.0
     	github.com/notaryproject/tspclient-go v0.2.1-0.20241030015323-90a141e7525c
     	github.com/opencontainers/go-digest v1.0.0
    
  • go.sum+2 2 modified
    @@ -32,8 +32,8 @@ github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh6
     github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
     github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
     github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
    -github.com/notaryproject/notation-core-go v1.2.0-rc.1.0.20241112001243-33af15a18954 h1:UbjH/ePjxU8jcYMca9NVYqU8Qcr7pP1SKDWCxl++ToA=
    -github.com/notaryproject/notation-core-go v1.2.0-rc.1.0.20241112001243-33af15a18954/go.mod h1:phjvE2bqHsLfJMqMUYqRCqNIH3TQ4GCcFQuEVyQTpDg=
    +github.com/notaryproject/notation-core-go v1.2.0-rc.1.0.20241129024749-95d89543c9f9 h1:FURo9xpGLKmghWCcWypCPQTlcOGKxzayeXacGfb8WUU=
    +github.com/notaryproject/notation-core-go v1.2.0-rc.1.0.20241129024749-95d89543c9f9/go.mod h1:Umjn4NKGmuHpVffMgKVcUnArNG3Qtd3duKYpPILUBg4=
     github.com/notaryproject/notation-plugin-framework-go v1.0.0 h1:6Qzr7DGXoCgXEQN+1gTZWuJAZvxh3p8Lryjn5FaLzi4=
     github.com/notaryproject/notation-plugin-framework-go v1.0.0/go.mod h1:RqWSrTOtEASCrGOEffq0n8pSg2KOgKYiWqFWczRSics=
     github.com/notaryproject/tspclient-go v0.2.1-0.20241030015323-90a141e7525c h1:bX6gGxFw9+DShmYTgbD+vr6neF1SoXIMUU2fDgdLsfA=
    
  • notation.go+6 0 modified
    @@ -31,6 +31,7 @@ import (
     	orasRegistry "oras.land/oras-go/v2/registry"
     	"oras.land/oras-go/v2/registry/remote"
     
    +	"github.com/notaryproject/notation-core-go/revocation"
     	"github.com/notaryproject/notation-core-go/signature"
     	"github.com/notaryproject/notation-core-go/signature/cose"
     	"github.com/notaryproject/notation-core-go/signature/jws"
    @@ -69,6 +70,11 @@ type SignerSignOptions struct {
     
     	// TSARootCAs is the cert pool holding caller's TSA trust anchor
     	TSARootCAs *x509.CertPool
    +
    +	// TSARevocationValidator is used for validating revocation status of
    +	// timestamping certificate chain with context during signing.
    +	// When present, only used when timestamping is performed.
    +	TSARevocationValidator revocation.Validator
     }
     
     // Signer is a generic interface for signing an OCI artifact.
    
  • signer/signer.go+13 9 modified
    @@ -106,7 +106,6 @@ func (s *GenericSigner) Sign(ctx context.Context, desc ocispec.Descriptor, opts
     	if err != nil {
     		return nil, nil, fmt.Errorf("envelope payload can't be marshalled: %w", err)
     	}
    -
     	var signingAgentId string
     	if opts.SigningAgent != "" {
     		signingAgentId = opts.SigningAgent
    @@ -124,12 +123,13 @@ func (s *GenericSigner) Sign(ctx context.Context, desc ocispec.Descriptor, opts
     			ContentType: envelope.MediaTypePayloadV1,
     			Content:     payloadBytes,
     		},
    -		Signer:        s.signer,
    -		SigningTime:   time.Now(),
    -		SigningScheme: signature.SigningSchemeX509,
    -		SigningAgent:  signingAgentId,
    -		Timestamper:   opts.Timestamper,
    -		TSARootCAs:    opts.TSARootCAs,
    +		Signer:                 s.signer,
    +		SigningTime:            time.Now(),
    +		SigningScheme:          signature.SigningSchemeX509,
    +		SigningAgent:           signingAgentId,
    +		Timestamper:            opts.Timestamper,
    +		TSARootCAs:             opts.TSARootCAs,
    +		TSARevocationValidator: opts.TSARevocationValidator,
     	}
     
     	// Add expiry only if ExpiryDuration is not zero
    @@ -143,6 +143,12 @@ 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)
    +	if signReq.Timestamper != nil {
    +		logger.Debug("Enabled timestamping")
    +		if signReq.TSARevocationValidator != nil {
    +			logger.Debug("Enabled timestamping certificate chain revocation check")
    +		}
    +	}
     
     	// Add ctx to the SignRequest
     	signReq = signReq.WithContext(ctx)
    @@ -152,12 +158,10 @@ func (s *GenericSigner) Sign(ctx context.Context, desc ocispec.Descriptor, opts
     	if err != nil {
     		return nil, nil, err
     	}
    -
     	sig, err := sigEnv.Sign(signReq)
     	if err != nil {
     		return nil, nil, err
     	}
    -
     	envContent, err := sigEnv.Verify()
     	if err != nil {
     		return nil, nil, fmt.Errorf("generated signature failed verification: %v", err)
    
  • signer/signer_test.go+23 0 modified
    @@ -30,6 +30,8 @@ import (
     	"testing"
     	"time"
     
    +	"github.com/notaryproject/notation-core-go/revocation"
    +	"github.com/notaryproject/notation-core-go/revocation/purpose"
     	"github.com/notaryproject/notation-core-go/signature"
     	_ "github.com/notaryproject/notation-core-go/signature/cose"
     	_ "github.com/notaryproject/notation-core-go/signature/jws"
    @@ -257,6 +259,27 @@ func TestSignWithTimestamping(t *testing.T) {
     	if err == nil || err.Error() != expectedErrMsg {
     		t.Fatalf("expected %s, but got %s", expectedErrMsg, err)
     	}
    +
    +	// timestamping with unknown authority
    +	desc, sOpts = generateSigningContent()
    +	sOpts.SignatureMediaType = envelopeType
    +	sOpts.Timestamper, err = tspclient.NewHTTPTimestamper(nil, rfc3161URL)
    +	if err != nil {
    +		t.Fatal(err)
    +	}
    +	sOpts.TSARootCAs = x509.NewCertPool()
    +	tsaRevocationValidator, err := revocation.NewWithOptions(revocation.Options{
    +		CertChainPurpose: purpose.Timestamping,
    +	})
    +	if err != nil {
    +		t.Fatal(err)
    +	}
    +	sOpts.TSARevocationValidator = tsaRevocationValidator
    +	_, _, err = s.Sign(ctx, desc, sOpts)
    +	expectedErrMsg = "timestamp: failed to verify signed token: cms verification failure: x509: certificate signed by unknown authority"
    +	if err == nil || err.Error() != expectedErrMsg {
    +		t.Fatalf("expected %s, but got %s", expectedErrMsg, err)
    +	}
     }
     
     func TestSignBlobWithCertChain(t *testing.T) {
    
e7005a6d13e5

fix: enable timestamping cert chain revocation check during signing (#482)

https://github.com/notaryproject/notation-goPatrick ZhengDec 2, 2024via ghsa
7 files changed · +62 15
  • example_signWithTimestmap_test.go+14 3 modified
    @@ -21,6 +21,8 @@ import (
     
     	"oras.land/oras-go/v2/registry/remote"
     
    +	"github.com/notaryproject/notation-core-go/revocation"
    +	"github.com/notaryproject/notation-core-go/revocation/purpose"
     	"github.com/notaryproject/notation-core-go/testhelper"
     	"github.com/notaryproject/notation-go"
     	"github.com/notaryproject/notation-go/registry"
    @@ -77,12 +79,21 @@ func Example_signWithTimestamp() {
     	tsaRootCAs := x509.NewCertPool()
     	tsaRootCAs.AddCert(tsaRootCert)
     
    +	// enable timestamping certificate chain revocation check
    +	tsaRevocationValidator, err := revocation.NewWithOptions(revocation.Options{
    +		CertChainPurpose: purpose.Timestamping,
    +	})
    +	if err != nil {
    +		panic(err) // Handle error
    +	}
    +
     	// exampleSignOptions is an example of notation.SignOptions.
     	exampleSignOptions := notation.SignOptions{
     		SignerSignOptions: notation.SignerSignOptions{
    -			SignatureMediaType: exampleSignatureMediaType,
    -			Timestamper:        httpTimestamper,
    -			TSARootCAs:         tsaRootCAs,
    +			SignatureMediaType:     exampleSignatureMediaType,
    +			Timestamper:            httpTimestamper,
    +			TSARootCAs:             tsaRootCAs,
    +			TSARevocationValidator: tsaRevocationValidator,
     		},
     		ArtifactReference: exampleArtifactReference,
     	}
    
  • .github/.codecov.yml+3 0 modified
    @@ -14,5 +14,8 @@
     coverage:
       status:
         project:
    +      default:
    +        target: 80%
    +    patch:
           default:
             target: 80%
    \ No newline at end of file
    
  • go.mod+1 1 modified
    @@ -4,7 +4,7 @@ go 1.22.0
     
     require (
     	github.com/go-ldap/ldap/v3 v3.4.8
    -	github.com/notaryproject/notation-core-go v1.2.0-rc.1.0.20241112001243-33af15a18954
    +	github.com/notaryproject/notation-core-go v1.2.0-rc.1.0.20241129024749-95d89543c9f9
     	github.com/notaryproject/notation-plugin-framework-go v1.0.0
     	github.com/notaryproject/tspclient-go v0.2.1-0.20241030015323-90a141e7525c
     	github.com/opencontainers/go-digest v1.0.0
    
  • go.sum+2 2 modified
    @@ -32,8 +32,8 @@ github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh6
     github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
     github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
     github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
    -github.com/notaryproject/notation-core-go v1.2.0-rc.1.0.20241112001243-33af15a18954 h1:UbjH/ePjxU8jcYMca9NVYqU8Qcr7pP1SKDWCxl++ToA=
    -github.com/notaryproject/notation-core-go v1.2.0-rc.1.0.20241112001243-33af15a18954/go.mod h1:phjvE2bqHsLfJMqMUYqRCqNIH3TQ4GCcFQuEVyQTpDg=
    +github.com/notaryproject/notation-core-go v1.2.0-rc.1.0.20241129024749-95d89543c9f9 h1:FURo9xpGLKmghWCcWypCPQTlcOGKxzayeXacGfb8WUU=
    +github.com/notaryproject/notation-core-go v1.2.0-rc.1.0.20241129024749-95d89543c9f9/go.mod h1:Umjn4NKGmuHpVffMgKVcUnArNG3Qtd3duKYpPILUBg4=
     github.com/notaryproject/notation-plugin-framework-go v1.0.0 h1:6Qzr7DGXoCgXEQN+1gTZWuJAZvxh3p8Lryjn5FaLzi4=
     github.com/notaryproject/notation-plugin-framework-go v1.0.0/go.mod h1:RqWSrTOtEASCrGOEffq0n8pSg2KOgKYiWqFWczRSics=
     github.com/notaryproject/tspclient-go v0.2.1-0.20241030015323-90a141e7525c h1:bX6gGxFw9+DShmYTgbD+vr6neF1SoXIMUU2fDgdLsfA=
    
  • notation.go+6 0 modified
    @@ -29,6 +29,7 @@ import (
     	orasRegistry "oras.land/oras-go/v2/registry"
     	"oras.land/oras-go/v2/registry/remote"
     
    +	"github.com/notaryproject/notation-core-go/revocation"
     	"github.com/notaryproject/notation-core-go/signature"
     	"github.com/notaryproject/notation-core-go/signature/cose"
     	"github.com/notaryproject/notation-core-go/signature/jws"
    @@ -67,6 +68,11 @@ type SignerSignOptions struct {
     
     	// TSARootCAs is the cert pool holding caller's TSA trust anchor
     	TSARootCAs *x509.CertPool
    +
    +	// TSARevocationValidator is used for validating revocation status of
    +	// timestamping certificate chain with context during signing.
    +	// When present, only used when timestamping is performed.
    +	TSARevocationValidator revocation.Validator
     }
     
     // Signer is a generic interface for signing an OCI artifact.
    
  • signer/signer.go+13 9 modified
    @@ -107,7 +107,6 @@ func (s *GenericSigner) Sign(ctx context.Context, desc ocispec.Descriptor, opts
     	if err != nil {
     		return nil, nil, fmt.Errorf("envelope payload can't be marshalled: %w", err)
     	}
    -
     	var signingAgentId string
     	if opts.SigningAgent != "" {
     		signingAgentId = opts.SigningAgent
    @@ -125,12 +124,13 @@ func (s *GenericSigner) Sign(ctx context.Context, desc ocispec.Descriptor, opts
     			ContentType: envelope.MediaTypePayloadV1,
     			Content:     payloadBytes,
     		},
    -		Signer:        s.signer,
    -		SigningTime:   time.Now(),
    -		SigningScheme: signature.SigningSchemeX509,
    -		SigningAgent:  signingAgentId,
    -		Timestamper:   opts.Timestamper,
    -		TSARootCAs:    opts.TSARootCAs,
    +		Signer:                 s.signer,
    +		SigningTime:            time.Now(),
    +		SigningScheme:          signature.SigningSchemeX509,
    +		SigningAgent:           signingAgentId,
    +		Timestamper:            opts.Timestamper,
    +		TSARootCAs:             opts.TSARootCAs,
    +		TSARevocationValidator: opts.TSARevocationValidator,
     	}
     
     	// Add expiry only if ExpiryDuration is not zero
    @@ -144,6 +144,12 @@ 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)
    +	if signReq.Timestamper != nil {
    +		logger.Debug("Enabled timestamping")
    +		if signReq.TSARevocationValidator != nil {
    +			logger.Debug("Enabled timestamping certificate chain revocation check")
    +		}
    +	}
     
     	// Add ctx to the SignRequest
     	signReq = signReq.WithContext(ctx)
    @@ -153,12 +159,10 @@ func (s *GenericSigner) Sign(ctx context.Context, desc ocispec.Descriptor, opts
     	if err != nil {
     		return nil, nil, err
     	}
    -
     	sig, err := sigEnv.Sign(signReq)
     	if err != nil {
     		return nil, nil, err
     	}
    -
     	envContent, err := sigEnv.Verify()
     	if err != nil {
     		return nil, nil, fmt.Errorf("generated signature failed verification: %v", err)
    
  • signer/signer_test.go+23 0 modified
    @@ -30,6 +30,8 @@ import (
     	"testing"
     	"time"
     
    +	"github.com/notaryproject/notation-core-go/revocation"
    +	"github.com/notaryproject/notation-core-go/revocation/purpose"
     	"github.com/notaryproject/notation-core-go/signature"
     	_ "github.com/notaryproject/notation-core-go/signature/cose"
     	_ "github.com/notaryproject/notation-core-go/signature/jws"
    @@ -257,6 +259,27 @@ func TestSignWithTimestamping(t *testing.T) {
     	if err == nil || err.Error() != expectedErrMsg {
     		t.Fatalf("expected %s, but got %s", expectedErrMsg, err)
     	}
    +
    +	// timestamping with unknown authority
    +	desc, sOpts = generateSigningContent()
    +	sOpts.SignatureMediaType = envelopeType
    +	sOpts.Timestamper, err = tspclient.NewHTTPTimestamper(nil, rfc3161URL)
    +	if err != nil {
    +		t.Fatal(err)
    +	}
    +	sOpts.TSARootCAs = x509.NewCertPool()
    +	tsaRevocationValidator, err := revocation.NewWithOptions(revocation.Options{
    +		CertChainPurpose: purpose.Timestamping,
    +	})
    +	if err != nil {
    +		t.Fatal(err)
    +	}
    +	sOpts.TSARevocationValidator = tsaRevocationValidator
    +	_, _, err = s.Sign(ctx, desc, sOpts)
    +	expectedErrMsg = "timestamp: failed to verify signed token: cms verification failure: x509: certificate signed by unknown authority"
    +	if err == nil || err.Error() != expectedErrMsg {
    +		t.Fatalf("expected %s, but got %s", expectedErrMsg, err)
    +	}
     }
     
     func TestSignWithoutExpiry(t *testing.T) {
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.