jose-0.13: test/Perf.hs
{-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-}
{-
Test program for ensuring that verification of a large JWT
happens in reasonable time. This program is based on a test
program published by Silvan Mosberger at:
https://github.com/tweag/haskell-fido2/tree/a25308a07551ccd86af47774a74dbdf989454d51
Related: https://github.com/frasertweedale/hs-jose/pull/103
-}
import Control.Lens ((^?), _Just)
import Control.Monad.Except (ExceptT, runExceptT)
import Crypto.JOSE.JWK.Store (VerificationKeyStore (getVerificationKeys))
import Crypto.JWT (CompactJWS, HasX5c (x5c), JWSHeader, JWTError, RequiredProtection, decodeCompact, fromX509Certificate, param, verifyJWS')
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L
import Data.List.NonEmpty (NonEmpty ((:|)))
import System.Timeout (timeout)
import System.Exit (die)
data Store = Store
instance VerificationKeyStore (ExceptT JWTError IO) (JWSHeader RequiredProtection) B.ByteString Store where
getVerificationKeys header _ _ = do
let Just (x :| _) = header ^? x5c . _Just . param
res <- fromX509Certificate x
return [res]
main :: IO ()
main = do
s <- L.readFile path
r <- timeout 500000 (go s)
case r of
Nothing -> die "Verifying the big JWT timed out!"
Just _ -> pure ()
where
path = "test/data/fido.jwt"
go :: L.ByteString -> IO ()
go s = do
r <- runExceptT $ do
jws <- decodeCompact s
verifyJWS' Store (jws :: CompactJWS JWSHeader)
case r of
Left err ->
die $ "Verification failure: " ++ show (err :: JWTError)
Right payload ->
putStrLn $ "Payload verified (size = " ++ show (B.length payload) ++ ")"