diff --git a/Changes b/Changes index 26dabe5ca..14d26bd7f 100644 --- a/Changes +++ b/Changes @@ -5,6 +5,10 @@ v2 has many incompatibilities with v1. To see the full list of differences betwe v1 and v2, please read the Changes-v2.md file (https://github.com/lestrrat-go/jwx/blob/develop/v2/Changes-v2.md) v2.0.17 UNRELEASED +[Bug Fixes] + * [jws] Previously, `jws.UnregisterSigner` did not remove the previous signer instance when + the signer was registered and unregistered multiple times. This has been fixed. + [New Features] * [jwe] (EXPERIMENTAL) `jwe.WithCEK` has been added to extract the content encryption key (CEK) from the Decrypt operation. * [jwe] (EXPERIMENTAL) `jwe.EncryptStatic` has been added to encrypt content using a static CEK. diff --git a/jws/jws.go b/jws/jws.go index a348c6186..4cf2c3175 100644 --- a/jws/jws.go +++ b/jws/jws.go @@ -74,6 +74,12 @@ func (s *payloadSigner) PublicHeader() Headers { var signers = make(map[jwa.SignatureAlgorithm]Signer) var muSigner = &sync.Mutex{} +func removeSigner(alg jwa.SignatureAlgorithm) { + muSigner.Lock() + defer muSigner.Unlock() + delete(signers, alg) +} + func makeSigner(alg jwa.SignatureAlgorithm, key interface{}, public, protected Headers) (*payloadSigner, error) { muSigner.Lock() signer, ok := signers[alg] diff --git a/jws/jws_test.go b/jws/jws_test.go index bf29b5a8b..d0a311056 100644 --- a/jws/jws_test.go +++ b/jws/jws_test.go @@ -2044,6 +2044,19 @@ func TestGH910(t *testing.T) { require.NoError(t, err, `jws.Verify should succeed`) require.Equal(t, src, string(verified), `verified payload should match`) + + jws.UnregisterSigner(sha256Algo) + + // Now try after unregistering the signer for the algorithm + _, err = jws.Sign([]byte(src), jws.WithKey(sha256Algo, nil)) + require.Error(t, err, `jws.Sign should succeed`) + + jws.RegisterSigner(sha256Algo, jws.SignerFactoryFn(func() (jws.Signer, error) { + return s256SignerVerifier{}, nil + })) + + _, err = jws.Sign([]byte(src), jws.WithKey(sha256Algo, nil)) + require.NoError(t, err, `jws.Sign should succeed`) } func TestUnpaddedSignatureR(t *testing.T) { diff --git a/jws/signer.go b/jws/signer.go index 44c8bfb76..39da72863 100644 --- a/jws/signer.go +++ b/jws/signer.go @@ -34,6 +34,9 @@ func RegisterSigner(alg jwa.SignatureAlgorithm, f SignerFactory) { muSignerDB.Lock() signerDB[alg] = f muSignerDB.Unlock() + + // Remove previous signer, if there was one + removeSigner(alg) } // UnregisterSigner removes the signer factory associated with @@ -49,6 +52,8 @@ func UnregisterSigner(alg jwa.SignatureAlgorithm) { muSignerDB.Lock() delete(signerDB, alg) muSignerDB.Unlock() + // Remove previous signer + removeSigner(alg) } func init() {