From 0f5be3fccda75fce066b0f1b869c83b530247f25 Mon Sep 17 00:00:00 2001 From: Fumiaki Kinoshita Date: Mon, 22 Nov 2021 21:57:07 +0900 Subject: [PATCH] introduce VerifyArgs --- src/WebAuthn.hs | 33 +++++++++++++++++++-------------- test/Tests.hs | 15 +++++++++++++-- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/WebAuthn.hs b/src/WebAuthn.hs index 2a51640..a0e5bbc 100644 --- a/src/WebAuthn.hs +++ b/src/WebAuthn.hs @@ -37,6 +37,7 @@ module WebAuthn ( , registerCredential , CredentialCreationOptions(..) , defaultCredentialCreationOptions + , VerifyArgs(..) , verify , encodeAttestation ) where @@ -202,23 +203,27 @@ registerCredential certStore opts@CredentialCreationOptions{..} clientDataJSON a -- non present public key will fail anyway or the fmt == 'none' Nothing -> return Nothing +data VerifyArgs = VerifyArgs + { challenge :: Challenge + , relyingParty :: RelyingParty + , tokenBindingID :: Maybe Text + , requireVerification :: Bool + , clientDataJSON :: ByteString + , authenticatorData :: ByteString + , signature :: ByteString + , credentialPublicKey :: CredentialPublicKey + } + -- | 7.2. Verifying an Authentication Assertion -verify :: Challenge - -> RelyingParty - -> Maybe Text -- ^ Token Binding ID in base64 - -> Bool -- ^ require user verification? - -> ByteString -- ^ clientDataJSON - -> ByteString -- ^ authenticatorData - -> ByteString -- ^ signature - -> CredentialPublicKey -- ^ public key +verify :: VerifyArgs -> Either VerificationFailure () -verify challenge rp tbi verificationRequired clientDataJSON adRaw sig pub = do - clientDataCheck Get challenge clientDataJSON rp tbi +verify VerifyArgs{..} = do + clientDataCheck Get challenge clientDataJSON relyingParty tokenBindingID let clientDataHash = hash clientDataJSON :: Digest SHA256 - _ <- verifyAuthenticatorData rp adRaw verificationRequired - let dat = adRaw <> BA.convert clientDataHash - pub' <- parsePublicKey pub - verifySig pub' sig dat + _ <- verifyAuthenticatorData relyingParty authenticatorData requireVerification + let dat = authenticatorData <> BA.convert clientDataHash + pub' <- parsePublicKey credentialPublicKey + verifySig pub' signature dat clientDataCheck :: WebAuthnType -> Challenge -> ByteString -> RelyingParty -> Maybe Text -> Either VerificationFailure () clientDataCheck ctype challenge clientDataJSON rp tbi = do diff --git a/test/Tests.hs b/test/Tests.hs index 4927cb1..bd32553 100644 --- a/test/Tests.hs +++ b/test/Tests.hs @@ -4,7 +4,9 @@ {-# LANGUAGE RecordWildCards #-} import WebAuthn ( registerCredential, - verify ) + VerifyArgs(..), + verify, + ) import Test.Tasty ( defaultMain, testGroup, TestTree ) import Test.Tasty.HUnit (assertEqual, assertBool, testCaseSteps ) import Data.String.Interpolate () @@ -126,7 +128,16 @@ genericCredentialTest name TestPublicKeyCredential{..} time = testCaseSteps name assertBool (show eth) (isRight eth) let Right cdata = eth step "Verification check..." - let eth = verify getChallenge defRp Nothing False getClientDataJSON getAuthenticatorData getSignature cdata.credentialPublicKey + let eth = verify VerifyArgs + { challenge = getChallenge + , relyingParty = defRp + , tokenBindingID = Nothing + , requireVerification = False + , clientDataJSON = getClientDataJSON + , authenticatorData = getAuthenticatorData + , signature = getSignature + , credentialPublicKey = cdata.credentialPublicKey + } assertBool (show eth) (isRight eth) registrationTest :: TestTree