packages feed

jwt 0.7.0 → 0.7.1

raw patch · 7 files changed

+104/−55 lines, 7 filesbinary-added

Files

CHANGELOG.md view
@@ -1,86 +1,91 @@+# 2016-04-11 0.7.1++* Add `binarySecret` function to enable providing a secret based on a `ByteString`+  (fixes #21 - Thanks to Joe Nelson for reporting this).+ # 2016-02-20 0.7.0 -	* Update JWT to match RFC 7519. This is a backward compatible change with-	deprecation warnings added for types and functions to be removed in the-	future.-		* Add NumericDate as a replacement for IntDate (and numericDate as a -		  replacement for intDate)-		* Add JOSEHeader as a replacement for JWTHeader.-	* Use Stack and LTS 4.0-    * Use cryptonite instead of cryptohash (Thanks to Greg V)-    * Remove Web.Base64 in favour of using `memory` (Thanks to Greg V)+* Update JWT to match RFC 7519. This is a backward compatible change with+deprecation warnings added for types and functions to be removed in the+future.+	* Add NumericDate as a replacement for IntDate (and numericDate as a +	  replacement for intDate)+	* Add JOSEHeader as a replacement for JWTHeader.+* Use Stack and LTS 4.0+* Use cryptonite instead of cryptohash (Thanks to Greg V)+* Remove Web.Base64 in favour of using `memory` (Thanks to Greg V)  # 2015-04-22 0.6.0 -	* Execute doctests in addition to the testsuite when using 'make test'.-	* Export `ClaimsMap` type alias (fixes #12)-	* Allow base 4.8-	* Lowered required cabal library version (to 1.16) to workaround build-	  issues in a consumer project.-	* Add 7.10.1 to the travis config+* Execute doctests in addition to the testsuite when using 'make test'.+* Export `ClaimsMap` type alias (fixes #12)+* Allow base 4.8+* Lowered required cabal library version (to 1.16) to workaround build+  issues in a consumer project.+* Add 7.10.1 to the travis config  # 2015-01-19 0.5.3 -	* Add the missing `other-modules` field to the .cabal file so that -	  all the tests are present in the source distribution. Thanks to -	  Richard Wallace for reporting this.+* Add the missing `other-modules` field to the .cabal file so that +  all the tests are present in the source distribution. Thanks to +  Richard Wallace for reporting this.  # 2015-01-17 0.5.2 -	* Tim McLean pointed out that comparing signatures may be susceptible to-	  a timing attack in the way the signatures were compared (using the default-	  Eq instance). Both `Signature` and `Secret` now have an `Eq` instance that-	  uses a constant time comparison function. Thanks Tim for reporting this.+* Tim McLean pointed out that comparing signatures may be susceptible to+  a timing attack in the way the signatures were compared (using the default+  Eq instance). Both `Signature` and `Secret` now have an `Eq` instance that+  uses a constant time comparison function. Thanks Tim for reporting this.  # 2015-01-03 0.5.1 -	* Fix the encoding of the `aud` part of the claim.-	  Thanks to Aaron Levin for reporting and implementing the change.-	  In addition to the fix we now also verify the shape fo the generated-	  payload.+* Fix the encoding of the `aud` part of the claim.+  Thanks to Aaron Levin for reporting and implementing the change.+  In addition to the fix we now also verify the shape fo the generated+  payload.  # 2014-12-01 0.5.0 -	* Rev. 17 of the JWT Draft changed the audience claim from being an-	optional String to being either an optional `StringOrURI`s or an optional list of-	`StringOrURI`s. Thanks to Aaron Levin for reporting and implementing the-	change. This change breaks backwards compatibility (in regard to 0.4.x).+* Rev. 17 of the JWT Draft changed the audience claim from being an+  optional String to being either an optional `StringOrURI`s or an optional list of+  `StringOrURI`s. Thanks to Aaron Levin for reporting and implementing the+  change. This change breaks backwards compatibility (in regard to 0.4.x).  # 2014-10-15 0.4.2 -	* Fix the build problems introduced in 0.4.1 to work with the -	  split network package. Thanks to Richard Wallace for-	  fixing this and to Jeremy Shaw for reporting this at the same time.+* Fix the build problems introduced in 0.4.1 to work with the +  split network package. Thanks to Richard Wallace for+  fixing this and to Jeremy Shaw for reporting this at the same time.  # 2014-09-17 0.4.1 -	* Update jwt.cabal to work with the new split network package.-	  Thanks to Jeremy Shaw for reporting this.+* Update jwt.cabal to work with the new split network package.+  Thanks to Jeremy Shaw for reporting this.  # 2014-08-02 0.4.0 -	* Change the upper boundary of base from 4.7 to 4.8 (#5)+* Change the upper boundary of base from 4.7 to 4.8 (#5)  # 2014-06-02 0.3.0 -	* Add verify function (thanks to Robert Massaioli) to allow verifying an-	already decoded JWT token+* Add verify function (thanks to Robert Massaioli) to allow verifying an+  already decoded JWT token  # 2014-03-10 0.2.1 -    * Add Decoding/Encoding sections-    * Make the examples runnable by doctest-    * Fix hlint warnings-    * Add 'secondsSinceEpoch' to extract the seconds from epoch from an IntDate+* Add Decoding/Encoding sections+* Make the examples runnable by doctest+* Fix hlint warnings+* Add 'secondsSinceEpoch' to extract the seconds from epoch from an IntDate  # 2014-03-10 0.2.0 -	* Export the IntDate and StringOrURI types #5a1137b+* Export the IntDate and StringOrURI types #5a1137b  # 2014-03-03  0.1.1 -	* Verify that invalid input to the decode* functions fails as expected+* Verify that invalid input to the decode\* functions fails as expected  # 2014-03-03  0.1.0 -	* Initial release+* Initial release
jwt.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                jwt-version:             0.7.0+version:             0.7.1 synopsis:            JSON Web Token (JWT) decoding and encoding license:             MIT license-file:        LICENSE@@ -22,6 +22,7 @@ extra-source-files:     CHANGELOG.md     README.md+    tests/jwt.secret.1  source-repository head     type: git@@ -29,7 +30,7 @@  library   exposed-modules:     Web.JWT-  other-modules:       Data.Text.Extended+  other-modules:       Data.Text.Extended, Data.ByteString.Extended   build-depends:       base >= 4.6 && < 4.9                      , cryptonite               >= 0.6                      , memory                   >= 0.8
+ src/Data/ByteString/Extended.hs view
@@ -0,0 +1,14 @@+module Data.ByteString.Extended (+    module Data.ByteString+  , constTimeCompare+) where++import           Data.Bits+import           Data.ByteString+import qualified Data.List       as L+import           Prelude         hiding (length, zip, zipWith)++constTimeCompare :: ByteString -> ByteString -> Bool+constTimeCompare l r = length l == length r && comp' l r+  where+    comp' a b = 0 == L.foldl' (.|.) 0 (uncurry xor <$> zip a b)
src/Web/JWT.hs view
@@ -40,6 +40,7 @@     -- ** Common     , tokenIssuer     , secret+    , binarySecret     -- ** JWT structure     , claims     , header@@ -76,6 +77,7 @@     ) where  import qualified Data.ByteString.Lazy.Char8 as BL (fromStrict, toStrict)+import qualified Data.ByteString.Extended as BS import qualified Data.Text.Extended         as T import qualified Data.Text.Encoding         as TE @@ -107,10 +109,10 @@ type JWTHeader = JOSEHeader  -- | The secret used for calculating the message signature-newtype Secret = Secret T.Text+newtype Secret = Secret BS.ByteString  instance Eq Secret where-    (Secret s1) == (Secret s2) = s1 `T.constTimeCompare` s2+    (Secret s1) == (Secret s2) = s1 `BS.constTimeCompare` s2  instance Show Secret where     show _ = "<secret>"@@ -353,13 +355,15 @@ tokenIssuer :: JSON -> Maybe StringOrURI tokenIssuer = decode >=> fmap pure claims >=> iss --- | Create a Secret using the given key--- This will currently simply wrap the given key appropriately buy may--- return a Nothing in the future if the key needs to adhere to a specific--- format and the given key is invalid.+-- | Create a Secret using the given key.+-- Consider using `binarySecret` instead if your key is not already a "Data.Text". secret :: T.Text -> Secret-secret = Secret+secret = Secret . TE.encodeUtf8 +-- | Create a Secret using the given key.+binarySecret :: BS.ByteString -> Secret+binarySecret = Secret+ -- | Convert the `NominalDiffTime` into an IntDate. Returns a Nothing if the -- argument is invalid (e.g. the NominalDiffTime must be convertible into a -- positive Integer representing the seconds since epoch).@@ -413,7 +417,7 @@ -- =================================================================================  calculateDigest :: Algorithm -> Secret -> T.Text -> T.Text-calculateDigest HS256 (Secret key) msg = TE.decodeUtf8 $ convertToBase Base64URLUnpadded (hmac (bs key) (bs msg) :: HMAC SHA256)+calculateDigest HS256 (Secret key) msg = TE.decodeUtf8 $ convertToBase Base64URLUnpadded (hmac key (bs msg) :: HMAC SHA256)     where          bs = TE.encodeUtf8 
+ tests/jwt.secret.1 view

binary file changed (absent → 64 bytes)

tests/src/TestRunner.hs view
@@ -3,6 +3,7 @@ import qualified Web.JWTTests import qualified Web.JWTTestsCompat import qualified Web.JWTInteropTests+import qualified Data.ByteString.ExtendedTests import qualified Data.Text.ExtendedTests import           Test.Tasty @@ -15,5 +16,6 @@                   , Web.JWTTestsCompat.defaultTestGroup                   , Web.JWTInteropTests.defaultTestGroup                   , Data.Text.ExtendedTests.defaultTestGroup+                  , Data.ByteString.ExtendedTests.defaultTestGroup                 ] 
tests/src/Web/JWTTests.hs view
@@ -14,7 +14,9 @@ import qualified Test.QuickCheck as QC import qualified Data.Map              as Map import qualified Data.Text             as T+import qualified Data.Text.Encoding         as TE import qualified Data.Text.Lazy        as TL+import qualified Data.ByteString as BS import           Data.Aeson.Types import           Data.Maybe import           Data.String (fromString, IsString)@@ -186,6 +188,17 @@         jwt = decodeAndVerifySignature secret' $ encodeSigned HS256 secret' cs     Just cs @=? fmap claims jwt +case_encodeDecodeJWTClaimsSetBinarySecret = do+    let now = 1234+        cs = def {+            iss = stringOrURI "Foo"+          , iat = numericDate now+        }+    secretKey <- BS.readFile "tests/jwt.secret.1"+    let secret' = binarySecret secretKey+        jwt = decodeAndVerifySignature secret' $ encodeSigned HS256 secret' cs+    Just cs @=? fmap claims jwt+ prop_stringOrURIProp = f     where f :: StringOrURI -> Bool           f sou = let s = stringOrURI $ T.pack $ show sou@@ -203,12 +216,18 @@           f key claims' = let Just unverified = (decode $ encodeSigned HS256 (secret key) claims')                           in claims unverified == claims' +prop_encode_decode_binary_secret = f+    where f :: BS.ByteString -> JWTClaimsSet -> Bool+          f binary claims' = let Just unverified = (decode $ encodeSigned HS256 (binarySecret binary) claims')+                          in claims unverified == claims'+ prop_encode_decode_verify_signature = f     where f :: T.Text -> JWTClaimsSet -> Bool           f key' claims' = let key = secret key'                                Just verified = (decodeAndVerifySignature key $ encodeSigned HS256 key claims')                            in claims verified == claims' + instance Arbitrary JWTClaimsSet where     arbitrary = JWTClaimsSet <$> arbitrary                              <*> arbitrary@@ -234,6 +253,10 @@     arbitrary = fmap (f . stringOrURI) (arbitrary :: QC.Gen T.Text)         where             f = fromMaybe (fromJust $ stringOrURI "http://example.com")++instance Arbitrary BS.ByteString where+    arbitrary = BS.pack <$> arbitrary+    shrink xs = BS.pack <$> shrink (BS.unpack xs)  instance Arbitrary T.Text where     arbitrary = fromString <$> (arbitrary :: QC.Gen String)