botan-low-0.1.0.0: src/Botan/Low/Utility.hs
{-|
Module : Botan.Low.Utility
Description : Utility functions
Copyright : (c) 2023-2024, Apotheca Labs
(c) 2024-2025, Haskell Foundation
License : BSD-3-Clause
Maintainer : joris@well-typed.com, leo@apotheca.io
Stability : experimental
Portability : POSIX
This module is based on the [Utility
Functions](https://botan.randombit.net/handbook/api_ref/ffi.html#utility-functions)
section of the C Botan FFI documentation.
-}
module Botan.Low.Utility (
constantTimeCompare
, scrubMem
, HexEncodingFlags(..)
, hexEncode
, hexDecode
, base64Encode
, base64Decode
) where
import Botan.Bindings.ConstPtr (ConstPtr (..))
import Botan.Bindings.Utility
import Botan.Low.Error.Internal
import Botan.Low.Internal.ByteString
import Botan.Low.Make
import Data.ByteString (ByteString)
import Data.Text
import qualified Data.Text.Encoding as Text
import Data.Word
import Foreign.Ptr
-- | Returns 0 if x[0..len] == y[0..len], -1 otherwise.
constantTimeCompare ::
ByteString -- ^ __x__
-> ByteString -- ^ __y__
-> Int -- ^ __len__
-> IO Bool
constantTimeCompare x y len =
asBytesLen x $ \ xPtr _xlen ->
asBytesLen y $ \ yPtr _ylen -> do
result <- botan_constant_time_compare
(ConstPtr xPtr)
(ConstPtr yPtr)
(fromIntegral len)
case result of
0 -> return True
_ -> return False
scrubMem ::
Ptr a -- ^ __mem__
-> Int -- ^ __bytes__
-> IO ()
scrubMem ptr sz = throwBotanIfNegative_ $ botan_scrub_mem (castPtr ptr) (fromIntegral sz)
data HexEncodingFlags =
HexUpperCase
| HexLowerCase
hexEncodingFlags :: HexEncodingFlags -> Word32
hexEncodingFlags HexUpperCase = BOTAN_FFI_HEX_UPPER_CASE
hexEncodingFlags HexLowerCase = BOTAN_FFI_HEX_LOWER_CASE
hexEncode ::
ByteString -- ^ __x__
-> HexEncodingFlags -- ^ __flags__
-> IO Text -- ^ __y__
hexEncode bytes flags =
fmap Text.decodeUtf8 $
asBytesLen bytes $ \ bytesPtr bytesLen ->
allocBytes (fromIntegral $ 2 * bytesLen) $ \ hexPtr ->
throwBotanIfNegative_ $ botan_hex_encode
(ConstPtr bytesPtr)
bytesLen
hexPtr
(hexEncodingFlags flags)
hexDecode ::
Text -- ^ __hex_str__
-> IO ByteString -- ^ __out__
hexDecode txt =
asBytesLen (Text.encodeUtf8 txt) $ \ hexPtr hexLen ->
allocBytesQuerying $ \ bytesPtr szPtr ->
botan_hex_decode
(ConstPtr hexPtr)
hexLen
bytesPtr
szPtr
base64Encode ::
ByteString -- ^ __x__
-> IO Text -- ^ __out__
base64Encode bytes =
fmap Text.decodeUtf8 $
asBytesLen bytes $ \ bytesPtr bytesLen ->
allocBytesQueryingCString $ \ base64Ptr szPtr ->
botan_base64_encode
(ConstPtr bytesPtr)
bytesLen
base64Ptr
szPtr
base64Decode ::
Text -- ^ __base64_str__
-> IO ByteString -- ^ __out__
base64Decode txt =
asBytesLen (Text.encodeUtf8 txt) $ \ base64Ptr base64Len ->
allocBytesQueryingCString $ \ bytesPtr szPtr ->
botan_base64_decode
(ConstPtr base64Ptr)
base64Len
bytesPtr
szPtr