fosite icon indicating copy to clipboard operation
fosite copied to clipboard

fix: sign with jose.OpaqueSigner check incorrect key type

Open elct9620 opened this issue 6 months ago • 3 comments

Related Issue or Design Document

I am working on an internal OAuth2 server that needs to sign JWTs using AWS KMS.

However, the jwt.DefaultSigner doesn't work correctly. It is caused by checking the public key against the private key type.

https://github.com/ory/fosite/blob/8052806a6efe52832867d24cd41b17463190903d/token/jwt/jwt.go#L58-L79

If I provide a jose.OpaqueSigner wrapper to the AWS KMS, it will get this error

Error creating access response: unsupported private / public key pairs: *example.KmsSigner, *rsa.PublicKey

To fix it, I change PrivateKey to PublicKey and add new test case to cover it.

Checklist

  • [x] I have read the contributing guidelines and signed the CLA.
  • [x] I have referenced an issue containing the design document if my change introduces a new feature.
  • [x] I have read the security policy.
  • [x] I confirm that this pull request does not address a security vulnerability. If this pull request addresses a security vulnerability, I confirm that I got approval (please contact [email protected]) from the maintainers to push the changes.
  • [x] I have added tests that prove my fix is effective or that my feature works.
  • [x] I have added the necessary documentation within the code base (if appropriate).

Further comments

elct9620 avatar Jun 20 '25 06:06 elct9620

Please rebase from latest master branch to fix CI issues.

mitar avatar Jul 01 '25 12:07 mitar

@mitar done 💪

elct9620 avatar Jul 01 '25 13:07 elct9620

Hi, @aeneasr

Can you explain more details about it?

The jose.OpaqueSigner have following interface:

type OpaqueSigner interface {
	// Public returns the public key of the current signing key.
	Public() *JSONWebKey
	// Algs returns a list of supported signing algorithms.
	Algs() []SignatureAlgorithm
	// SignPayload signs a payload with the current signing key using the given
	// algorithm.
	SignPayload(payload []byte, alg SignatureAlgorithm) ([]byte, error)
}

It means we only know the public key but cannot access the private key (stored on HSM or remote service, e.g., AWS KMS)

I changed the type from PrivateKey to PublicKey because we do not have any private key in our memory, and the Generate method uses t.Public().Key.(type) to get its type.

It enables the correct detection of the key type and continues to generate the key. After the key is signed by HSM, we are still able to use t.Public() to get the public key to verify it.

This change only applies to Generate to allow it can choose the correct alg type, I think it does not break the Validate method.

elct9620 avatar Jul 03 '25 09:07 elct9620