jose-jwt 0.7.5 → 0.7.6
raw patch · 7 files changed
+54/−12 lines, 7 filesdep ~eitherPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: either
API changes (from Hackage documentation)
Files
- CHANGELOG.md +7/−1
- Jose/Internal/Parser.hs +1/−1
- Jose/Jwe.hs +28/−7
- Jose/Jwk.hs +12/−1
- Jose/Jwt.hs +3/−1
- jose-jwt.cabal +1/−1
- tests/Tests/JweSpec.hs +2/−0
CHANGELOG.md view
@@ -1,7 +1,13 @@+0.7.6+-----++* Fixed exception when JWT contained invalid Base64 (issue #15).+* Add generateSymmetricKey utility function to Jwk module.+ 0.7.5 ----- -* A JWT parser is now used to separate parsing and decoding into separaate stages (internal change).+* A JWT parser is now used to separate parsing and decoding into separate stages (internal change). 0.7.4 -----
Jose/Internal/Parser.hs view
@@ -139,4 +139,4 @@ b64Decode :: ByteString -> P.Parser ByteString-b64Decode bs = either (fail "Invalid Base64") return $ convertFromBase Base64URLUnpadded bs+b64Decode bs = either (const (fail "Invalid Base64")) return $ convertFromBase Base64URLUnpadded bs
Jose/Jwe.hs view
@@ -1,16 +1,37 @@ {-# LANGUAGE OverloadedStrings #-} --- | JWE RSA encrypted token support.+-- | JWE encrypted token support. ----- Example usage:+-- To create a JWE, you need to select two algorithms. One is an AES algorithm+-- used to encrypt the content of your token (for example, @A128GCM@), for which+-- a single-use key is generated internally. The second is used to encrypt+-- this content-encryption key and can be either an RSA or AES-keywrap algorithm.+-- You need to generate a suitable key to use with this, or load one from storage. --+-- AES is much faster and creates shorter tokens, but both the encoder and decoder+-- of the token need to have a copy of the key, which they must keep secret. With+-- RSA anyone can send you a JWE if they have a copy of your public key.+--+-- In the example below, we show encoding and decoding using a 512 byte RSA key pair+-- (in practice you would use a larger key-size, for example 2048 bytes):+-- -- >>> import Jose.Jwe -- >>> import Jose.Jwa--- >>> import Crypto.PubKey.RSA--- >>> (kPub, kPr) <- generate 512 65537--- >>> Right (Jwt jwt) <- rsaEncode RSA_OAEP A128GCM kPub "secret claims"--- >>> rsaDecode kPr jwt--- Right (JweHeader {jweAlg = RSA_OAEP, jweEnc = A128GCM, jweTyp = Nothing, jweCty = Nothing, jweZip = Nothing, jweKid = Nothing},"secret claims")+-- >>> import Jose.Jwk (generateRsaKeyPair, generateSymmetricKey, KeyUse(Enc), KeyId)+-- >>> (kPub, kPr) <- generateRsaKeyPair 512 (KeyId "My RSA Key") Enc Nothing+-- >>> Right (Jwt jwt) <- jwkEncode RSA_OAEP A128GCM kPub (Claims "secret claims")+-- >>> Right (Jwe (hdr, claims)) <- jwkDecode kPr jwt+-- >>> claims+-- "secret claims"+--+-- Using 128-bit AES keywrap is very similar, the main difference is that+-- we generate a 128-bit symmetric key:+--+-- >>> aesKey <- generateSymmetricKey 16 (KeyId "My Keywrap Key") Enc Nothing+-- >>> Right (Jwt jwt) <- jwkEncode A128KW A128GCM aesKey (Claims "more secret claims")+-- >>> Right (Jwe (hdr, claims)) <- jwkDecode aesKey jwt+-- >>> claims+-- "more secret claims" module Jose.Jwe ( jwkEncode
Jose/Jwk.hs view
@@ -15,12 +15,13 @@ , canEncodeJws , canEncodeJwe , generateRsaKeyPair+ , generateSymmetricKey ) where import Control.Applicative (pure) import Control.Monad (unless)-import Crypto.Random (MonadRandom)+import Crypto.Random (MonadRandom, getRandomBytes) import qualified Crypto.PubKey.RSA as RSA import qualified Crypto.PubKey.ECC.ECDSA as ECDSA import qualified Crypto.PubKey.ECC.Types as ECC@@ -72,6 +73,16 @@ generateRsaKeyPair nBytes id' kuse kalg = do (kPub, kPr) <- RSA.generate nBytes 65537 return (RsaPublicJwk kPub (Just id') (Just kuse) kalg, RsaPrivateJwk kPr (Just id') (Just kuse) kalg)++generateSymmetricKey :: (MonadRandom m)+ => Int+ -> KeyId+ -> KeyUse+ -> Maybe Alg+ -> m Jwk+generateSymmetricKey size id' kuse kalg = do+ k <- getRandomBytes size+ return $ SymmetricJwk k (Just id') (Just kuse) kalg isPublic :: Jwk -> Bool isPublic RsaPublicJwk {} = True
Jose/Jwt.hs view
@@ -3,7 +3,9 @@ -- | High-level JWT encoding and decoding. ----- Example usage:+-- See the Jose.Jws and Jose.Jwe modules for specific JWS and JWE examples.+--+-- Example usage with a key stored as a JWK: -- -- >>> import Jose.Jwe -- >>> import Jose.Jwa
jose-jwt.cabal view
@@ -1,5 +1,5 @@ Name: jose-jwt-Version: 0.7.5+Version: 0.7.6 Synopsis: JSON Object Signing and Encryption Library Homepage: http://github.com/tekul/jose-jwt Bug-Reports: http://github.com/tekul/jose-jwt/issues
tests/Tests/JweSpec.hs view
@@ -150,6 +150,8 @@ unpad "111\t\t\t\t\t\t\t" @?= Nothing it "Padding byte which matches padding length is OK" $ unpad "1111111\t\t\t\t\t\t\t\t\t" @?= Just "1111111"+ it "Rejects invalid Base64 JWT" $+ withBlinder (Jwe.rsaDecode a2PrivKey "=.") @?= Left BadCrypto -- verboseQuickCheckWith quickCheckWith stdArgs {maxSuccess=10000} jweRoundTrip jweRoundTrip :: RNG -> JWEAlgs -> [Word8] -> Bool