module Botan.Low.Bcrypt (
bcryptGenerate
, bcryptIsValid
, BcryptWorkFactor
, pattern BcryptFast
, pattern BcryptGood
, pattern BcryptStrong
, BcryptPassword
, BcryptDigest
) where
import Botan.Bindings.Bcrypt
import Botan.Bindings.ConstPtr (ConstPtr (..))
import Botan.Low.Error.Internal
import Botan.Low.Internal.ByteString
import Botan.Low.RNG
import Data.ByteString (ByteString)
import qualified Data.ByteString as ByteString
import Foreign.Marshal.Alloc
import Foreign.Ptr
import Foreign.Storable
type BcryptWorkFactor = Int
pattern BcryptFast
, BcryptGood
, BcryptStrong
:: BcryptWorkFactor
pattern $bBcryptFast :: BcryptWorkFactor
$mBcryptFast :: forall {r}. BcryptWorkFactor -> ((# #) -> r) -> ((# #) -> r) -> r
BcryptFast = BOTAN_BCRYPT_WORK_FACTOR_FAST
pattern $bBcryptGood :: BcryptWorkFactor
$mBcryptGood :: forall {r}. BcryptWorkFactor -> ((# #) -> r) -> ((# #) -> r) -> r
BcryptGood = BOTAN_BCRYPT_WORK_FACTOR_GOOD
pattern $bBcryptStrong :: BcryptWorkFactor
$mBcryptStrong :: forall {r}. BcryptWorkFactor -> ((# #) -> r) -> ((# #) -> r) -> r
BcryptStrong = BOTAN_BCRYPT_WORK_FACTOR_STRONG
type BcryptPassword = ByteString
type BcryptDigest = ByteString
bcryptGenerate
:: BcryptPassword
-> RNG
-> BcryptWorkFactor
-> IO BcryptDigest
bcryptGenerate :: BcryptPassword -> RNG -> BcryptWorkFactor -> IO BcryptPassword
bcryptGenerate BcryptPassword
password RNG
rng BcryptWorkFactor
factor = BcryptPassword
-> (Ptr CChar -> IO BcryptPassword) -> IO BcryptPassword
forall a. BcryptPassword -> (Ptr CChar -> IO a) -> IO a
asCString BcryptPassword
password ((Ptr CChar -> IO BcryptPassword) -> IO BcryptPassword)
-> (Ptr CChar -> IO BcryptPassword) -> IO BcryptPassword
forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
passwordPtr -> do
RNG -> (BotanRNG -> IO BcryptPassword) -> IO BcryptPassword
forall a. RNG -> (BotanRNG -> IO a) -> IO a
withRNG RNG
rng ((BotanRNG -> IO BcryptPassword) -> IO BcryptPassword)
-> (BotanRNG -> IO BcryptPassword) -> IO BcryptPassword
forall a b. (a -> b) -> a -> b
$ \ BotanRNG
botanRNG -> do
(Ptr CSize -> IO BcryptPassword) -> IO BcryptPassword
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CSize -> IO BcryptPassword) -> IO BcryptPassword)
-> (Ptr CSize -> IO BcryptPassword) -> IO BcryptPassword
forall a b. (a -> b) -> a -> b
$ \ Ptr CSize
szPtr -> do
Ptr CSize -> CSize -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CSize
szPtr CSize
80
BcryptWorkFactor
-> (Ptr Word8 -> IO BcryptPassword) -> IO BcryptPassword
forall a b. BcryptWorkFactor -> (Ptr a -> IO b) -> IO b
allocaBytes BcryptWorkFactor
80 ((Ptr Word8 -> IO BcryptPassword) -> IO BcryptPassword)
-> (Ptr Word8 -> IO BcryptPassword) -> IO BcryptPassword
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
outPtr -> do
HasCallStack => IO CInt -> IO ()
IO CInt -> IO ()
throwBotanIfNegative_ (IO CInt -> IO ()) -> IO CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ Ptr Word8
-> Ptr CSize
-> ConstPtr CChar
-> BotanRNG
-> CSize
-> Word32
-> IO CInt
botan_bcrypt_generate
Ptr Word8
outPtr
Ptr CSize
szPtr
(Ptr CChar -> ConstPtr CChar
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr CChar
passwordPtr)
BotanRNG
botanRNG
(BcryptWorkFactor -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral BcryptWorkFactor
factor)
Word32
0
Ptr CChar -> IO BcryptPassword
ByteString.packCString (Ptr Word8 -> Ptr CChar
forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
outPtr)
bcryptIsValid ::
BcryptPassword
-> BcryptDigest
-> IO Bool
bcryptIsValid :: BcryptPassword -> BcryptPassword -> IO Bool
bcryptIsValid BcryptPassword
password BcryptPassword
hash =
BcryptPassword -> (Ptr CChar -> IO Bool) -> IO Bool
forall a. BcryptPassword -> (Ptr CChar -> IO a) -> IO a
asCString BcryptPassword
password ((Ptr CChar -> IO Bool) -> IO Bool)
-> (Ptr CChar -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
passwordPtr ->
BcryptPassword -> (Ptr CChar -> IO Bool) -> IO Bool
forall a. BcryptPassword -> (Ptr CChar -> IO a) -> IO a
asCString BcryptPassword
hash ((Ptr CChar -> IO Bool) -> IO Bool)
-> (Ptr CChar -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
hashPtr ->
HasCallStack => IO CInt -> IO Bool
IO CInt -> IO Bool
throwBotanCatchingInvalidVerifier (IO CInt -> IO Bool) -> IO CInt -> IO Bool
forall a b. (a -> b) -> a -> b
$ ConstPtr CChar -> ConstPtr CChar -> IO CInt
botan_bcrypt_is_valid (Ptr CChar -> ConstPtr CChar
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr CChar
passwordPtr) (Ptr CChar -> ConstPtr CChar
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr CChar
hashPtr)