Closed edgmnt closed 7 years ago
Yep, we can do better. I need to think about what the API should look like. Ideas welcome.
I think it should look the same, but take a JWKSet instead of a JWK. The current validation policy stuff makes sense, e.g. one or all signatures must check out, but each can come from a different key in the set.
I want to make sure that the type will admit a more general implementation in future, e.g. instead of a JWKSet, consider a map structure that looks up keys efficiently by "kid" or ""x5t#S256" parameter if present in the JWS header, otherwise performs a linear search (or aborts).
So something like:
class JWKStore a where
keysFor
-- parameters shared by JWS and JWE header
:: ( HasAlg h, HasJku h, HasJwk h, HasKid h
, HasX5u h, HasX5c h, HasX5t h, HasX5t_S256 h
, HasTyp h, HasCty h )
=> h -> Fold a JWK
instance JWKStore JWK where
... -- constant fold; just the single key
instance Foldable t => JWKStore (t JWK) where
... -- constant fold; all the keys in the container
instance JWKStore JWKSet where
... -- constant fold; everything in the JWKSet
verifyJWS
:: ( HasAlgorithms a, HasValidationPolicy a, AsError e, MonadError e m
, HasJWSHeader h, HasParams h
, JWKStore k )
=> a
-> k
-> JWS h
-> m ()
verifyJWS = ...
This approach would allow verifyJWS
to be used with both single JWK
as
well as a JWKSet
or any Foldable t => t JWK
. Existing code will be compatible.
And the JWKStore
class can be used to build any (pure) key lookup structure
that can use almost any information available in JWS or JWE header.
Sound alright?
Not sure when I'll get around to implementing it...
I implemented it. Could you please review to see how well it meets your needs? (On master
branch).
@edgmnt ping. Does the current implementation meet your needs?
@frasertweedale Sorry it took me so long to reply. Yes, it's alright, although it should also work for JWTs, so validateJWSJWT should also take a JWKStore.
Right, good point @edgmnt. I'll do that and hopefully cut a new release in the not too distant future.
There should be a helper that validates a JWT/JWS using a JWKSet instead of just one key. I'm not sure if we can do better than verifying against all keys in the JWKSet. Any thoughts?
This is useful for checking Google's JWTs, because they publish multiple keys as a JWKSet.