diff --git a/Crypto/OTP.hs b/Crypto/OTP.hs index af507f5..98e241f 100644 --- a/Crypto/OTP.hs +++ b/Crypto/OTP.hs @@ -33,7 +33,7 @@ hotp d k c = dt `mod` digitsPower d fromIntegral (B.index mac (offset + 3) .&. 0xff) -- | Attempt to resynchronize the server's counter value --- with the client, given a sequence of HOTP values +-- with the client, given a sequence of HOTP values. resynchronize :: ByteArrayAccess key => OTPDigits -> Word32 @@ -43,14 +43,13 @@ resynchronize :: ByteArrayAccess key -- ^ The shared secret -> Word64 -- ^ The current server counter value - -> Word32 - -- ^ The first OTP submitted by the client - -> [Word32] - -- ^ Additional sequential OTPs (may be empty) + -> (Word32, [Word32]) + -- ^ The first OTP submitted by the client and a list of additional + -- sequential OTPs (which may be empty) -> Maybe Word64 -- ^ The new counter value, synchronized with the client's current counter - -- or Nothing if the submitted OTP values didn't match -resynchronize d s k c p1 extras = do + -- or Nothing if the submitted OTP values didn't match anywhere within the window +resynchronize d s k c (p1, extras) = do offBy <- fmap fromIntegral (elemIndex p1 range) checkExtraOtps (c + offBy + 1) extras where diff --git a/tests/KAT_OTP.hs b/tests/KAT_OTP.hs index deba93e..069e13c 100644 --- a/tests/KAT_OTP.hs +++ b/tests/KAT_OTP.hs @@ -38,7 +38,7 @@ makeKATs = concatMap makeTest (zip3 is counts hotps) ] -- resynching with the expected value should just return the current counter + 1 -prop_resyncExpected ctr window = resynchronize OTP6 window key ctr otp [] == Just (ctr + 1) +prop_resyncExpected ctr window = resynchronize OTP6 window key ctr (otp, []) == Just (ctr + 1) where key = "1234" :: ByteString otp = hotp OTP6 key ctr