@@ -1379,6 +1379,7 @@ enqueueMessage c cData sq msgFlags aMessage =
13791379 ExceptT $ fmap fst . runIdentity <$> enqueueMessageB c (Identity (Right (cData, [sq], Nothing , msgFlags, aMessage)))
13801380{-# INLINE enqueueMessage #-}
13811381
1382+ -- TODO [save once] IntMap of msg bodies.
13821383-- this function is used only for sending messages in batch, it returns the list of successes to enqueue additional deliveries
13831384enqueueMessageB :: forall t . Traversable t => AgentClient -> t (Either AgentErrorType (ConnData , NonEmpty SndQueue , Maybe PQEncryption , MsgFlags , AMessage )) -> AM' (t (Either AgentErrorType ((AgentMsgId , PQEncryption ), Maybe (ConnData , [SndQueue ], AgentMsgId ))))
13841385enqueueMessageB c reqs = do
@@ -1391,19 +1392,21 @@ enqueueMessageB c reqs = do
13911392 where
13921393 storeSentMsg :: DB. Connection -> AgentConfig -> (ConnData , NonEmpty SndQueue , Maybe PQEncryption , MsgFlags , AMessage ) -> IO (Either AgentErrorType ((ConnData , NonEmpty SndQueue , Maybe PQEncryption , MsgFlags , AMessage ), InternalId , PQEncryption ))
13931394 storeSentMsg db cfg req@ (cData@ ConnData {connId}, sq :| _, pqEnc_, msgFlags, aMessage) = fmap (first storeError) $ runExceptT $ do
1394- let AgentConfig {smpAgentVRange, e2eEncryptVRange} = cfg
1395+ let AgentConfig {e2eEncryptVRange} = cfg
13951396 internalTs <- liftIO getCurrentTime
13961397 (internalId, internalSndId, prevMsgHash) <- ExceptT $ updateSndIds db connId
13971398 let privHeader = APrivHeader (unSndId internalSndId) prevMsgHash
13981399 agentMsg = AgentMessage privHeader aMessage
13991400 agentMsgStr = smpEncode agentMsg
14001401 internalHash = C. sha256Hash agentMsgStr
14011402 currentE2EVersion = maxVersion e2eEncryptVRange
1402- (encAgentMessage, pqEnc) <- agentRatchetEncrypt db cData agentMsgStr e2eEncAgentMsgLength pqEnc_ currentE2EVersion
1403- let agentVersion = maxVersion smpAgentVRange
1404- msgBody = smpEncode $ AgentMsgEnvelope {agentVersion, encAgentMessage}
1405- msgType = agentMessageType agentMsg
1406- msgData = SndMsgData {internalId, internalSndId, internalTs, msgType, msgFlags, msgBody, pqEncryption = pqEnc, internalHash, prevMsgHash}
1403+ -- TODO [save once] Save single MsgBody / enveloped body agentMsgStr (outside of withStoreBatch ... storeSentMsg).
1404+ -- TODO Link messages to it, save encryption data per message.
1405+ -- TODO 'msg_body' field is not nullable - use default empty strings?
1406+ (mek, paddedLen, pqEnc) <- agentRatchetEncryptHeader db cData e2eEncAgentMsgLength pqEnc_ currentE2EVersion
1407+ withExceptT (SEAgentError . cryptoError) $ CR. rcCheckCanPad paddedLen agentMsgStr
1408+ let msgType = agentMessageType agentMsg
1409+ msgData = SndMsgData {internalId, internalSndId, internalTs, msgType, msgFlags, msgBody = agentMsgStr, pqEncryption = pqEnc, internalHash, prevMsgHash, encryptKey_ = Just mek, paddedLen_ = Just paddedLen}
14071410 liftIO $ createSndMsg db connId msgData
14081411 liftIO $ createSndMsgDelivery db connId sq internalId
14091412 pure (req, internalId, pqEnc)
@@ -1451,7 +1454,7 @@ runSmpQueueMsgDelivery c@AgentClient {subQ} ConnData {connId} sq@SndQueue {userI
14511454 liftIO $ throwWhenNoDelivery c sq
14521455 atomically $ beginAgentOperation c AOSndNetwork
14531456 withWork c doWork (\ db -> getPendingQueueMsg db connId sq) $
1454- \ (rq_, PendingMsgData {msgId, msgType, msgBody, pqEncryption, msgFlags, msgRetryState, internalTs}) -> do
1457+ \ (rq_, PendingMsgData {msgId, msgType, msgBody, pqEncryption, msgFlags, msgRetryState, internalTs, encryptKey_, paddedLen_ }) -> do
14551458 atomically $ endAgentOperation c AOMsgDelivery -- this operation begins in submitPendingMsg
14561459 let mId = unId msgId
14571460 ri' = maybe id updateRetryInterval2 msgRetryState ri
@@ -1461,7 +1464,15 @@ runSmpQueueMsgDelivery c@AgentClient {subQ} ConnData {connId} sq@SndQueue {userI
14611464 resp <- tryError $ case msgType of
14621465 AM_CONN_INFO -> sendConfirmation c sq msgBody
14631466 AM_CONN_INFO_REPLY -> sendConfirmation c sq msgBody
1464- _ -> sendAgentMessage c sq msgFlags msgBody
1467+ _ -> case (encryptKey_, paddedLen_) of
1468+ (Nothing , Nothing ) -> sendAgentMessage c sq msgFlags msgBody
1469+ (Just mek, Just paddedLen) -> do
1470+ AgentConfig {smpAgentVRange} <- asks config
1471+ encAgentMessage <- liftError cryptoError $ CR. rcEncryptMsg mek paddedLen msgBody
1472+ let agentVersion = maxVersion smpAgentVRange
1473+ msgBody' = smpEncode $ AgentMsgEnvelope {agentVersion, encAgentMessage}
1474+ sendAgentMessage c sq msgFlags msgBody'
1475+ _ -> throwE $ INTERNAL " runSmpQueueMsgDelivery: missing encryption data"
14651476 case resp of
14661477 Left e -> do
14671478 let err = if msgType == AM_A_MSG_ then MERR mId e else ERR e
@@ -1833,7 +1844,7 @@ deleteConnQueues c waitDelivery ntf rqs = do
18331844 deleteQueueRecs rs = do
18341845 maxErrs <- asks $ deleteErrorCount . config
18351846 rs' <- rights <$> withStoreBatch' c (\ db -> map (deleteQueueRec db maxErrs) rs)
1836- let delQ ((rq, _), err_) = (qConnId rq,qServer rq,queueId rq,) <$> err_
1847+ let delQ ((rq, _), err_) = (qConnId rq,qServer rq,queueId rq,) <$> err_
18371848 delQs_ = L. nonEmpty $ mapMaybe delQ rs'
18381849 forM_ delQs_ $ \ delQs -> notify (" " , " " , AEvt SAEConn $ DEL_RCVQS delQs)
18391850 pure $ map fst rs'
@@ -2952,7 +2963,7 @@ storeConfirmation c cData@ConnData {connId, pqSupport, connAgentVersion = v} sq
29522963 (encConnInfo, pqEncryption) <- agentRatchetEncrypt db cData agentMsgStr e2eEncConnInfoLength (Just pqEnc) currentE2EVersion
29532964 let msgBody = smpEncode $ AgentConfirmation {agentVersion = v, e2eEncryption_, encConnInfo}
29542965 msgType = agentMessageType agentMsg
2955- msgData = SndMsgData {internalId, internalSndId, internalTs, msgType, msgBody, pqEncryption, msgFlags = SMP. MsgFlags {notification = True }, internalHash, prevMsgHash}
2966+ msgData = SndMsgData {internalId, internalSndId, internalTs, msgType, msgBody, pqEncryption, msgFlags = SMP. MsgFlags {notification = True }, internalHash, prevMsgHash, encryptKey_ = Nothing , paddedLen_ = Nothing }
29562967 liftIO $ createSndMsg db connId msgData
29572968 liftIO $ createSndMsgDelivery db connId sq internalId
29582969
@@ -2978,19 +2989,25 @@ enqueueRatchetKey c cData@ConnData {connId} sq e2eEncryption = do
29782989 let msgBody = smpEncode $ AgentRatchetKey {agentVersion, e2eEncryption, info = agentMsgStr}
29792990 msgType = agentMessageType agentMsg
29802991 -- this message is e2e encrypted with queue key, not with double ratchet
2981- msgData = SndMsgData {internalId, internalSndId, internalTs, msgType, msgBody, pqEncryption = PQEncOff , msgFlags = SMP. MsgFlags {notification = True }, internalHash, prevMsgHash}
2992+ msgData = SndMsgData {internalId, internalSndId, internalTs, msgType, msgBody, pqEncryption = PQEncOff , msgFlags = SMP. MsgFlags {notification = True }, internalHash, prevMsgHash, encryptKey_ = Nothing , paddedLen_ = Nothing }
29822993 liftIO $ createSndMsg db connId msgData
29832994 liftIO $ createSndMsgDelivery db connId sq internalId
29842995 pure internalId
29852996
29862997-- encoded AgentMessage -> encoded EncAgentMessage
29872998agentRatchetEncrypt :: DB. Connection -> ConnData -> ByteString -> (VersionSMPA -> PQSupport -> Int ) -> Maybe PQEncryption -> CR. VersionE2E -> ExceptT StoreError IO (ByteString , PQEncryption )
2988- agentRatchetEncrypt db ConnData {connId, connAgentVersion = v, pqSupport} msg getPaddedLen pqEnc_ currentE2EVersion = do
2999+ agentRatchetEncrypt db cData msg getPaddedLen pqEnc_ currentE2EVersion = do
3000+ (mek, paddedLen, pqEnc) <- agentRatchetEncryptHeader db cData getPaddedLen pqEnc_ currentE2EVersion
3001+ encMsg <- withExceptT (SEAgentError . cryptoError) $ CR. rcEncryptMsg mek paddedLen msg
3002+ pure (encMsg, pqEnc)
3003+
3004+ agentRatchetEncryptHeader :: DB. Connection -> ConnData -> (VersionSMPA -> PQSupport -> Int ) -> Maybe PQEncryption -> CR. VersionE2E -> ExceptT StoreError IO (CR. MsgEncryptKeyX448 , Int , PQEncryption )
3005+ agentRatchetEncryptHeader db ConnData {connId, connAgentVersion = v, pqSupport} getPaddedLen pqEnc_ currentE2EVersion = do
29893006 rc <- ExceptT $ getRatchet db connId
29903007 let paddedLen = getPaddedLen v pqSupport
2991- (encMsg , rc') <- withExceptT (SEAgentError . cryptoError) $ CR. rcEncrypt rc paddedLen msg pqEnc_ currentE2EVersion
3008+ (mek , rc') <- withExceptT (SEAgentError . cryptoError) $ CR. rcEncryptHeader rc pqEnc_ currentE2EVersion
29923009 liftIO $ updateRatchet db connId rc' CR. SMDNoChange
2993- pure (encMsg , CR. rcSndKEM rc')
3010+ pure (mek, paddedLen , CR. rcSndKEM rc')
29943011
29953012-- encoded EncAgentMessage -> encoded AgentMessage
29963013agentRatchetDecrypt :: TVar ChaChaDRG -> DB. Connection -> ConnId -> ByteString -> ExceptT StoreError IO (ByteString , PQEncryption )
0 commit comments