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_recv_msg_wait(chat_ctrl ctl, int wait);
extern char *chat_parse_markdown(char *str); extern char *chat_parse_markdown(char *str);
extern char *chat_parse_server(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.M20230129_drop_chat_items_group_idx
Simplex.Chat.Migrations.M20230206_item_deleted_by_group_member_id Simplex.Chat.Migrations.M20230206_item_deleted_by_group_member_id
Simplex.Chat.Mobile Simplex.Chat.Mobile
Simplex.Chat.Mobile.WebRTC
Simplex.Chat.Options Simplex.Chat.Options
Simplex.Chat.ProfileGenerator Simplex.Chat.ProfileGenerator
Simplex.Chat.Protocol Simplex.Chat.Protocol

View File

@ -18,6 +18,7 @@ import Data.Functor (($>))
import Data.List (find) import Data.List (find)
import qualified Data.List.NonEmpty as L import qualified Data.List.NonEmpty as L
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
import Data.Word (Word8)
import Database.SQLite.Simple (SQLError (..)) import Database.SQLite.Simple (SQLError (..))
import qualified Database.SQLite.Simple as DB import qualified Database.SQLite.Simple as DB
import Foreign.C.String import Foreign.C.String
@ -29,6 +30,7 @@ import GHC.Generics (Generic)
import Simplex.Chat import Simplex.Chat
import Simplex.Chat.Controller import Simplex.Chat.Controller
import Simplex.Chat.Markdown (ParsedMarkdown (..), parseMaybeMarkdownList) import Simplex.Chat.Markdown (ParsedMarkdown (..), parseMaybeMarkdownList)
import Simplex.Chat.Mobile.WebRTC
import Simplex.Chat.Options import Simplex.Chat.Options
import Simplex.Chat.Store import Simplex.Chat.Store
import Simplex.Chat.Types 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_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 -- | check / migrate database and initialize chat controller on success
cChatMigrateInit :: CString -> CString -> Ptr (StablePtr ChatController) -> IO CJSONString cChatMigrateInit :: CString -> CString -> Ptr (StablePtr ChatController) -> IO CJSONString
cChatMigrateInit fp key ctrl = do 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 #-}