core: encrypt/decrypt WebRTC frames (#1935)

* core: encrypt/decrypt WebRTC frames

* swift API

* add decrypt stub

* change name

* remove unused type

* move functions

* update cabal file

* copy bytes from encrypted string
This commit is contained in:
Evgeny Poberezkin 2023-02-16 20:25:37 +00:00 committed by GitHub
parent a0351d6f99
commit b7575ec01d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 0 deletions

View File

@ -22,3 +22,5 @@ extern char *chat_recv_msg(chat_ctrl ctl);
extern char *chat_recv_msg_wait(chat_ctrl ctl, int wait);
extern char *chat_parse_markdown(char *str);
extern char *chat_parse_server(char *str);
extern void chat_encrypt_media(char *key, char *frame, int len);
extern void chat_decrypt_media(char *key, char *frame, int len);

View File

@ -85,6 +85,7 @@ library
Simplex.Chat.Migrations.M20230129_drop_chat_items_group_idx
Simplex.Chat.Migrations.M20230206_item_deleted_by_group_member_id
Simplex.Chat.Mobile
Simplex.Chat.Mobile.WebRTC
Simplex.Chat.Options
Simplex.Chat.ProfileGenerator
Simplex.Chat.Protocol

View File

@ -18,6 +18,7 @@ import Data.Functor (($>))
import Data.List (find)
import qualified Data.List.NonEmpty as L
import Data.Maybe (fromMaybe)
import Data.Word (Word8)
import Database.SQLite.Simple (SQLError (..))
import qualified Database.SQLite.Simple as DB
import Foreign.C.String
@ -29,6 +30,7 @@ import GHC.Generics (Generic)
import Simplex.Chat
import Simplex.Chat.Controller
import Simplex.Chat.Markdown (ParsedMarkdown (..), parseMaybeMarkdownList)
import Simplex.Chat.Mobile.WebRTC
import Simplex.Chat.Options
import Simplex.Chat.Store
import Simplex.Chat.Types
@ -63,6 +65,10 @@ foreign export ccall "chat_parse_markdown" cChatParseMarkdown :: CString -> IO C
foreign export ccall "chat_parse_server" cChatParseServer :: CString -> IO CJSONString
foreign export ccall "chat_encrypt_media" cChatEncryptMedia :: CString -> Ptr Word8 -> CInt -> IO ()
foreign export ccall "chat_decrypt_media" cChatDecryptMedia :: CString -> Ptr Word8 -> CInt -> IO ()
-- | check / migrate database and initialize chat controller on success
cChatMigrateInit :: CString -> CString -> Ptr (StablePtr ChatController) -> IO CJSONString
cChatMigrateInit fp key ctrl = do

View File

@ -0,0 +1,43 @@
module Simplex.Chat.Mobile.WebRTC where
import qualified Data.ByteString as B
import Data.ByteString.Internal (ByteString(PS), memcpy)
import Foreign.C (CInt, CString)
import Foreign.Ptr (Ptr, plusPtr)
import Foreign.ForeignPtr (newForeignPtr_)
import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
import Control.Monad (when)
import Data.Word (Word8)
cChatEncryptMedia :: CString -> Ptr Word8 -> CInt -> IO ()
cChatEncryptMedia = cTransformMedia chatEncryptMedia
cChatDecryptMedia :: CString -> Ptr Word8 -> CInt -> IO ()
cChatDecryptMedia = cTransformMedia chatDecryptMedia
cTransformMedia :: (ByteString -> ByteString -> ByteString) -> CString -> Ptr Word8 -> CInt -> IO ()
cTransformMedia f cKey cFrame cFrameLen = do
key <- B.packCStringLen (cKey, 32)
frame <- getByteString cFrame cFrameLen
let frame' = f key frame
putByteString frame' cFrame cFrameLen
{-# INLINE cTransformMedia #-}
chatEncryptMedia :: ByteString -> ByteString -> ByteString
chatEncryptMedia _key frame = frame
chatDecryptMedia :: ByteString -> ByteString -> ByteString
chatDecryptMedia _key frame = frame
getByteString :: Ptr Word8 -> CInt -> IO ByteString
getByteString p size = do
fp <- newForeignPtr_ p
pure $ PS fp 0 $ fromIntegral size
{-# INLINE getByteString #-}
putByteString :: ByteString -> Ptr Word8 -> CInt -> IO ()
putByteString bs@(PS fp offset _) to size = do
let len = B.length bs
p = unsafeForeignPtrToPtr fp `plusPtr` offset
when (len <= fromIntegral size) $ memcpy to p len
{-# INLINE putByteString #-}