{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RoleAnnotations #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Sel.SecretKey.Stream
(
encryptList
, decryptList
, Multipart
, encryptStream
, encryptChunk
, decryptStream
, decryptChunk
, SecretKey
, newSecretKey
, secretKeyFromHexByteString
, unsafeSecretKeyToHexByteString
, Header
, headerToHexByteString
, headerFromHexByteString
, MessageTag (..)
, CipherText
, ciphertextFromHexByteString
, ciphertextToBinary
, ciphertextToHexByteString
, ciphertextToHexText
, StreamInitEncryptionException
, StreamEncryptionException
, StreamDecryptionException
) where
import Control.Exception (Exception, throw)
import Control.Monad (forM, when)
import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.Base16.Types (Base16)
import qualified Data.Base16.Types as Base16
import Data.ByteString (StrictByteString)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Base16 as Base16
import qualified Data.ByteString.Internal as BSI
import qualified Data.ByteString.Unsafe as BSU
import Data.Kind (Type)
import qualified Data.List as List
import Data.Text (Text)
import qualified Data.Text as Text
import Data.Text.Display (Display (..), OpaqueInstance (..))
import qualified Data.Text.Lazy.Builder as Builder
import Data.Word (Word8)
import Foreign (ForeignPtr, Ptr)
import qualified Foreign
import Foreign.C (CChar, CSize, CUChar, CULLong)
import Foreign.C.Error (throwErrno)
import System.IO.Unsafe (unsafeDupablePerformIO)
import LibSodium.Bindings.SecretStream
( CryptoSecretStreamXChaCha20Poly1305State
, cryptoSecretStreamXChaCha20Poly1305ABytes
, cryptoSecretStreamXChaCha20Poly1305HeaderBytes
, cryptoSecretStreamXChaCha20Poly1305InitPull
, cryptoSecretStreamXChaCha20Poly1305InitPush
, cryptoSecretStreamXChaCha20Poly1305KeyBytes
, cryptoSecretStreamXChaCha20Poly1305KeyGen
, cryptoSecretStreamXChaCha20Poly1305Pull
, cryptoSecretStreamXChaCha20Poly1305Push
, cryptoSecretStreamXChaCha20Poly1305StateBytes
, cryptoSecretStreamXChaCha20Poly1305TagFinal
, cryptoSecretStreamXChaCha20Poly1305TagMessage
, cryptoSecretStreamXChaCha20Poly1305TagPush
, cryptoSecretStreamXChaCha20Poly1305TagRekey
)
import LibSodium.Bindings.SecureMemory (finalizerSodiumFree, sodiumMalloc)
import Sel.Internal (allocateWith, foreignPtrEq, foreignPtrOrd)
newtype Multipart s = Multipart (Ptr CryptoSecretStreamXChaCha20Poly1305State)
type role Multipart nominal
encryptStream
:: forall (a :: Type) (m :: Type -> Type)
. MonadIO m
=> SecretKey
-> (forall s. Multipart s -> m a)
-> m (Header, a)
encryptStream :: forall a (m :: * -> *).
MonadIO m =>
SecretKey -> (forall s. Multipart s -> m a) -> m (Header, a)
encryptStream (SecretKey ForeignPtr CUChar
secretKeyForeignPtr) forall s. Multipart s -> m a
actions = CSize
-> (Ptr CryptoSecretStreamXChaCha20Poly1305State -> m (Header, a))
-> m (Header, a)
forall a b (m :: * -> *).
MonadIO m =>
CSize -> (Ptr a -> m b) -> m b
allocateWith CSize
cryptoSecretStreamXChaCha20Poly1305StateBytes ((Ptr CryptoSecretStreamXChaCha20Poly1305State -> m (Header, a))
-> m (Header, a))
-> (Ptr CryptoSecretStreamXChaCha20Poly1305State -> m (Header, a))
-> m (Header, a)
forall a b. (a -> b) -> a -> b
$ \Ptr CryptoSecretStreamXChaCha20Poly1305State
statePtr -> do
Ptr CUChar
headerPtr <- IO (Ptr CUChar) -> m (Ptr CUChar)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Ptr CUChar) -> m (Ptr CUChar))
-> IO (Ptr CUChar) -> m (Ptr CUChar)
forall a b. (a -> b) -> a -> b
$ CSize -> IO (Ptr CUChar)
forall a. CSize -> IO (Ptr a)
sodiumMalloc CSize
cryptoSecretStreamXChaCha20Poly1305HeaderBytes
ForeignPtr CUChar
headerForeignPtr <- IO (ForeignPtr CUChar) -> m (ForeignPtr CUChar)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (ForeignPtr CUChar) -> m (ForeignPtr CUChar))
-> IO (ForeignPtr CUChar) -> m (ForeignPtr CUChar)
forall a b. (a -> b) -> a -> b
$ FinalizerPtr CUChar -> Ptr CUChar -> IO (ForeignPtr CUChar)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
Foreign.newForeignPtr FinalizerPtr CUChar
forall a. FinalizerPtr a
finalizerSodiumFree Ptr CUChar
headerPtr
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Ptr CUChar
headerPtr Ptr CUChar -> Ptr CUChar -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr CUChar
forall a. Ptr a
Foreign.nullPtr) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (String -> IO ()
forall a. String -> IO a
throwErrno String
"sodium_malloc")
IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ ForeignPtr CUChar -> (Ptr CUChar -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
Foreign.withForeignPtr ForeignPtr CUChar
secretKeyForeignPtr ((Ptr CUChar -> IO ()) -> IO ()) -> (Ptr CUChar -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
secretKeyPtr -> do
CInt
result <-
Ptr CryptoSecretStreamXChaCha20Poly1305State
-> Ptr CUChar -> Ptr CUChar -> IO CInt
cryptoSecretStreamXChaCha20Poly1305InitPush
Ptr CryptoSecretStreamXChaCha20Poly1305State
statePtr
Ptr CUChar
headerPtr
Ptr CUChar
secretKeyPtr
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (CInt
result CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
/= CInt
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ StreamInitEncryptionException -> IO ()
forall a e. Exception e => e -> a
throw StreamInitEncryptionException
StreamInitEncryptionException
let part :: Multipart s
part = Ptr CryptoSecretStreamXChaCha20Poly1305State -> Multipart s
forall s.
Ptr CryptoSecretStreamXChaCha20Poly1305State -> Multipart s
Multipart Ptr CryptoSecretStreamXChaCha20Poly1305State
statePtr
let header :: Header
header = ForeignPtr CUChar -> Header
Header ForeignPtr CUChar
headerForeignPtr
a
result <- Multipart Any -> m a
forall s. Multipart s -> m a
actions Multipart Any
forall {s}. Multipart s
part
(Header, a) -> m (Header, a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Header
header, a
result)
encryptChunk
:: forall m s
. MonadIO m
=> Multipart s
-> MessageTag
-> StrictByteString
-> m CipherText
encryptChunk :: forall (m :: * -> *) s.
MonadIO m =>
Multipart s -> MessageTag -> StrictByteString -> m CipherText
encryptChunk (Multipart Ptr CryptoSecretStreamXChaCha20Poly1305State
statePtr) MessageTag
messageTag StrictByteString
message = IO CipherText -> m CipherText
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO CipherText -> m CipherText) -> IO CipherText -> m CipherText
forall a b. (a -> b) -> a -> b
$ StrictByteString -> (CStringLen -> IO CipherText) -> IO CipherText
forall a. StrictByteString -> (CStringLen -> IO a) -> IO a
BSU.unsafeUseAsCStringLen StrictByteString
message ((CStringLen -> IO CipherText) -> IO CipherText)
-> (CStringLen -> IO CipherText) -> IO CipherText
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
cString, Int
cStringLen) -> do
let messagePtr :: Ptr CUChar
messagePtr = forall a b. Ptr a -> Ptr b
Foreign.castPtr @CChar @CUChar Ptr CChar
cString
let messageLen :: CULLong
messageLen = forall a b. (Integral a, Num b) => a -> b
fromIntegral @Int @CULLong Int
cStringLen
ForeignPtr CUChar
cipherTextFPtr <- Int -> IO (ForeignPtr CUChar)
forall a. Int -> IO (ForeignPtr a)
Foreign.mallocForeignPtrBytes (Int
cStringLen Int -> Int -> Int
forall a. Num a => a -> a -> a
+ CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
cryptoSecretStreamXChaCha20Poly1305ABytes)
ForeignPtr CUChar -> (Ptr CUChar -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
Foreign.withForeignPtr ForeignPtr CUChar
cipherTextFPtr ((Ptr CUChar -> IO ()) -> IO ()) -> (Ptr CUChar -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
cipherTextBuffer -> do
CInt
result <-
Ptr CryptoSecretStreamXChaCha20Poly1305State
-> Ptr CUChar
-> Ptr CULLong
-> Ptr CUChar
-> CULLong
-> Ptr CUChar
-> CULLong
-> CUChar
-> IO CInt
cryptoSecretStreamXChaCha20Poly1305Push
Ptr CryptoSecretStreamXChaCha20Poly1305State
statePtr
Ptr CUChar
cipherTextBuffer
Ptr CULLong
forall a. Ptr a
Foreign.nullPtr
Ptr CUChar
messagePtr
CULLong
messageLen
Ptr CUChar
forall a. Ptr a
Foreign.nullPtr
CULLong
0
(MessageTag -> CUChar
messageTagToConstant MessageTag
messageTag)
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (CInt
result CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
/= CInt
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ StreamEncryptionException -> IO ()
forall a e. Exception e => e -> a
throw StreamEncryptionException
StreamEncryptionException
CipherText -> IO CipherText
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CipherText -> IO CipherText) -> CipherText -> IO CipherText
forall a b. (a -> b) -> a -> b
$ CULLong -> ForeignPtr CUChar -> CipherText
CipherText (Int -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
cStringLen) ForeignPtr CUChar
cipherTextFPtr
encryptList :: forall m. MonadIO m => SecretKey -> [StrictByteString] -> m (Header, [CipherText])
encryptList :: forall (m :: * -> *).
MonadIO m =>
SecretKey -> [StrictByteString] -> m (Header, [CipherText])
encryptList SecretKey
secretKey [StrictByteString]
messages = SecretKey
-> (forall {s}. Multipart s -> m [CipherText])
-> m (Header, [CipherText])
forall a (m :: * -> *).
MonadIO m =>
SecretKey -> (forall s. Multipart s -> m a) -> m (Header, a)
encryptStream SecretKey
secretKey ((forall {s}. Multipart s -> m [CipherText])
-> m (Header, [CipherText]))
-> (forall {s}. Multipart s -> m [CipherText])
-> m (Header, [CipherText])
forall a b. (a -> b) -> a -> b
$ \Multipart s
multipart -> Multipart s -> [StrictByteString] -> [CipherText] -> m [CipherText]
forall s.
Multipart s -> [StrictByteString] -> [CipherText] -> m [CipherText]
go Multipart s
multipart [StrictByteString]
messages []
where
go :: Multipart s -> [StrictByteString] -> [CipherText] -> m [CipherText]
go :: forall s.
Multipart s -> [StrictByteString] -> [CipherText] -> m [CipherText]
go Multipart s
multipart [StrictByteString
lastMsg] [CipherText]
acc = do
CipherText
encryptedChunk <- Multipart s -> MessageTag -> StrictByteString -> m CipherText
forall (m :: * -> *) s.
MonadIO m =>
Multipart s -> MessageTag -> StrictByteString -> m CipherText
encryptChunk Multipart s
multipart MessageTag
Final StrictByteString
lastMsg
[CipherText] -> m [CipherText]
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([CipherText] -> m [CipherText]) -> [CipherText] -> m [CipherText]
forall a b. (a -> b) -> a -> b
$ [CipherText] -> [CipherText]
forall a. [a] -> [a]
List.reverse ([CipherText] -> [CipherText]) -> [CipherText] -> [CipherText]
forall a b. (a -> b) -> a -> b
$ CipherText
encryptedChunk CipherText -> [CipherText] -> [CipherText]
forall a. a -> [a] -> [a]
: [CipherText]
acc
go Multipart s
multipart (StrictByteString
msg : [StrictByteString]
rest) [CipherText]
acc = do
CipherText
encryptedChunk <- Multipart s -> MessageTag -> StrictByteString -> m CipherText
forall (m :: * -> *) s.
MonadIO m =>
Multipart s -> MessageTag -> StrictByteString -> m CipherText
encryptChunk Multipart s
multipart MessageTag
Message StrictByteString
msg
Multipart s -> [StrictByteString] -> [CipherText] -> m [CipherText]
forall s.
Multipart s -> [StrictByteString] -> [CipherText] -> m [CipherText]
go Multipart s
multipart [StrictByteString]
rest (CipherText
encryptedChunk CipherText -> [CipherText] -> [CipherText]
forall a. a -> [a] -> [a]
: [CipherText]
acc)
go Multipart s
_ [] [CipherText]
acc = [CipherText] -> m [CipherText]
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [CipherText]
acc
decryptStream
:: forall (a :: Type) (m :: Type -> Type)
. MonadIO m
=> SecretKey
-> Header
-> (forall s. Multipart s -> m a)
-> m (Maybe a)
decryptStream :: forall a (m :: * -> *).
MonadIO m =>
SecretKey
-> Header -> (forall s. Multipart s -> m a) -> m (Maybe a)
decryptStream (SecretKey ForeignPtr CUChar
secretKeyForeignPtr) (Header ForeignPtr CUChar
headerForeignPtr) forall s. Multipart s -> m a
actions = CSize
-> (Ptr CryptoSecretStreamXChaCha20Poly1305State -> m (Maybe a))
-> m (Maybe a)
forall a b (m :: * -> *).
MonadIO m =>
CSize -> (Ptr a -> m b) -> m b
allocateWith CSize
cryptoSecretStreamXChaCha20Poly1305StateBytes ((Ptr CryptoSecretStreamXChaCha20Poly1305State -> m (Maybe a))
-> m (Maybe a))
-> (Ptr CryptoSecretStreamXChaCha20Poly1305State -> m (Maybe a))
-> m (Maybe a)
forall a b. (a -> b) -> a -> b
$ \Ptr CryptoSecretStreamXChaCha20Poly1305State
statePtr -> do
CInt
result <- IO CInt -> m CInt
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO CInt -> m CInt) -> IO CInt -> m CInt
forall a b. (a -> b) -> a -> b
$ ForeignPtr CUChar -> (Ptr CUChar -> IO CInt) -> IO CInt
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
Foreign.withForeignPtr ForeignPtr CUChar
secretKeyForeignPtr ((Ptr CUChar -> IO CInt) -> IO CInt)
-> (Ptr CUChar -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
secretKeyPtr -> do
ForeignPtr CUChar -> (Ptr CUChar -> IO CInt) -> IO CInt
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
Foreign.withForeignPtr ForeignPtr CUChar
headerForeignPtr ((Ptr CUChar -> IO CInt) -> IO CInt)
-> (Ptr CUChar -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
headerPtr -> do
Ptr CryptoSecretStreamXChaCha20Poly1305State
-> Ptr CUChar -> Ptr CUChar -> IO CInt
cryptoSecretStreamXChaCha20Poly1305InitPull
Ptr CryptoSecretStreamXChaCha20Poly1305State
statePtr
Ptr CUChar
headerPtr
Ptr CUChar
secretKeyPtr
if CInt
result CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
/= CInt
0
then Maybe a -> m (Maybe a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing
else do
let part :: Multipart s
part = Ptr CryptoSecretStreamXChaCha20Poly1305State -> Multipart s
forall s.
Ptr CryptoSecretStreamXChaCha20Poly1305State -> Multipart s
Multipart Ptr CryptoSecretStreamXChaCha20Poly1305State
statePtr
a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> m a -> m (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Multipart Any -> m a
forall s. Multipart s -> m a
actions Multipart Any
forall {s}. Multipart s
part
decryptChunk
:: forall m s
. MonadIO m
=> Multipart s
-> CipherText
-> m StrictByteString
decryptChunk :: forall (m :: * -> *) s.
MonadIO m =>
Multipart s -> CipherText -> m StrictByteString
decryptChunk (Multipart Ptr CryptoSecretStreamXChaCha20Poly1305State
statePtr) CipherText{CULLong
messageLength :: CULLong
messageLength :: CipherText -> CULLong
messageLength, ForeignPtr CUChar
cipherTextForeignPtr :: ForeignPtr CUChar
cipherTextForeignPtr :: CipherText -> ForeignPtr CUChar
cipherTextForeignPtr} = do
ForeignPtr CUChar
clearTextForeignPtr <- IO (ForeignPtr CUChar) -> m (ForeignPtr CUChar)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (ForeignPtr CUChar) -> m (ForeignPtr CUChar))
-> IO (ForeignPtr CUChar) -> m (ForeignPtr CUChar)
forall a b. (a -> b) -> a -> b
$ Int -> IO (ForeignPtr CUChar)
forall a. Int -> IO (ForeignPtr a)
Foreign.mallocForeignPtrBytes (CULLong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CULLong
messageLength)
let cipherTextLen :: CULLong
cipherTextLen = CULLong
messageLength CULLong -> CULLong -> CULLong
forall a. Num a => a -> a -> a
+ CSize -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
cryptoSecretStreamXChaCha20Poly1305ABytes
IO StrictByteString -> m StrictByteString
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO StrictByteString -> m StrictByteString)
-> IO StrictByteString -> m StrictByteString
forall a b. (a -> b) -> a -> b
$ ForeignPtr CUChar
-> (Ptr CUChar -> IO StrictByteString) -> IO StrictByteString
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
Foreign.withForeignPtr ForeignPtr CUChar
cipherTextForeignPtr ((Ptr CUChar -> IO StrictByteString) -> IO StrictByteString)
-> (Ptr CUChar -> IO StrictByteString) -> IO StrictByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
cipherTextBuffer -> do
IO StrictByteString -> IO StrictByteString
forall a. IO a -> IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO StrictByteString -> IO StrictByteString)
-> IO StrictByteString -> IO StrictByteString
forall a b. (a -> b) -> a -> b
$ ForeignPtr CUChar
-> (Ptr CUChar -> IO StrictByteString) -> IO StrictByteString
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
Foreign.withForeignPtr ForeignPtr CUChar
clearTextForeignPtr ((Ptr CUChar -> IO StrictByteString) -> IO StrictByteString)
-> (Ptr CUChar -> IO StrictByteString) -> IO StrictByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
clearTextBuffer -> do
Ptr CUChar
tagBuffer <- CSize -> IO (Ptr CUChar)
forall a. CSize -> IO (Ptr a)
sodiumMalloc CSize
1
CInt
result <-
Ptr CryptoSecretStreamXChaCha20Poly1305State
-> Ptr CUChar
-> Ptr CULLong
-> Ptr CUChar
-> Ptr CUChar
-> CULLong
-> Ptr CUChar
-> CULLong
-> IO CInt
cryptoSecretStreamXChaCha20Poly1305Pull
Ptr CryptoSecretStreamXChaCha20Poly1305State
statePtr
Ptr CUChar
clearTextBuffer
Ptr CULLong
forall a. Ptr a
Foreign.nullPtr
Ptr CUChar
tagBuffer
Ptr CUChar
cipherTextBuffer
CULLong
cipherTextLen
Ptr CUChar
forall a. Ptr a
Foreign.nullPtr
CULLong
0
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (CInt
result CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
/= CInt
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ StreamDecryptionException -> IO ()
forall a e. Exception e => e -> a
throw StreamDecryptionException
StreamDecryptionException
Ptr CChar
bsPtr <- Int -> IO (Ptr CChar)
forall a. Int -> IO (Ptr a)
Foreign.mallocBytes (CULLong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CULLong
messageLength)
Ptr CChar -> Ptr CChar -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
Foreign.copyBytes Ptr CChar
bsPtr (Ptr CUChar -> Ptr CChar
forall a b. Ptr a -> Ptr b
Foreign.castPtr Ptr CUChar
clearTextBuffer) (CULLong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CULLong
messageLength)
CStringLen -> IO StrictByteString
BSU.unsafePackMallocCStringLen (Ptr CChar
bsPtr, CULLong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CULLong
messageLength)
decryptList :: forall m. MonadIO m => SecretKey -> Header -> [CipherText] -> m (Maybe [StrictByteString])
decryptList :: forall (m :: * -> *).
MonadIO m =>
SecretKey -> Header -> [CipherText] -> m (Maybe [StrictByteString])
decryptList SecretKey
secretKey Header
header [CipherText]
encryptedMessages =
SecretKey
-> Header
-> (forall {s}. Multipart s -> m [StrictByteString])
-> m (Maybe [StrictByteString])
forall a (m :: * -> *).
MonadIO m =>
SecretKey
-> Header -> (forall s. Multipart s -> m a) -> m (Maybe a)
decryptStream SecretKey
secretKey Header
header ((forall {s}. Multipart s -> m [StrictByteString])
-> m (Maybe [StrictByteString]))
-> (forall {s}. Multipart s -> m [StrictByteString])
-> m (Maybe [StrictByteString])
forall a b. (a -> b) -> a -> b
$ \Multipart s
multipart -> do
[CipherText]
-> (CipherText -> m StrictByteString) -> m [StrictByteString]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [CipherText]
encryptedMessages ((CipherText -> m StrictByteString) -> m [StrictByteString])
-> (CipherText -> m StrictByteString) -> m [StrictByteString]
forall a b. (a -> b) -> a -> b
$ \CipherText
cipherText -> do
Multipart s -> CipherText -> m StrictByteString
forall (m :: * -> *) s.
MonadIO m =>
Multipart s -> CipherText -> m StrictByteString
decryptChunk Multipart s
multipart CipherText
cipherText
newtype SecretKey = SecretKey (ForeignPtr CUChar)
deriving
( Int -> SecretKey -> Builder
[SecretKey] -> Builder
SecretKey -> Builder
(SecretKey -> Builder)
-> ([SecretKey] -> Builder)
-> (Int -> SecretKey -> Builder)
-> Display SecretKey
forall a.
(a -> Builder)
-> ([a] -> Builder) -> (Int -> a -> Builder) -> Display a
$cdisplayBuilder :: SecretKey -> Builder
displayBuilder :: SecretKey -> Builder
$cdisplayList :: [SecretKey] -> Builder
displayList :: [SecretKey] -> Builder
$cdisplayPrec :: Int -> SecretKey -> Builder
displayPrec :: Int -> SecretKey -> Builder
Display
)
via (OpaqueInstance "[REDACTED]" SecretKey)
instance Eq SecretKey where
(SecretKey ForeignPtr CUChar
hk1) == :: SecretKey -> SecretKey -> Bool
== (SecretKey ForeignPtr CUChar
hk2) =
IO Bool -> Bool
forall a. IO a -> a
unsafeDupablePerformIO (IO Bool -> Bool) -> IO Bool -> Bool
forall a b. (a -> b) -> a -> b
$
ForeignPtr CUChar -> ForeignPtr CUChar -> CSize -> IO Bool
forall a. ForeignPtr a -> ForeignPtr a -> CSize -> IO Bool
foreignPtrEq ForeignPtr CUChar
hk1 ForeignPtr CUChar
hk2 CSize
cryptoSecretStreamXChaCha20Poly1305KeyBytes
instance Ord SecretKey where
compare :: SecretKey -> SecretKey -> Ordering
compare (SecretKey ForeignPtr CUChar
hk1) (SecretKey ForeignPtr CUChar
hk2) =
IO Ordering -> Ordering
forall a. IO a -> a
unsafeDupablePerformIO (IO Ordering -> Ordering) -> IO Ordering -> Ordering
forall a b. (a -> b) -> a -> b
$
ForeignPtr CUChar -> ForeignPtr CUChar -> CSize -> IO Ordering
forall a. ForeignPtr a -> ForeignPtr a -> CSize -> IO Ordering
foreignPtrOrd ForeignPtr CUChar
hk1 ForeignPtr CUChar
hk2 CSize
cryptoSecretStreamXChaCha20Poly1305KeyBytes
instance Show SecretKey where
show :: SecretKey -> String
show SecretKey
_ = String
"[REDACTED]"
newSecretKey :: IO SecretKey
newSecretKey :: IO SecretKey
newSecretKey = (Ptr CUChar -> IO ()) -> IO SecretKey
newSecretKeyWith Ptr CUChar -> IO ()
cryptoSecretStreamXChaCha20Poly1305KeyGen
secretKeyFromHexByteString :: Base16 StrictByteString -> Either Text SecretKey
secretKeyFromHexByteString :: Base16 StrictByteString -> Either Text SecretKey
secretKeyFromHexByteString Base16 StrictByteString
hexSecretKey = IO (Either Text SecretKey) -> Either Text SecretKey
forall a. IO a -> a
unsafeDupablePerformIO (IO (Either Text SecretKey) -> Either Text SecretKey)
-> IO (Either Text SecretKey) -> Either Text SecretKey
forall a b. (a -> b) -> a -> b
$
case StrictByteString -> Either Text StrictByteString
Base16.decodeBase16Untyped (Base16 StrictByteString -> StrictByteString
forall a. Base16 a -> a
Base16.extractBase16 Base16 StrictByteString
hexSecretKey) of
Right StrictByteString
bytestring ->
if StrictByteString -> Int
BS.length StrictByteString
bytestring Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
cryptoSecretStreamXChaCha20Poly1305KeyBytes
then StrictByteString
-> (CStringLen -> IO (Either Text SecretKey))
-> IO (Either Text SecretKey)
forall a. StrictByteString -> (CStringLen -> IO a) -> IO a
BSU.unsafeUseAsCStringLen StrictByteString
bytestring ((CStringLen -> IO (Either Text SecretKey))
-> IO (Either Text SecretKey))
-> (CStringLen -> IO (Either Text SecretKey))
-> IO (Either Text SecretKey)
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
outsideSecretKeyPtr, Int
_) -> do
SecretKey
secretKey <- (Ptr CUChar -> IO ()) -> IO SecretKey
newSecretKeyWith ((Ptr CUChar -> IO ()) -> IO SecretKey)
-> (Ptr CUChar -> IO ()) -> IO SecretKey
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
secretKeyPtr ->
Ptr CChar -> Ptr CChar -> Int -> IO ()
forall a. Storable a => Ptr a -> Ptr a -> Int -> IO ()
Foreign.copyArray
(forall a b. Ptr a -> Ptr b
Foreign.castPtr @CUChar @CChar Ptr CUChar
secretKeyPtr)
Ptr CChar
outsideSecretKeyPtr
(CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
cryptoSecretStreamXChaCha20Poly1305KeyBytes)
Either Text SecretKey -> IO (Either Text SecretKey)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either Text SecretKey -> IO (Either Text SecretKey))
-> Either Text SecretKey -> IO (Either Text SecretKey)
forall a b. (a -> b) -> a -> b
$ SecretKey -> Either Text SecretKey
forall a b. b -> Either a b
Right SecretKey
secretKey
else Either Text SecretKey -> IO (Either Text SecretKey)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either Text SecretKey -> IO (Either Text SecretKey))
-> Either Text SecretKey -> IO (Either Text SecretKey)
forall a b. (a -> b) -> a -> b
$ Text -> Either Text SecretKey
forall a b. a -> Either a b
Left (Text -> Either Text SecretKey) -> Text -> Either Text SecretKey
forall a b. (a -> b) -> a -> b
$ String -> Text
Text.pack (String
"Secret Key is not of size " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> CSize -> String
forall a. Show a => a -> String
show CSize
cryptoSecretStreamXChaCha20Poly1305KeyBytes)
Left Text
msg -> Either Text SecretKey -> IO (Either Text SecretKey)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either Text SecretKey -> IO (Either Text SecretKey))
-> Either Text SecretKey -> IO (Either Text SecretKey)
forall a b. (a -> b) -> a -> b
$ Text -> Either Text SecretKey
forall a b. a -> Either a b
Left Text
msg
unsafeSecretKeyToHexByteString :: SecretKey -> Base16 StrictByteString
unsafeSecretKeyToHexByteString :: SecretKey -> Base16 StrictByteString
unsafeSecretKeyToHexByteString (SecretKey ForeignPtr CUChar
secretKeyForeignPtr) =
StrictByteString -> Base16 StrictByteString
Base16.encodeBase16' (StrictByteString -> Base16 StrictByteString)
-> StrictByteString -> Base16 StrictByteString
forall a b. (a -> b) -> a -> b
$
ForeignPtr Word8 -> Int -> StrictByteString
BSI.fromForeignPtr0
(forall a b. ForeignPtr a -> ForeignPtr b
Foreign.castForeignPtr @CUChar @Word8 ForeignPtr CUChar
secretKeyForeignPtr)
(forall a b. (Integral a, Num b) => a -> b
fromIntegral @CSize @Int CSize
cryptoSecretStreamXChaCha20Poly1305KeyBytes)
newSecretKeyWith :: (Ptr CUChar -> IO ()) -> IO SecretKey
newSecretKeyWith :: (Ptr CUChar -> IO ()) -> IO SecretKey
newSecretKeyWith Ptr CUChar -> IO ()
action = do
Ptr CUChar
ptr <- CSize -> IO (Ptr CUChar)
forall a. CSize -> IO (Ptr a)
sodiumMalloc CSize
cryptoSecretStreamXChaCha20Poly1305KeyBytes
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Ptr CUChar
ptr Ptr CUChar -> Ptr CUChar -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr CUChar
forall a. Ptr a
Foreign.nullPtr) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
forall a. String -> IO a
throwErrno String
"sodium_malloc"
ForeignPtr CUChar
fPtr <- FinalizerPtr CUChar -> Ptr CUChar -> IO (ForeignPtr CUChar)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
Foreign.newForeignPtr FinalizerPtr CUChar
forall a. FinalizerPtr a
finalizerSodiumFree Ptr CUChar
ptr
Ptr CUChar -> IO ()
action Ptr CUChar
ptr
SecretKey -> IO SecretKey
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SecretKey -> IO SecretKey) -> SecretKey -> IO SecretKey
forall a b. (a -> b) -> a -> b
$ ForeignPtr CUChar -> SecretKey
SecretKey ForeignPtr CUChar
fPtr
newtype = (ForeignPtr CUChar)
instance Show Header where
show :: Header -> String
show = StrictByteString -> String
BSI.unpackChars (StrictByteString -> String)
-> (Header -> StrictByteString) -> Header -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base16 StrictByteString -> StrictByteString
forall a. Base16 a -> a
Base16.extractBase16 (Base16 StrictByteString -> StrictByteString)
-> (Header -> Base16 StrictByteString)
-> Header
-> StrictByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Header -> Base16 StrictByteString
headerToHexByteString
instance Display Header where
displayBuilder :: Header -> Builder
displayBuilder = Text -> Builder
Builder.fromText (Text -> Builder) -> (Header -> Text) -> Header -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base16 Text -> Text
forall a. Base16 a -> a
Base16.extractBase16 (Base16 Text -> Text) -> (Header -> Base16 Text) -> Header -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Header -> Base16 Text
headerToHexText
instance Eq Header where
(Header ForeignPtr CUChar
header1) == :: Header -> Header -> Bool
== (Header ForeignPtr CUChar
header2) =
IO Bool -> Bool
forall a. IO a -> a
unsafeDupablePerformIO (IO Bool -> Bool) -> IO Bool -> Bool
forall a b. (a -> b) -> a -> b
$
ForeignPtr CUChar -> ForeignPtr CUChar -> CSize -> IO Bool
forall a. ForeignPtr a -> ForeignPtr a -> CSize -> IO Bool
foreignPtrEq ForeignPtr CUChar
header1 ForeignPtr CUChar
header2 CSize
cryptoSecretStreamXChaCha20Poly1305HeaderBytes
instance Ord Header where
compare :: Header -> Header -> Ordering
compare (Header ForeignPtr CUChar
header1) (Header ForeignPtr CUChar
header2) =
IO Ordering -> Ordering
forall a. IO a -> a
unsafeDupablePerformIO (IO Ordering -> Ordering) -> IO Ordering -> Ordering
forall a b. (a -> b) -> a -> b
$
ForeignPtr CUChar -> ForeignPtr CUChar -> CSize -> IO Ordering
forall a. ForeignPtr a -> ForeignPtr a -> CSize -> IO Ordering
foreignPtrOrd ForeignPtr CUChar
header1 ForeignPtr CUChar
header2 CSize
cryptoSecretStreamXChaCha20Poly1305HeaderBytes
headerToHexByteString :: Header -> Base16 StrictByteString
(Header ForeignPtr CUChar
headerForeignPtr) =
StrictByteString -> Base16 StrictByteString
Base16.encodeBase16' (StrictByteString -> Base16 StrictByteString)
-> StrictByteString -> Base16 StrictByteString
forall a b. (a -> b) -> a -> b
$
ForeignPtr Word8 -> Int -> StrictByteString
BSI.fromForeignPtr0
(forall a b. ForeignPtr a -> ForeignPtr b
Foreign.castForeignPtr @CUChar @Word8 ForeignPtr CUChar
headerForeignPtr)
(forall a b. (Integral a, Num b) => a -> b
fromIntegral @CSize @Int CSize
cryptoSecretStreamXChaCha20Poly1305HeaderBytes)
headerFromHexByteString :: Base16 StrictByteString -> Either Text Header
Base16 StrictByteString
hexHeader = IO (Either Text Header) -> Either Text Header
forall a. IO a -> a
unsafeDupablePerformIO (IO (Either Text Header) -> Either Text Header)
-> IO (Either Text Header) -> Either Text Header
forall a b. (a -> b) -> a -> b
$
case StrictByteString -> Either Text StrictByteString
Base16.decodeBase16Untyped (Base16 StrictByteString -> StrictByteString
forall a. Base16 a -> a
Base16.extractBase16 Base16 StrictByteString
hexHeader) of
Right StrictByteString
bytestring ->
if StrictByteString -> Int
BS.length StrictByteString
bytestring Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
cryptoSecretStreamXChaCha20Poly1305HeaderBytes
then StrictByteString
-> (CStringLen -> IO (Either Text Header))
-> IO (Either Text Header)
forall a. StrictByteString -> (CStringLen -> IO a) -> IO a
BSU.unsafeUseAsCStringLen StrictByteString
bytestring ((CStringLen -> IO (Either Text Header))
-> IO (Either Text Header))
-> (CStringLen -> IO (Either Text Header))
-> IO (Either Text Header)
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
outsideHeaderPtr, Int
_) -> do
let headerLength :: Int
headerLength = CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
cryptoSecretStreamXChaCha20Poly1305HeaderBytes
ForeignPtr CUChar
headerForeignPtr <- Int -> IO (ForeignPtr CUChar)
forall a. Int -> IO (ForeignPtr a)
Foreign.mallocForeignPtrBytes (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
cryptoSecretStreamXChaCha20Poly1305HeaderBytes)
ForeignPtr CUChar
-> (Ptr CUChar -> IO (Either Text Header))
-> IO (Either Text Header)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
Foreign.withForeignPtr ForeignPtr CUChar
headerForeignPtr ((Ptr CUChar -> IO (Either Text Header))
-> IO (Either Text Header))
-> (Ptr CUChar -> IO (Either Text Header))
-> IO (Either Text Header)
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
headerPtr -> do
Ptr CUChar -> Ptr CUChar -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
Foreign.copyBytes Ptr CUChar
headerPtr (Ptr CChar -> Ptr CUChar
forall a b. Ptr a -> Ptr b
Foreign.castPtr Ptr CChar
outsideHeaderPtr) Int
headerLength
Either Text Header -> IO (Either Text Header)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either Text Header -> IO (Either Text Header))
-> Either Text Header -> IO (Either Text Header)
forall a b. (a -> b) -> a -> b
$ Header -> Either Text Header
forall a b. b -> Either a b
Right (Header -> Either Text Header) -> Header -> Either Text Header
forall a b. (a -> b) -> a -> b
$ ForeignPtr CUChar -> Header
Header ForeignPtr CUChar
headerForeignPtr
else Either Text Header -> IO (Either Text Header)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either Text Header -> IO (Either Text Header))
-> Either Text Header -> IO (Either Text Header)
forall a b. (a -> b) -> a -> b
$ Text -> Either Text Header
forall a b. a -> Either a b
Left (Text -> Either Text Header) -> Text -> Either Text Header
forall a b. (a -> b) -> a -> b
$ String -> Text
Text.pack (String
"Secret Key is not of size " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> CSize -> String
forall a. Show a => a -> String
show CSize
cryptoSecretStreamXChaCha20Poly1305HeaderBytes)
Left Text
msg -> Either Text Header -> IO (Either Text Header)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either Text Header -> IO (Either Text Header))
-> Either Text Header -> IO (Either Text Header)
forall a b. (a -> b) -> a -> b
$ Text -> Either Text Header
forall a b. a -> Either a b
Left Text
msg
headerToHexText :: Header -> Base16 Text
= StrictByteString -> Base16 Text
Base16.encodeBase16 (StrictByteString -> Base16 Text)
-> (Header -> StrictByteString) -> Header -> Base16 Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base16 StrictByteString -> StrictByteString
forall a. Base16 a -> a
Base16.extractBase16 (Base16 StrictByteString -> StrictByteString)
-> (Header -> Base16 StrictByteString)
-> Header
-> StrictByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Header -> Base16 StrictByteString
headerToHexByteString
data MessageTag
=
Message
|
Final
|
Push
|
Rekey
messageTagToConstant :: MessageTag -> CUChar
messageTagToConstant :: MessageTag -> CUChar
messageTagToConstant = \case
MessageTag
Message -> CSize -> CUChar
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
cryptoSecretStreamXChaCha20Poly1305TagMessage
MessageTag
Final -> CSize -> CUChar
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
cryptoSecretStreamXChaCha20Poly1305TagFinal
MessageTag
Push -> CSize -> CUChar
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
cryptoSecretStreamXChaCha20Poly1305TagPush
MessageTag
Rekey -> CSize -> CUChar
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
cryptoSecretStreamXChaCha20Poly1305TagRekey
data CipherText = CipherText
{ CipherText -> CULLong
messageLength :: CULLong
, CipherText -> ForeignPtr CUChar
cipherTextForeignPtr :: ForeignPtr CUChar
}
instance Eq CipherText where
(CipherText CULLong
cipherTextLength1 ForeignPtr CUChar
h1) == :: CipherText -> CipherText -> Bool
== (CipherText CULLong
cipherTextLength2 ForeignPtr CUChar
h2) =
IO Bool -> Bool
forall a. IO a -> a
unsafeDupablePerformIO (IO Bool -> Bool) -> IO Bool -> Bool
forall a b. (a -> b) -> a -> b
$ do
Bool
result1 <-
ForeignPtr CUChar -> ForeignPtr CUChar -> CSize -> IO Bool
forall a. ForeignPtr a -> ForeignPtr a -> CSize -> IO Bool
foreignPtrEq
ForeignPtr CUChar
h1
ForeignPtr CUChar
h2
(CULLong -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral CULLong
cipherTextLength1 CSize -> CSize -> CSize
forall a. Num a => a -> a -> a
+ CSize
cryptoSecretStreamXChaCha20Poly1305ABytes)
Bool -> IO Bool
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> IO Bool) -> Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ CULLong
cipherTextLength1 CULLong -> CULLong -> Bool
forall a. Eq a => a -> a -> Bool
== CULLong
cipherTextLength2 Bool -> Bool -> Bool
&& Bool
result1
instance Ord CipherText where
compare :: CipherText -> CipherText -> Ordering
compare (CipherText CULLong
cipherTextLength1 ForeignPtr CUChar
c1) (CipherText CULLong
cipherTextLength2 ForeignPtr CUChar
c2) =
IO Ordering -> Ordering
forall a. IO a -> a
unsafeDupablePerformIO (IO Ordering -> Ordering) -> IO Ordering -> Ordering
forall a b. (a -> b) -> a -> b
$ do
Ordering
result1 <- ForeignPtr CUChar -> ForeignPtr CUChar -> CSize -> IO Ordering
forall a. ForeignPtr a -> ForeignPtr a -> CSize -> IO Ordering
foreignPtrOrd ForeignPtr CUChar
c1 ForeignPtr CUChar
c2 (CULLong -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral CULLong
cipherTextLength1 CSize -> CSize -> CSize
forall a. Num a => a -> a -> a
+ CSize
cryptoSecretStreamXChaCha20Poly1305ABytes)
Ordering -> IO Ordering
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ordering -> IO Ordering) -> Ordering -> IO Ordering
forall a b. (a -> b) -> a -> b
$ CULLong -> CULLong -> Ordering
forall a. Ord a => a -> a -> Ordering
compare CULLong
cipherTextLength1 CULLong
cipherTextLength2 Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> Ordering
result1
instance Display CipherText where
displayBuilder :: CipherText -> Builder
displayBuilder = Text -> Builder
Builder.fromText (Text -> Builder) -> (CipherText -> Text) -> CipherText -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base16 Text -> Text
forall a. Base16 a -> a
Base16.extractBase16 (Base16 Text -> Text)
-> (CipherText -> Base16 Text) -> CipherText -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CipherText -> Base16 Text
ciphertextToHexText
instance Show CipherText where
show :: CipherText -> String
show = StrictByteString -> String
BSI.unpackChars (StrictByteString -> String)
-> (CipherText -> StrictByteString) -> CipherText -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base16 StrictByteString -> StrictByteString
forall a. Base16 a -> a
Base16.extractBase16 (Base16 StrictByteString -> StrictByteString)
-> (CipherText -> Base16 StrictByteString)
-> CipherText
-> StrictByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CipherText -> Base16 StrictByteString
ciphertextToHexByteString
ciphertextFromHexByteString :: Base16 StrictByteString -> Either Text CipherText
ciphertextFromHexByteString :: Base16 StrictByteString -> Either Text CipherText
ciphertextFromHexByteString Base16 StrictByteString
hexCipherText = IO (Either Text CipherText) -> Either Text CipherText
forall a. IO a -> a
unsafeDupablePerformIO (IO (Either Text CipherText) -> Either Text CipherText)
-> IO (Either Text CipherText) -> Either Text CipherText
forall a b. (a -> b) -> a -> b
$
case StrictByteString -> Either Text StrictByteString
Base16.decodeBase16Untyped (Base16 StrictByteString -> StrictByteString
forall a. Base16 a -> a
Base16.extractBase16 Base16 StrictByteString
hexCipherText) of
Right StrictByteString
bytestring ->
if StrictByteString -> Int
BS.length StrictByteString
bytestring Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
cryptoSecretStreamXChaCha20Poly1305ABytes
then StrictByteString
-> (CStringLen -> IO (Either Text CipherText))
-> IO (Either Text CipherText)
forall a. StrictByteString -> (CStringLen -> IO a) -> IO a
BSU.unsafeUseAsCStringLen StrictByteString
bytestring ((CStringLen -> IO (Either Text CipherText))
-> IO (Either Text CipherText))
-> (CStringLen -> IO (Either Text CipherText))
-> IO (Either Text CipherText)
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
outsideCipherTextPtr, Int
outsideCipherTextLength) -> do
ForeignPtr CChar
cipherTextFPtr <- forall a. Int -> IO (ForeignPtr a)
BSI.mallocByteString @CChar Int
outsideCipherTextLength
ForeignPtr CChar -> (Ptr CChar -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
Foreign.withForeignPtr ForeignPtr CChar
cipherTextFPtr ((Ptr CChar -> IO ()) -> IO ()) -> (Ptr CChar -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
cipherTextPtr ->
Ptr CChar -> Ptr CChar -> Int -> IO ()
forall a. Storable a => Ptr a -> Ptr a -> Int -> IO ()
Foreign.copyArray Ptr CChar
cipherTextPtr Ptr CChar
outsideCipherTextPtr Int
outsideCipherTextLength
Either Text CipherText -> IO (Either Text CipherText)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either Text CipherText -> IO (Either Text CipherText))
-> Either Text CipherText -> IO (Either Text CipherText)
forall a b. (a -> b) -> a -> b
$
CipherText -> Either Text CipherText
forall a b. b -> Either a b
Right (CipherText -> Either Text CipherText)
-> CipherText -> Either Text CipherText
forall a b. (a -> b) -> a -> b
$
CULLong -> ForeignPtr CUChar -> CipherText
CipherText
(forall a b. (Integral a, Num b) => a -> b
fromIntegral @Int @CULLong Int
outsideCipherTextLength CULLong -> CULLong -> CULLong
forall a. Num a => a -> a -> a
- forall a b. (Integral a, Num b) => a -> b
fromIntegral @CSize @CULLong CSize
cryptoSecretStreamXChaCha20Poly1305ABytes)
(forall a b. ForeignPtr a -> ForeignPtr b
Foreign.castForeignPtr @CChar @CUChar ForeignPtr CChar
cipherTextFPtr)
else Either Text CipherText -> IO (Either Text CipherText)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either Text CipherText -> IO (Either Text CipherText))
-> Either Text CipherText -> IO (Either Text CipherText)
forall a b. (a -> b) -> a -> b
$ Text -> Either Text CipherText
forall a b. a -> Either a b
Left (Text -> Either Text CipherText) -> Text -> Either Text CipherText
forall a b. (a -> b) -> a -> b
$ String -> Text
Text.pack String
"CipherText is too short"
Left Text
msg -> Either Text CipherText -> IO (Either Text CipherText)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either Text CipherText -> IO (Either Text CipherText))
-> Either Text CipherText -> IO (Either Text CipherText)
forall a b. (a -> b) -> a -> b
$ Text -> Either Text CipherText
forall a b. a -> Either a b
Left Text
msg
ciphertextToHexText :: CipherText -> Base16 Text
ciphertextToHexText :: CipherText -> Base16 Text
ciphertextToHexText = StrictByteString -> Base16 Text
Base16.encodeBase16 (StrictByteString -> Base16 Text)
-> (CipherText -> StrictByteString) -> CipherText -> Base16 Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CipherText -> StrictByteString
ciphertextToBinary
ciphertextToHexByteString :: CipherText -> Base16 StrictByteString
ciphertextToHexByteString :: CipherText -> Base16 StrictByteString
ciphertextToHexByteString = StrictByteString -> Base16 StrictByteString
Base16.encodeBase16' (StrictByteString -> Base16 StrictByteString)
-> (CipherText -> StrictByteString)
-> CipherText
-> Base16 StrictByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CipherText -> StrictByteString
ciphertextToBinary
ciphertextToBinary :: CipherText -> StrictByteString
ciphertextToBinary :: CipherText -> StrictByteString
ciphertextToBinary (CipherText CULLong
cipherTextLength ForeignPtr CUChar
fPtr) =
ForeignPtr Word8 -> Int -> StrictByteString
BSI.fromForeignPtr0
(ForeignPtr CUChar -> ForeignPtr Word8
forall a b. ForeignPtr a -> ForeignPtr b
Foreign.castForeignPtr ForeignPtr CUChar
fPtr)
(CULLong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CULLong
cipherTextLength Int -> Int -> Int
forall a. Num a => a -> a -> a
+ CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
cryptoSecretStreamXChaCha20Poly1305ABytes)
data StreamEncryptionException = StreamEncryptionException
deriving stock (StreamEncryptionException -> StreamEncryptionException -> Bool
(StreamEncryptionException -> StreamEncryptionException -> Bool)
-> (StreamEncryptionException -> StreamEncryptionException -> Bool)
-> Eq StreamEncryptionException
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StreamEncryptionException -> StreamEncryptionException -> Bool
== :: StreamEncryptionException -> StreamEncryptionException -> Bool
$c/= :: StreamEncryptionException -> StreamEncryptionException -> Bool
/= :: StreamEncryptionException -> StreamEncryptionException -> Bool
Eq, Eq StreamEncryptionException
Eq StreamEncryptionException =>
(StreamEncryptionException
-> StreamEncryptionException -> Ordering)
-> (StreamEncryptionException -> StreamEncryptionException -> Bool)
-> (StreamEncryptionException -> StreamEncryptionException -> Bool)
-> (StreamEncryptionException -> StreamEncryptionException -> Bool)
-> (StreamEncryptionException -> StreamEncryptionException -> Bool)
-> (StreamEncryptionException
-> StreamEncryptionException -> StreamEncryptionException)
-> (StreamEncryptionException
-> StreamEncryptionException -> StreamEncryptionException)
-> Ord StreamEncryptionException
StreamEncryptionException -> StreamEncryptionException -> Bool
StreamEncryptionException -> StreamEncryptionException -> Ordering
StreamEncryptionException
-> StreamEncryptionException -> StreamEncryptionException
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: StreamEncryptionException -> StreamEncryptionException -> Ordering
compare :: StreamEncryptionException -> StreamEncryptionException -> Ordering
$c< :: StreamEncryptionException -> StreamEncryptionException -> Bool
< :: StreamEncryptionException -> StreamEncryptionException -> Bool
$c<= :: StreamEncryptionException -> StreamEncryptionException -> Bool
<= :: StreamEncryptionException -> StreamEncryptionException -> Bool
$c> :: StreamEncryptionException -> StreamEncryptionException -> Bool
> :: StreamEncryptionException -> StreamEncryptionException -> Bool
$c>= :: StreamEncryptionException -> StreamEncryptionException -> Bool
>= :: StreamEncryptionException -> StreamEncryptionException -> Bool
$cmax :: StreamEncryptionException
-> StreamEncryptionException -> StreamEncryptionException
max :: StreamEncryptionException
-> StreamEncryptionException -> StreamEncryptionException
$cmin :: StreamEncryptionException
-> StreamEncryptionException -> StreamEncryptionException
min :: StreamEncryptionException
-> StreamEncryptionException -> StreamEncryptionException
Ord, Int -> StreamEncryptionException -> ShowS
[StreamEncryptionException] -> ShowS
StreamEncryptionException -> String
(Int -> StreamEncryptionException -> ShowS)
-> (StreamEncryptionException -> String)
-> ([StreamEncryptionException] -> ShowS)
-> Show StreamEncryptionException
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> StreamEncryptionException -> ShowS
showsPrec :: Int -> StreamEncryptionException -> ShowS
$cshow :: StreamEncryptionException -> String
show :: StreamEncryptionException -> String
$cshowList :: [StreamEncryptionException] -> ShowS
showList :: [StreamEncryptionException] -> ShowS
Show)
deriving anyclass (Show StreamEncryptionException
Typeable StreamEncryptionException
(Typeable StreamEncryptionException,
Show StreamEncryptionException) =>
(StreamEncryptionException -> SomeException)
-> (SomeException -> Maybe StreamEncryptionException)
-> (StreamEncryptionException -> String)
-> Exception StreamEncryptionException
SomeException -> Maybe StreamEncryptionException
StreamEncryptionException -> String
StreamEncryptionException -> SomeException
forall e.
(Typeable e, Show e) =>
(e -> SomeException)
-> (SomeException -> Maybe e) -> (e -> String) -> Exception e
$ctoException :: StreamEncryptionException -> SomeException
toException :: StreamEncryptionException -> SomeException
$cfromException :: SomeException -> Maybe StreamEncryptionException
fromException :: SomeException -> Maybe StreamEncryptionException
$cdisplayException :: StreamEncryptionException -> String
displayException :: StreamEncryptionException -> String
Exception)
data StreamInitEncryptionException = StreamInitEncryptionException
deriving stock (StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool
(StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool)
-> (StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool)
-> Eq StreamInitEncryptionException
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool
== :: StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool
$c/= :: StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool
/= :: StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool
Eq, Eq StreamInitEncryptionException
Eq StreamInitEncryptionException =>
(StreamInitEncryptionException
-> StreamInitEncryptionException -> Ordering)
-> (StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool)
-> (StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool)
-> (StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool)
-> (StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool)
-> (StreamInitEncryptionException
-> StreamInitEncryptionException -> StreamInitEncryptionException)
-> (StreamInitEncryptionException
-> StreamInitEncryptionException -> StreamInitEncryptionException)
-> Ord StreamInitEncryptionException
StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool
StreamInitEncryptionException
-> StreamInitEncryptionException -> Ordering
StreamInitEncryptionException
-> StreamInitEncryptionException -> StreamInitEncryptionException
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: StreamInitEncryptionException
-> StreamInitEncryptionException -> Ordering
compare :: StreamInitEncryptionException
-> StreamInitEncryptionException -> Ordering
$c< :: StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool
< :: StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool
$c<= :: StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool
<= :: StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool
$c> :: StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool
> :: StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool
$c>= :: StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool
>= :: StreamInitEncryptionException
-> StreamInitEncryptionException -> Bool
$cmax :: StreamInitEncryptionException
-> StreamInitEncryptionException -> StreamInitEncryptionException
max :: StreamInitEncryptionException
-> StreamInitEncryptionException -> StreamInitEncryptionException
$cmin :: StreamInitEncryptionException
-> StreamInitEncryptionException -> StreamInitEncryptionException
min :: StreamInitEncryptionException
-> StreamInitEncryptionException -> StreamInitEncryptionException
Ord, Int -> StreamInitEncryptionException -> ShowS
[StreamInitEncryptionException] -> ShowS
StreamInitEncryptionException -> String
(Int -> StreamInitEncryptionException -> ShowS)
-> (StreamInitEncryptionException -> String)
-> ([StreamInitEncryptionException] -> ShowS)
-> Show StreamInitEncryptionException
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> StreamInitEncryptionException -> ShowS
showsPrec :: Int -> StreamInitEncryptionException -> ShowS
$cshow :: StreamInitEncryptionException -> String
show :: StreamInitEncryptionException -> String
$cshowList :: [StreamInitEncryptionException] -> ShowS
showList :: [StreamInitEncryptionException] -> ShowS
Show)
deriving anyclass (Show StreamInitEncryptionException
Typeable StreamInitEncryptionException
(Typeable StreamInitEncryptionException,
Show StreamInitEncryptionException) =>
(StreamInitEncryptionException -> SomeException)
-> (SomeException -> Maybe StreamInitEncryptionException)
-> (StreamInitEncryptionException -> String)
-> Exception StreamInitEncryptionException
SomeException -> Maybe StreamInitEncryptionException
StreamInitEncryptionException -> String
StreamInitEncryptionException -> SomeException
forall e.
(Typeable e, Show e) =>
(e -> SomeException)
-> (SomeException -> Maybe e) -> (e -> String) -> Exception e
$ctoException :: StreamInitEncryptionException -> SomeException
toException :: StreamInitEncryptionException -> SomeException
$cfromException :: SomeException -> Maybe StreamInitEncryptionException
fromException :: SomeException -> Maybe StreamInitEncryptionException
$cdisplayException :: StreamInitEncryptionException -> String
displayException :: StreamInitEncryptionException -> String
Exception)
data StreamDecryptionException = StreamDecryptionException
deriving stock (StreamDecryptionException -> StreamDecryptionException -> Bool
(StreamDecryptionException -> StreamDecryptionException -> Bool)
-> (StreamDecryptionException -> StreamDecryptionException -> Bool)
-> Eq StreamDecryptionException
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StreamDecryptionException -> StreamDecryptionException -> Bool
== :: StreamDecryptionException -> StreamDecryptionException -> Bool
$c/= :: StreamDecryptionException -> StreamDecryptionException -> Bool
/= :: StreamDecryptionException -> StreamDecryptionException -> Bool
Eq, Eq StreamDecryptionException
Eq StreamDecryptionException =>
(StreamDecryptionException
-> StreamDecryptionException -> Ordering)
-> (StreamDecryptionException -> StreamDecryptionException -> Bool)
-> (StreamDecryptionException -> StreamDecryptionException -> Bool)
-> (StreamDecryptionException -> StreamDecryptionException -> Bool)
-> (StreamDecryptionException -> StreamDecryptionException -> Bool)
-> (StreamDecryptionException
-> StreamDecryptionException -> StreamDecryptionException)
-> (StreamDecryptionException
-> StreamDecryptionException -> StreamDecryptionException)
-> Ord StreamDecryptionException
StreamDecryptionException -> StreamDecryptionException -> Bool
StreamDecryptionException -> StreamDecryptionException -> Ordering
StreamDecryptionException
-> StreamDecryptionException -> StreamDecryptionException
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: StreamDecryptionException -> StreamDecryptionException -> Ordering
compare :: StreamDecryptionException -> StreamDecryptionException -> Ordering
$c< :: StreamDecryptionException -> StreamDecryptionException -> Bool
< :: StreamDecryptionException -> StreamDecryptionException -> Bool
$c<= :: StreamDecryptionException -> StreamDecryptionException -> Bool
<= :: StreamDecryptionException -> StreamDecryptionException -> Bool
$c> :: StreamDecryptionException -> StreamDecryptionException -> Bool
> :: StreamDecryptionException -> StreamDecryptionException -> Bool
$c>= :: StreamDecryptionException -> StreamDecryptionException -> Bool
>= :: StreamDecryptionException -> StreamDecryptionException -> Bool
$cmax :: StreamDecryptionException
-> StreamDecryptionException -> StreamDecryptionException
max :: StreamDecryptionException
-> StreamDecryptionException -> StreamDecryptionException
$cmin :: StreamDecryptionException
-> StreamDecryptionException -> StreamDecryptionException
min :: StreamDecryptionException
-> StreamDecryptionException -> StreamDecryptionException
Ord, Int -> StreamDecryptionException -> ShowS
[StreamDecryptionException] -> ShowS
StreamDecryptionException -> String
(Int -> StreamDecryptionException -> ShowS)
-> (StreamDecryptionException -> String)
-> ([StreamDecryptionException] -> ShowS)
-> Show StreamDecryptionException
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> StreamDecryptionException -> ShowS
showsPrec :: Int -> StreamDecryptionException -> ShowS
$cshow :: StreamDecryptionException -> String
show :: StreamDecryptionException -> String
$cshowList :: [StreamDecryptionException] -> ShowS
showList :: [StreamDecryptionException] -> ShowS
Show)
deriving anyclass (Show StreamDecryptionException
Typeable StreamDecryptionException
(Typeable StreamDecryptionException,
Show StreamDecryptionException) =>
(StreamDecryptionException -> SomeException)
-> (SomeException -> Maybe StreamDecryptionException)
-> (StreamDecryptionException -> String)
-> Exception StreamDecryptionException
SomeException -> Maybe StreamDecryptionException
StreamDecryptionException -> String
StreamDecryptionException -> SomeException
forall e.
(Typeable e, Show e) =>
(e -> SomeException)
-> (SomeException -> Maybe e) -> (e -> String) -> Exception e
$ctoException :: StreamDecryptionException -> SomeException
toException :: StreamDecryptionException -> SomeException
$cfromException :: SomeException -> Maybe StreamDecryptionException
fromException :: SomeException -> Maybe StreamDecryptionException
$cdisplayException :: StreamDecryptionException -> String
displayException :: StreamDecryptionException -> String
Exception)