module Botan.Low.TOTP
(
TOTP(..)
, TOTPHashName(..)
, TOTPTimestep(..)
, TOTPTimestamp(..)
, TOTPCode(..)
, withTOTP
, totpInit
, totpDestroy
, totpGenerate
, totpCheck
, pattern TOTP_SHA1
, pattern TOTP_SHA256
, pattern TOTP_SHA512
, totpHashes
) where
import qualified Data.ByteString as ByteString
import Botan.Bindings.TOTP
import Botan.Low.Error
import Botan.Low.Hash
import Botan.Low.Make
import Botan.Low.Prelude
import Botan.Low.Remake
newtype TOTP = MkTOTP { TOTP -> ForeignPtr BotanTOTPStruct
getTOTPForeignPtr :: ForeignPtr BotanTOTPStruct }
newTOTP :: BotanTOTP -> IO TOTP
withTOTP :: TOTP -> (BotanTOTP -> IO a) -> IO a
totpDestroy :: TOTP -> IO ()
createTOTP :: (Ptr BotanTOTP -> IO CInt) -> IO TOTP
(BotanTOTP -> IO TOTP
newTOTP, TOTP -> (BotanTOTP -> IO a) -> IO a
withTOTP, TOTP -> IO ()
totpDestroy, (Ptr BotanTOTP -> IO CInt) -> IO TOTP
createTOTP, (Ptr BotanTOTP -> Ptr CSize -> IO CInt) -> IO [TOTP]
_)
= (Ptr BotanTOTPStruct -> BotanTOTP)
-> (BotanTOTP -> Ptr BotanTOTPStruct)
-> (ForeignPtr BotanTOTPStruct -> TOTP)
-> (TOTP -> ForeignPtr BotanTOTPStruct)
-> FinalizerPtr BotanTOTPStruct
-> (BotanTOTP -> IO TOTP, TOTP -> (BotanTOTP -> IO a) -> IO a,
TOTP -> IO (), (Ptr BotanTOTP -> IO CInt) -> IO TOTP,
(Ptr BotanTOTP -> Ptr CSize -> IO CInt) -> IO [TOTP])
forall botan struct object a.
Storable botan =>
(Ptr struct -> botan)
-> (botan -> Ptr struct)
-> (ForeignPtr struct -> object)
-> (object -> ForeignPtr struct)
-> FinalizerPtr struct
-> (botan -> IO object, object -> (botan -> IO a) -> IO a,
object -> IO (), (Ptr botan -> IO CInt) -> IO object,
(Ptr botan -> Ptr CSize -> IO CInt) -> IO [object])
mkBindings
Ptr BotanTOTPStruct -> BotanTOTP
MkBotanTOTP BotanTOTP -> Ptr BotanTOTPStruct
runBotanTOTP
ForeignPtr BotanTOTPStruct -> TOTP
MkTOTP TOTP -> ForeignPtr BotanTOTPStruct
getTOTPForeignPtr
FinalizerPtr BotanTOTPStruct
botan_totp_destroy
type TOTPHashName = HashName
pattern TOTP_SHA1
, TOTP_SHA256
, TOTP_SHA512
:: TOTPHashName
pattern $mTOTP_SHA1 :: forall {r}. TOTPHashName -> ((# #) -> r) -> ((# #) -> r) -> r
$bTOTP_SHA1 :: TOTPHashName
TOTP_SHA1 = SHA1
pattern $mTOTP_SHA256 :: forall {r}. TOTPHashName -> ((# #) -> r) -> ((# #) -> r) -> r
$bTOTP_SHA256 :: TOTPHashName
TOTP_SHA256 = SHA256
pattern $mTOTP_SHA512 :: forall {r}. TOTPHashName -> ((# #) -> r) -> ((# #) -> r) -> r
$bTOTP_SHA512 :: TOTPHashName
TOTP_SHA512 = SHA512
totpHashes :: [TOTPHashName]
totpHashes =
[ TOTPHashName
TOTP_SHA1
, TOTPHashName
TOTP_SHA256
, TOTPHashName
TOTP_SHA512
]
type TOTPTimestep = Word64
type TOTPTimestamp = Word64
type TOTPCode = Word32
totpInit
:: ByteString
-> TOTPHashName
-> Int
-> TOTPTimestep
-> IO TOTP
totpInit :: TOTPHashName -> TOTPHashName -> Int -> TOTPTimestep -> IO TOTP
totpInit TOTPHashName
key TOTPHashName
algo Int
digits TOTPTimestep
timestep = TOTPHashName -> (Ptr Word8 -> CSize -> IO TOTP) -> IO TOTP
forall byte a. TOTPHashName -> (Ptr byte -> CSize -> IO a) -> IO a
asBytesLen TOTPHashName
key ((Ptr Word8 -> CSize -> IO TOTP) -> IO TOTP)
-> (Ptr Word8 -> CSize -> IO TOTP) -> IO TOTP
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
keyPtr CSize
keyLen -> do
TOTPHashName -> (Ptr CChar -> IO TOTP) -> IO TOTP
forall a. TOTPHashName -> (Ptr CChar -> IO a) -> IO a
asCString TOTPHashName
algo ((Ptr CChar -> IO TOTP) -> IO TOTP)
-> (Ptr CChar -> IO TOTP) -> IO TOTP
forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
algoPtr -> do
(Ptr BotanTOTP -> IO CInt) -> IO TOTP
createTOTP ((Ptr BotanTOTP -> IO CInt) -> IO TOTP)
-> (Ptr BotanTOTP -> IO CInt) -> IO TOTP
forall a b. (a -> b) -> a -> b
$ \ Ptr BotanTOTP
out -> Ptr BotanTOTP
-> ConstPtr Word8
-> CSize
-> ConstPtr CChar
-> CSize
-> CSize
-> IO CInt
botan_totp_init
Ptr BotanTOTP
out
(Ptr Word8 -> ConstPtr Word8
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr Word8
keyPtr)
CSize
keyLen
(Ptr CChar -> ConstPtr CChar
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr CChar
algoPtr)
(Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
digits)
(TOTPTimestep -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral TOTPTimestep
timestep)
withTOTPInit :: ByteString -> ByteString -> Int -> TOTPTimestep -> (TOTP -> IO a) -> IO a
withTOTPInit :: forall a.
TOTPHashName
-> TOTPHashName -> Int -> TOTPTimestep -> (TOTP -> IO a) -> IO a
withTOTPInit = (TOTPHashName -> TOTPHashName -> Int -> TOTPTimestep -> IO TOTP)
-> (TOTP -> IO ())
-> TOTPHashName
-> TOTPHashName
-> Int
-> TOTPTimestep
-> (TOTP -> IO a)
-> IO a
forall x y z w t a.
(x -> y -> z -> w -> IO t)
-> (t -> IO ()) -> x -> y -> z -> w -> (t -> IO a) -> IO a
mkWithTemp4 TOTPHashName -> TOTPHashName -> Int -> TOTPTimestep -> IO TOTP
totpInit TOTP -> IO ()
totpDestroy
totpGenerate
:: TOTP
-> TOTPTimestamp
-> IO TOTPCode
totpGenerate :: TOTP -> TOTPTimestep -> IO Word32
totpGenerate TOTP
totp TOTPTimestep
timestamp = TOTP -> (BotanTOTP -> IO Word32) -> IO Word32
forall a. TOTP -> (BotanTOTP -> IO a) -> IO a
withTOTP TOTP
totp ((BotanTOTP -> IO Word32) -> IO Word32)
-> (BotanTOTP -> IO Word32) -> IO Word32
forall a b. (a -> b) -> a -> b
$ \ BotanTOTP
totpPtr -> do
(Ptr Word32 -> IO Word32) -> IO Word32
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Word32 -> IO Word32) -> IO Word32)
-> (Ptr Word32 -> IO Word32) -> IO Word32
forall a b. (a -> b) -> a -> b
$ \ Ptr Word32
outPtr -> do
HasCallStack => IO CInt -> IO CInt
IO CInt -> IO CInt
throwBotanIfNegative (IO CInt -> IO CInt) -> IO CInt -> IO CInt
forall a b. (a -> b) -> a -> b
$ BotanTOTP -> Ptr Word32 -> TOTPTimestep -> IO CInt
botan_totp_generate BotanTOTP
totpPtr Ptr Word32
outPtr TOTPTimestep
timestamp
Ptr Word32 -> IO Word32
forall a. Storable a => Ptr a -> IO a
peek Ptr Word32
outPtr
totpCheck
:: TOTP
-> TOTPCode
-> TOTPTimestamp
-> Int
-> IO Bool
totpCheck :: TOTP -> Word32 -> TOTPTimestep -> Int -> IO Bool
totpCheck TOTP
totp Word32
code TOTPTimestep
timestamp Int
drift = TOTP -> (BotanTOTP -> IO Bool) -> IO Bool
forall a. TOTP -> (BotanTOTP -> IO a) -> IO a
withTOTP TOTP
totp ((BotanTOTP -> IO Bool) -> IO Bool)
-> (BotanTOTP -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \ BotanTOTP
totpPtr -> do
HasCallStack => IO CInt -> IO Bool
IO CInt -> IO Bool
throwBotanCatchingSuccess (IO CInt -> IO Bool) -> IO CInt -> IO Bool
forall a b. (a -> b) -> a -> b
$ BotanTOTP -> Word32 -> TOTPTimestep -> CSize -> IO CInt
botan_totp_check BotanTOTP
totpPtr Word32
code TOTPTimestep
timestamp (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
drift)