h$81      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX Safe-InferredYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ Safe-Inferred nMIT Stefan Saasen  experimentalNone  #$'(2>1&)jwtThe JWT Claims Set represents a JSON object whose members are the claims conveyed by the JWT.jwtThe iss (issuer) claim identifies the principal that issued the JWT.jwtThe sub (subject) claim identifies the principal that is the subject of the JWT.jwtThe aud (audience) claim identifies the audiences that the JWT is intended for according to draft 18 of the JWT spec, the aud claim is option and may be present in singular or as a list.jwtThe exp (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. Its value MUST be a number containing an IntDate value. jwtThe nbf (not before) claim identifies the time before which the JWT MUST NOT be accepted for processing. jwtThe iat (issued at) claim identifies the time at which the JWT was issued. jwtThe jti (JWT ID) claim provides a unique identifier for the JWT. jwtJOSE Header, describes the cryptographic operations applied to the JWTjwtThe typ (type) Header Parameter defined by [JWS] and [JWE] is used to declare the MIME Media Type [IANA.MediaTypes] of this complete JWT in contexts where this is useful to the application. This parameter has no effect upon the JWT processing.jwtThe cty (content type) Header Parameter defined by [JWS] and [JWE] is used by this specification to convey structural information about the JWT.jwtThe alg (algorithm) used for signing the JWT. The HS256 (HMAC using SHA-256) is the only required algorithm in addition to "none" which means that no signature will be used.See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-23#page-6jwtThe "kid" (key ID) Header Parameter is a hint indicating which key was used to secure the JWS. This parameter allows originators to explicitly signal a change of key to recipients. The structure of the "kid" value is unspecified. Its value MUST be a case-sensitive string. Use of this Header Parameter is OPTIONAL.See 1https://tools.ietf.org/html/rfc7515#section-4.1.4jwt!HMAC using SHA-256 hash algorithmjwt RSA using SHA-256 hash algorithmjwtA JSON string value, with the additional requirement that while arbitrary string values MAY be used, any value containing a ":" character MUST be a URI [RFC3986]. StringOrURI values are compared as case-sensitive strings with no transformations or canonicalizations applied.jwtA JSON numeric value representing the number of seconds from 1970-01-01T0:0:0Z UTC until the specified UTC date/time.jwtA JSON numeric value representing the number of seconds from 1970-01-01T0:0:0Z UTC until the specified UTC date/time.jwtThe JSON Web Tokenjwt2JSON Web Token that has been successfully verifiedjwt-JSON Web Token without signature verification%jwt,Extract the claims set from a JSON Web Token&jwt(Extract the header from a JSON Web Token'jwt4Extract the signature from a verified JSON Web Token(jwt=Return the seconds since 1970-01-01T0:0:0Z UTC for the given )jwt*Encode a claims set using the given secret:{ let: cs = mempty { -- mempty returns a default JWTClaimsSet) iss = stringOrURI . T.pack $ "Foo" , unregisteredClaims = ClaimsMap $ Map.fromList [(T.pack "http://example.com/is_root", (Bool True))] }, key = hmacSecret . T.pack $ "secret-key"in encodeSigned key mempty cs:}"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6dHJ1ZSwiaXNzIjoiRm9vIn0.vHQHuG3ujbnBUmEp-fSUtYxk27rLiP2hrNhxpyWhb2E"*jwt&Encode a claims set without signing it:{let cs = mempty6 { iss = stringOrURI . Data.Text.pack $ "Foo"( , iat = numericDate 1394700934 , unregisteredClaims = ClaimsMap $ Data.Map.fromList [(Data.Text.pack "http://example.com/is_root", (Bool True))] }in encodeUnsigned cs mempty:}"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjEzOTQ3MDA5MzQsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlLCJpc3MiOiJGb28ifQ."+jwtDecode a claims set without verifying the signature. This is useful if information from the claim set is required in order to verify the claim (e.g. the secret needs to be retrieved based on unverified information from the claims set).:{ let input = Data.Text.pack "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9.Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U" mJwt = decode input in fmap header mJwt:}Just (JOSEHeader {typ = Just "JWT", cty = Nothing, alg = Just HS256, kid = Nothing})and:{ let input = T.pack "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9.Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U" mJwt = decode input in fmap claims mJwt:}Just (JWTClaimsSet {iss = Nothing, sub = Nothing, aud = Nothing, exp = Nothing, nbf = Nothing, iat = Nothing, jti = Nothing, unregisteredClaims = ClaimsMap {unClaimsMap = fromList [("some",String "payload")]}}),jwtUsing a known secret and a decoded claims set verify that the signature is correct and return a verified JWT token as a result.This will return a VerifiedJWT if and only if the signature can be verified using the given secret.The separation between decode and verify is very useful if you are communicating with multiple different services with different secrets and it allows you to lookup the correct secret for the unverified JWT before trying to verify it. If this is not an isuse for you (there will only ever be one secret) then you should just use -.:{ let input = T.pack "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9.Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U"" mUnverifiedJwt = decode input mVerifiedJwt = verify (toVerify . hmacSecret . T.pack $ "secret") =<< mUnverifiedJwt in signature =<< mVerifiedJwt:}>Just (Signature "Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U")-jwtDecode a claims set and verify that the signature matches by using the supplied secret. The algorithm is based on the supplied header value.This will return a VerifiedJWT if and only if the signature can be verified using the given secret.:{ let input = T.pack "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9.Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U" mJwt = decodeAndVerifySignature (toVerify . hmacSecret . T.pack $ "secret") input in signature =<< mJwt:}>Just (Signature "Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U").jwt3Try to extract the value for the issue claim field  from the web token in JSON form/jwt5Create a Secret using the given key. Consider using  HMACSecret& instead if your key is not already a  Data.Text.0jwtConverts an EncodeSigner into a VerifySigner If you can encode then you can always verify; but the reverse is not always true.1jwt)Create an RSAPrivateKey from PEM contentsPlease, consider using 2 instead.2jwtCreate an RSA  from PEM contents 'readRsaSecret <$> BS.readFile "foo.pem":{ : -- A random example key created with `ssh-keygen -t rsa`. fromJust . readRsaSecret . C8.pack $ unlines) [ "-----BEGIN RSA PRIVATE KEY-----" , "MIIEowIBAAKCAQEAkkmgbLluo5HommstpHr1h53uWfuN3CwYYYR6I6a2MzAHIMIv" , "8Ak2ha+N2UDeYsfVhZ/DOnE+PMm2RpYSaiYT0l2a7ZkmRSbcyvVFt3XLePJbmUgo" , "ieyccS4uYHeqRggdWH9His3JaR2N71N9iU0+mY5nu2+15iYw3naT/PSx01IzBqHN" , "Zie1z3FYX09FgOs31mcR8VWj8DefxbKE08AW+vDMT2AmUC2b+Gqk6SqRz29HuPBs" , "yyV4Xl9CgzcCWjuXTv6mevDygo5RVZg34U6L1iFRgwwHbrLcd2N97wlKz+OiDSgM" , "sbZWA0i2D9ZsDR9rdEdXzUIw6toIRYZfeI9QYQIDAQABAoIBAEXkh5Fqx0G/ZLLi" , "olwDo2u4OTkkxxJ6vutYsEJ4VHUAbWdpYB3/SN12kv9JzvbDI3FEc7JoiKPifAQd" , "j47HwpCvyGXc1jwT5UnTBgwxa5XNtZX2s+ex9Mzek6njgqcTGXI+3Z+j0qc2R6og" , "6cm/7jjPoSAcr3vWo2KmpO4muw+LbYoSGo0Jydoa5cGtkmDfsjjrMw7mDoRttdhw" , "WdhS+q2aJPFI7q7itoYUd7KLe3nOeM0zd35Pc8Qc6jGk+JZxQdXrb/NrSNgAATcN" , "GGS226Q444N0pAfc188IDcAtQPSJpzbs/1+TPzE4ov/lpHTr91hXr3RLyVgYBI01" , "jrggfAECgYEAwaC4iDSZQ+8eUx/zR973Lu9mvQxC2BZn6QcOtBcIRBdGRlXfhwuD" , "UgwVZ2M3atH5ZXFuQ7pRtJtj7KCFy7HUFAJC15RCfLjx+n39bISNp5NOJEdI+UM+" , "G2xMHv5ywkULV7Jxb+tSgsYIvJ0tBjACkif8ahNjgVJmgMSOgdHR2pkCgYEAwWkN" , "uquRqKekx4gx1gJYV7Y6tPWcsZpEcgSS7AGNJ4UuGZGGHdStpUoJICn2cFUngYNz" , "eJXOg+VhQJMqQx9c+u85mg/tJluGaw95tBAafspwvhKewlO9OhQeVInPbXMUwrJ0" , "PS3XV7c74nxm6Nn4QHlM07orn3lOiWxZF8BBSQkCgYATjwSU3ZtNvW22v9d3PxKA" , "7zXVitOFuF2usEPP9TOkjSVQHYSCw6r0MrxGwULry2IB2T9mH//42mlxkZVySfg+" , "PSw7UoKUzqnCv89Fku4sKzkNeRXp99ziMEJQLyuwbAEFTsUepQqkoxRm2QmfQmJA" , "GUHqBSNcANLR1wj+HA+yoQKBgQCBlqj7RQ+AaGsQwiFaGhIlGtU1AEgv+4QWvRfQ" , "B64TJ7neqdGp1SFP2U5J/bPASl4A+hl5Vy6a0ysZQEGV3cLH41e98SPdin+C5kiO" , "LCgEghGOWR2EaOUlr+sui3OvCueDGFynzTo27G+0bdPp+nnKgTvHtTqbTIUhsLX1" , "IvzbOQKBgH4q36jgBb9T3hjXtWyrytlmFtBdw0i+UiMvMlnOqujGhcnOk5UMyxOQ" , "sQI+/31jIGbmlE7YaYykR1FH3LzAjO4J1+m7vv5fIRdG8+sI01xTc8UAdbmWtK+5"> , "TK1oLP43BHH5gRAfIlXj2qmap5lEG6If/xYB4MOs8Bui5iKaJlM5"' , "-----END RSA PRIVATE KEY-----" ]:}PrivateKey {private_pub = PublicKey {public_size = 256, public_n = 1846..., public_e = 65537}, private_d = 8823..., private_p = 135..., private_q = 1358..., private_dP = 1373..., private_dQ = 9100..., private_qinv = 8859...}3jwtCreate an RSA  from PEM contents 1 readRsaPublicKey <$> BS.readFile "foo.pub" >> :{fromJust . readRsaPublicKey . Data.ByteString.Char8.pack $ Data.List.unlines [ "-----BEGIN PUBLIC KEY-----" , MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA12d4M6f3QQ9E52fVjoJ7 , "HorKvi1A83f4YL4e7TU0Lj/73+afrRBtnAdl8dIrnYHLWRdL9T4+yw7+AimQgj1R" , "zZO5FQN+qVxygkPeMKAZ53nObi2NyBbQYmRrBjx7rOz7UddI5qoApTWNrSBjDKK" , "1splbuO2BoTrsHlsSoJDWps/5SwpEF4GGkn5c4nZRnpnayUZqolp+HwDK2Dys9MO" , "GEIsUil1+k376T96pBnPf6mf3X0IacTCNjJcztSaHCPWre1q45miQUGVlTmhfg6" , "L8xmNRxz4BZdv8Nv6STfRTsn6PqiaabD0vITVsF1AapdHohmPMwe+lG5ebUJEh8p" , HQIDAQAB , "-----END PUBLIC KEY-----" ] :} PublicKey {public_size = 256, public_n = 27192258298637073499814714121384917708820189127612408586659742012541332375187297990620494295383503839337630959589643433993051132285579261506578281787130221431792495554016841577295914249477128682873612830754668313951998800261326356221445367133271958375798088350587817966390021082924122322621635687775325677158394714044356852489350530339926527334843762933075425870780010358838296108179073735084189560997222261973170469403371017667139302904425235800700389626242339763391588052694912470921008842459564204534000688115202764921141372629345213727775126077560633656612484128950350759146471467728292335666402631045889956718877, public_e = 65537}4jwt Convert the  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).5jwt Convert the  into an NumericDate. Returns a Nothing if the argument is invalid (e.g. the NominalDiffTime must be convertible into a positive Integer representing the seconds since epoch).6jwt Convert a  into a . Returns a Nothing if the String cannot be converted (e.g. if the String contains a : but is *not* a valid URI).7jwt Convert a  into a . Returns the T.Text representing the String as-is or a Text representation of the URI otherwise.8jwt Convert the  claim in a  into a `[StringOrURI]`9  !"#$%&'()*+,-./0123456789+,-)*./230%&'84567( !"# $ 1      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\Z]^Z]_Z]`Z]aZ]bZ]cZ]dZ]eZ]fZ]gZ]hZ]iZ]jZ]kZ]lZ]mZ]nZ]oZ]pZ]qZ]rZ]sZ]tZ]uZ]vZ]wZ]xZ]yZ]zZ]{Z]|Z]}Z]~Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]Z]^p~yzvw!jwt-0.11.0-JT38LoL5oq478nbDu9QiFsWeb.JWTData.ByteString.ExtendedData.Text.Extended ClaimsMap unClaimsMap JWTClaimsSetisssubaudexpnbfiatjtiunregisteredClaims JOSEHeadertypctyalgkid AlgorithmHS256RS256 StringOrURI NumericDateIntDateJWT VerifiedJWT UnverifiedJWT Signature EncodeSignerEncodeHMACSecretEncodeRSAPrivateKey VerifySignerVerifyHMACSecretVerifyRSAPrivateKeyVerifyRSAPublicKey JWTHeaderclaimsheader signaturesecondsSinceEpoch encodeSignedencodeUnsigneddecodeverifydecodeAndVerifySignature tokenIssuer hmacSecrettoVerify rsaKeySecret readRsaSecretreadRsaPublicKeyintDate numericDate stringOrURIstringOrURIToTextauds $fEqSignature$fFromJSONNumericDate$fToJSONNumericDate$fFromJSONStringOrURI$fToJSONStringOrURI$fShowStringOrURI$fFromJSONAlgorithm$fToJSONAlgorithm$fToJSONJOSEHeader$fFromJSONJOSEHeader$fSemigroupJOSEHeader$fMonoidJOSEHeader$fSemigroupClaimsMap$fMonoidClaimsMap$fFromJSONJWTClaimsSet$fToJSONJWTClaimsSet$fSemigroupJWTClaimsSet$fMonoidJWTClaimsSet$fShowJWTClaimsSet$fEqJWTClaimsSet $fEqClaimsMap$fShowClaimsMap$fEqJOSEHeader$fShowJOSEHeader $fEqAlgorithm$fShowAlgorithm$fEqStringOrURI$fShowNumericDate$fEqNumericDate$fOrdNumericDate$fShowSignature $fShowJWTbytestring-0.10.10.0Data.ByteString.Internal ByteStringData.ByteStringempty appendFile writeFilereadFileinteract getContents hGetContentshGetSomehGetNonBlockinghGetputStrLnputStr hPutStrLnhPutStrhPutNonBlockinghPuthGetLinegetLinecopypackCStringLen packCStringuseAsCStringLen useAsCStringsorttailsinitsunzipzipWithzipfindSubstrings findSubstringbreakSubstring isInfixOf stripSuffix isSuffixOf stripPrefix isPrefixOf partitionfindfilternotElemelem findIndices findIndexcount elemIndices elemIndexEnd elemIndexindex intercalategroupBygroupsplit splitWithspanEndspanbreakEnd breakBytebreak dropWhile takeWhilesplitAtdroptakeunfoldrNunfoldr replicatescanr1scanrscanl1scanl mapAccumR mapAccumLminimummaximumallany concatMapconcatfoldr1'foldr1foldl1'foldl1foldr'foldrfoldl'foldl transpose interspersereversemapappendunsnocinitlastunconstailheadsnocconslengthnullunpackpack singletonconstTimeCompare text-1.2.3.2Data.Text.InternalText Data.TextcommonPrefixesunwordsunlineslineswords breakOnAll breakOnEndbreakOnchunksOfsplitOnstripstripEnd stripStart dropAround dropWhileEnd takeWhileEnddropEndtakeEndcenter justifyRight justifyLefttoTitletoUppertoLower toCaseFoldreplace compareLengthData.Text.ShowunpackCString#&cryptonite-0.29-8UjeKblvt5oLV3wQh3d00OCrypto.PubKey.RSA.Types PrivateKey PublicKey time-1.9.3(Data.Time.Clock.Internal.NominalDiffTimeNominalDiffTime