mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-05-14 14:05:08 +00:00
remove public header from all messages, fix envelope sizes (#251)
* fix envelope sizes * only send sender DH pub key for per-queue E2E with confirmation message
This commit is contained in:
committed by
GitHub
parent
83d085cadc
commit
4a73a7ecd4
@@ -26,7 +26,6 @@ CREATE TABLE rcv_queues (
|
||||
rcv_private_key BLOB NOT NULL,
|
||||
rcv_dh_secret BLOB NOT NULL,
|
||||
e2e_priv_key BLOB NOT NULL,
|
||||
e2e_snd_pub_key BLOB,
|
||||
e2e_dh_secret BLOB,
|
||||
snd_id BLOB NOT NULL,
|
||||
snd_key BLOB,
|
||||
@@ -45,7 +44,6 @@ CREATE TABLE snd_queues (
|
||||
snd_id BLOB NOT NULL,
|
||||
conn_alias BLOB NOT NULL REFERENCES connections ON DELETE CASCADE,
|
||||
snd_private_key BLOB NOT NULL,
|
||||
e2e_pub_key BLOB NOT NULL,
|
||||
e2e_dh_secret BLOB NOT NULL,
|
||||
status TEXT NOT NULL,
|
||||
smp_server_version INTEGER NOT NULL DEFAULT 1,
|
||||
|
||||
@@ -567,10 +567,11 @@ This command is sent to the server by the sender both to confirm the queue after
|
||||
```abnf
|
||||
send = %s"SEND " smpEncMessage
|
||||
smpEncMessage = smpPubHeader sentMsgBody ; message up to 15968 bytes
|
||||
smpPubHeader = smpClientVersion senderPublicDhKey
|
||||
smpPubHeader = smpClientVersion (%x01 senderPublicDhKey / %x00)
|
||||
smpClientVersion = word16
|
||||
senderPublicDhKey = length x509encoded
|
||||
; sender's Curve25519 public key to agree DH secret for E2E encryption in this queue
|
||||
; it is only sent in confirmation message
|
||||
x509encoded = <binary X509 key encoding>
|
||||
sentMsgBody = 15842*15842 OCTET
|
||||
; E2E-encrypted smpClientMessage padded to 15842 bytes before encryption
|
||||
@@ -609,21 +610,21 @@ SMP transmission structure for sent messages:
|
||||
```
|
||||
------- transmission (= 16384 bytes)
|
||||
2 | originalLength
|
||||
398- | signature SP sessionId SP corrId SP queueId SP %s"SEND" SP
|
||||
....... smpEncMessage (= 15968 bytes)
|
||||
396- | signature sessionId corrId queueId %s"SEND" SP (1+114 + 1+32? + 1+32 + 1+24 + 4+1 = 210)
|
||||
....... smpEncMessage (= 15968 bytes = 16384 - 416 bytes)
|
||||
126- | smpPubHeader
|
||||
24 | nonce for smpClientMessage
|
||||
------- smpClientMessage (E2E encrypted, = 15842 bytes)
|
||||
------- smpClientMessage (E2E encrypted, = 15802 bytes = 15968 - 166)
|
||||
2 | originalLength
|
||||
16- | smpPrivHeader
|
||||
.......
|
||||
| clientMsgBody (<= 15784 bytes)
|
||||
| clientMsgBody (<= 15784 bytes = 15802 - 18)
|
||||
.......
|
||||
0+ | smpClientMessage pad
|
||||
------- smpClientMessage end
|
||||
16 | auth tag for smpClientMessage
|
||||
....... smpEncMessage end
|
||||
16+ | transmission pad
|
||||
18+ | transmission pad
|
||||
------- transmission end
|
||||
```
|
||||
|
||||
@@ -632,28 +633,28 @@ SMP transmission structure for received messages:
|
||||
```
|
||||
------- transmission (= 16384 bytes)
|
||||
2 | originalLength
|
||||
398- | signature SP sessionId SP corrId SP queueId SP %s"MSG" SP msgId SP timestamp SP
|
||||
------- serverEncryptedMsg (= 15986 bytes)
|
||||
396- | signature sessionId corrId queueId %s"MSG" SP msgId timestamp (1+114 + 1+32? + 1+32 + 1+24 + 3+1 + 24+1 + 8 = 243)
|
||||
------- serverEncryptedMsg (= 15970 bytes = 16384 - 414 bytes)
|
||||
2 | originalLength
|
||||
....... smpEncMessage (= 15968 bytes)
|
||||
....... smpEncMessage (= 15968 bytes = 15970 - 2 bytes)
|
||||
126- | smpPubHeader
|
||||
24 | nonce for smpClientMessage
|
||||
------- smpClientMessage (E2E encrypted, = 15842 bytes)
|
||||
------- smpClientMessage (E2E encrypted, = 15802 bytes = 15968 - 166 bytes)
|
||||
2 | originalLength
|
||||
16- | smpPrivHeader
|
||||
....... clientMsgBody (<= 15784 bytes)
|
||||
....... clientMsgBody (<= 15784 bytes = 15802 - 18)
|
||||
-- TODO move internal structure to agent protocol
|
||||
16- | agentPublicHeader
|
||||
....... E2E double-ratchet encrypted (= 15768)
|
||||
16- | agentPublicHeader (the size is for user messages post handshake, without E2E X3DH keys)
|
||||
....... E2E double-ratchet encrypted (= 15768 bytes = 15784 - 16)
|
||||
96 | double-ratchet header
|
||||
16 | double-ratchet header auth tag
|
||||
24 | double-ratchet header iv
|
||||
------- encrypted agent message (= 15616 bytes)
|
||||
------- encrypted agent message (= 15616 bytes = 15768 - 152)
|
||||
2 | originalLength
|
||||
122 (90) | agentHeader
|
||||
4 | %s"MSG" SP
|
||||
.......
|
||||
| application message (<= 15488 bytes)
|
||||
| application message (<= 15488 bytes = 15616 - 128)
|
||||
.......
|
||||
0+ | encrypted agent message pad
|
||||
------- encrypted agent message end
|
||||
@@ -665,9 +666,9 @@ SMP transmission structure for received messages:
|
||||
------- smpClientMessage end
|
||||
16 | auth tag for smpClientMessage
|
||||
....... smpEncMessage end
|
||||
16 | auth tag (msgId is used as nonce)
|
||||
0+ | serverEncryptedMsg pad
|
||||
------- serverEncryptedMsg end
|
||||
16 | auth tag (msgId is used as nonce)
|
||||
0+ | transmission pad
|
||||
------- transmission end
|
||||
```
|
||||
|
||||
@@ -332,7 +332,7 @@ rejectContact' _ contactConnId invId =
|
||||
processConfirmation :: AgentMonad m => AgentClient -> RcvQueue -> SMPConfirmation -> m ()
|
||||
processConfirmation c rq@RcvQueue {e2ePrivKey} SMPConfirmation {senderKey, e2ePubKey} = do
|
||||
let dhSecret = C.dh' e2ePubKey e2ePrivKey
|
||||
withStore $ \st -> setRcvQueueConfirmedE2E st rq e2ePubKey dhSecret
|
||||
withStore $ \st -> setRcvQueueConfirmedE2E st rq dhSecret
|
||||
secureQueue c rq senderKey
|
||||
withStore $ \st -> setRcvQueueStatus st rq Secured
|
||||
|
||||
@@ -522,39 +522,38 @@ processSMPTransmission c@AgentClient {subQ} (srv, rId, cmd) = do
|
||||
_ -> atomically $ writeTBQueue subQ ("", "", ERR $ CONN NOT_FOUND)
|
||||
where
|
||||
processSMP :: SConnType c -> ConnData -> RcvQueue -> m ()
|
||||
processSMP cType ConnData {connId} rq@RcvQueue {rcvDhSecret, e2ePrivKey, e2eShared, status} =
|
||||
processSMP cType ConnData {connId} rq@RcvQueue {rcvDhSecret, e2ePrivKey, e2eDhSecret, status} =
|
||||
case cmd of
|
||||
SMP.MSG srvMsgId srvTs msgBody' -> handleNotifyAck $ do
|
||||
-- TODO deduplicate with previously received
|
||||
msgBody <- agentCbDecrypt rcvDhSecret (C.cbNonce srvMsgId) msgBody'
|
||||
encMessage@SMP.EncMessage {emHeader = SMP.PubHeader v e2ePubKey} <-
|
||||
encMessage@SMP.EncMessage {emHeader = SMP.PubHeader v e2ePubKey_} <-
|
||||
liftEither $ parse smpP (AGENT A_MESSAGE) msgBody
|
||||
case e2eShared of
|
||||
Nothing -> do
|
||||
let e2eDhSecret = C.dh' e2ePubKey e2ePrivKey
|
||||
case (e2eDhSecret, e2ePubKey_) of
|
||||
(Nothing, Just e2ePubKey) -> do
|
||||
let e2eDh = C.dh' e2ePubKey e2ePrivKey
|
||||
(_, agentMessage) <-
|
||||
decryptAgentMessage e2eDhSecret encMessage
|
||||
decryptAgentMessage e2eDh encMessage
|
||||
case agentMessage of
|
||||
AgentConfirmation senderKey connInfo -> do
|
||||
smpConfirmation SMPConfirmation {senderKey, e2ePubKey, connInfo}
|
||||
ack
|
||||
AgentInvitation cReq cInfo -> smpInvitation cReq cInfo >> ack
|
||||
_ -> prohibited >> ack
|
||||
Just (e2eSndPubKey, e2eDhSecret)
|
||||
| e2eSndPubKey /= e2ePubKey -> prohibited >> ack
|
||||
| otherwise -> do
|
||||
(msg, agentMessage) <-
|
||||
decryptAgentMessage e2eDhSecret encMessage
|
||||
case agentMessage of
|
||||
AgentMessage AHeader {sndMsgId, prevMsgHash} aMsg -> case aMsg of
|
||||
HELLO -> helloMsg >> ack
|
||||
REPLY cReq -> replyMsg cReq >> ack
|
||||
A_MSG body -> do
|
||||
-- note that there is no ACK sent here, it is sent with agent's user ACK command
|
||||
-- TODO add hash to other messages
|
||||
let msgHash = C.sha256Hash msg
|
||||
agentClientMsg prevMsgHash sndMsgId (srvMsgId, systemToUTCTime srvTs) body msgHash
|
||||
_ -> prohibited >> ack
|
||||
(Just e2eDh, Nothing) -> do
|
||||
(msg, agentMessage) <-
|
||||
decryptAgentMessage e2eDh encMessage
|
||||
case agentMessage of
|
||||
AgentMessage AHeader {sndMsgId, prevMsgHash} aMsg -> case aMsg of
|
||||
HELLO -> helloMsg >> ack
|
||||
REPLY cReq -> replyMsg cReq >> ack
|
||||
A_MSG body -> do
|
||||
-- note that there is no ACK sent here, it is sent with agent's user ACK command
|
||||
-- TODO add hash to other messages
|
||||
let msgHash = C.sha256Hash msg
|
||||
agentClientMsg prevMsgHash sndMsgId (srvMsgId, systemToUTCTime srvTs) body msgHash
|
||||
_ -> prohibited >> ack
|
||||
_ -> prohibited >> ack
|
||||
SMP.END -> do
|
||||
removeSubscription c connId
|
||||
logServer "<--" c srv rId "END"
|
||||
@@ -576,8 +575,8 @@ processSMPTransmission c@AgentClient {subQ} (srv, rId, cmd) = do
|
||||
ack = sendAck c rq
|
||||
|
||||
decryptAgentMessage :: C.DhSecretX25519 -> SMP.EncMessage -> m (ByteString, AgentMessage)
|
||||
decryptAgentMessage e2eDhSecret SMP.EncMessage {emNonce, emBody} = do
|
||||
msg <- agentCbDecrypt e2eDhSecret emNonce emBody
|
||||
decryptAgentMessage e2eDh SMP.EncMessage {emNonce, emBody} = do
|
||||
msg <- agentCbDecrypt e2eDh emNonce emBody
|
||||
agentMessage <-
|
||||
liftEither $ clientToAgentMsg =<< parse smpP (AGENT A_MESSAGE) msg
|
||||
pure (msg, agentMessage)
|
||||
@@ -699,7 +698,6 @@ newSndQueue_ a (SMPQueueUri smpServer senderId clientVersion rcvE2ePubDhKey) cIn
|
||||
{ server = smpServer,
|
||||
sndId = senderId,
|
||||
sndPrivateKey,
|
||||
e2ePubKey,
|
||||
e2eDhSecret = C.dh' rcvE2ePubDhKey e2ePrivKey,
|
||||
status = New
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ newRcvQueue_ a c srv = do
|
||||
rcvPrivateKey,
|
||||
rcvDhSecret = C.dh' rcvPublicDhKey privDhKey,
|
||||
e2ePrivKey,
|
||||
e2eShared = Nothing,
|
||||
e2eDhSecret = Nothing,
|
||||
sndId = Just sndId,
|
||||
status = New
|
||||
}
|
||||
@@ -305,14 +305,14 @@ logSecret :: ByteString -> ByteString
|
||||
logSecret bs = encode $ B.take 3 bs
|
||||
|
||||
sendConfirmation :: forall m. AgentMonad m => AgentClient -> SndQueue -> SMPConfirmation -> m ()
|
||||
sendConfirmation c sq@SndQueue {server, sndId} SMPConfirmation {senderKey, connInfo} =
|
||||
sendConfirmation c sq@SndQueue {server, sndId} SMPConfirmation {senderKey, e2ePubKey, connInfo} =
|
||||
withLogSMP_ c server sndId "SEND <KEY>" $ \smp -> do
|
||||
msg <- mkConfirmation
|
||||
liftSMP $ sendSMPMessage smp Nothing sndId msg
|
||||
where
|
||||
mkConfirmation :: m MsgBody
|
||||
mkConfirmation =
|
||||
agentCbEncrypt sq . serializeAgentMessage $
|
||||
agentCbEncrypt sq (Just e2ePubKey) . serializeAgentMessage $
|
||||
AgentConfirmation senderKey connInfo
|
||||
|
||||
sendHello :: forall m. AgentMonad m => AgentClient -> SndQueue -> RetryInterval -> m ()
|
||||
@@ -326,7 +326,7 @@ sendHello c sq@SndQueue {server, sndId, sndPrivateKey} ri =
|
||||
where
|
||||
mkHello :: m ByteString
|
||||
mkHello = do
|
||||
agentCbEncrypt sq . serializeAgentMessage $
|
||||
agentCbEncrypt sq Nothing . serializeAgentMessage $
|
||||
AgentMessage (AHeader 0 "") HELLO
|
||||
|
||||
sendInvitation :: forall m. AgentMonad m => AgentClient -> SMPQueueUri -> ConnectionRequest 'CMInvitation -> ConnInfo -> m ()
|
||||
@@ -363,11 +363,11 @@ deleteQueue c RcvQueue {server, rcvId, rcvPrivateKey} =
|
||||
sendAgentMessage :: AgentMonad m => AgentClient -> SndQueue -> ByteString -> m ()
|
||||
sendAgentMessage c sq@SndQueue {server, sndId, sndPrivateKey} msg =
|
||||
withLogSMP_ c server sndId "SEND <message>" $ \smp -> do
|
||||
msg' <- agentCbEncrypt sq msg
|
||||
msg' <- agentCbEncrypt sq Nothing msg
|
||||
liftSMP $ sendSMPMessage smp (Just sndPrivateKey) sndId msg'
|
||||
|
||||
agentCbEncrypt :: AgentMonad m => SndQueue -> ByteString -> m ByteString
|
||||
agentCbEncrypt SndQueue {e2ePubKey, e2eDhSecret} msg = do
|
||||
agentCbEncrypt :: AgentMonad m => SndQueue -> Maybe C.PublicKeyX25519 -> ByteString -> m ByteString
|
||||
agentCbEncrypt SndQueue {e2eDhSecret} e2ePubKey msg = do
|
||||
emNonce <- liftIO C.randomCbNonce
|
||||
emBody <-
|
||||
liftEither . first cryptoError $
|
||||
@@ -385,7 +385,7 @@ agentCbEncryptOnce dhRcvPubKey msg = do
|
||||
liftEither . first cryptoError $
|
||||
C.cbEncrypt e2eDhSecret emNonce msg SMP.e2eEncMessageLength
|
||||
-- TODO per-queue client version
|
||||
let emHeader = SMP.PubHeader (maxVersion SMP.smpClientVersion) dhSndPubKey
|
||||
let emHeader = SMP.PubHeader (maxVersion SMP.smpClientVersion) (Just dhSndPubKey)
|
||||
pure $ smpEncode SMP.EncMessage {emHeader, emNonce, emBody}
|
||||
|
||||
agentCbDecrypt :: AgentMonad m => C.DhSecretX25519 -> C.CbNonce -> ByteString -> m ByteString
|
||||
|
||||
@@ -44,7 +44,7 @@ class Monad m => MonadAgentStore s m where
|
||||
upgradeRcvConnToDuplex :: s -> ConnId -> SndQueue -> m ()
|
||||
upgradeSndConnToDuplex :: s -> ConnId -> RcvQueue -> m ()
|
||||
setRcvQueueStatus :: s -> RcvQueue -> QueueStatus -> m ()
|
||||
setRcvQueueConfirmedE2E :: s -> RcvQueue -> C.PublicKeyX25519 -> C.DhSecretX25519 -> m ()
|
||||
setRcvQueueConfirmedE2E :: s -> RcvQueue -> C.DhSecretX25519 -> m ()
|
||||
setSndQueueStatus :: s -> SndQueue -> QueueStatus -> m ()
|
||||
|
||||
-- Confirmations
|
||||
@@ -85,7 +85,7 @@ data RcvQueue = RcvQueue
|
||||
-- | private DH key related to public sent to sender out-of-band (to agree simple per-queue e2e)
|
||||
e2ePrivKey :: C.PrivateKeyX25519,
|
||||
-- | public sender's DH key and agreed shared DH secret for simple per-queue e2e
|
||||
e2eShared :: Maybe (C.PublicKeyX25519, C.DhSecretX25519),
|
||||
e2eDhSecret :: Maybe C.DhSecretX25519,
|
||||
-- | sender queue ID
|
||||
sndId :: Maybe SMP.SenderId,
|
||||
-- | queue status
|
||||
@@ -100,8 +100,6 @@ data SndQueue = SndQueue
|
||||
sndId :: SMP.SenderId,
|
||||
-- | key used by the sender to sign transmissions
|
||||
sndPrivateKey :: SndPrivateSignKey,
|
||||
-- | public DH key that was (or needs to be) sent to the recipient in SMP confirmation (to agree simple per-queue e2e)
|
||||
e2ePubKey :: C.PublicKeyX25519,
|
||||
-- | shared DH secret agreed for simple per-queue e2e encryption
|
||||
e2eDhSecret :: C.DhSecretX25519,
|
||||
-- | queue status
|
||||
|
||||
@@ -241,20 +241,18 @@ instance (MonadUnliftIO m, MonadError StoreError m) => MonadAgentStore SQLiteSto
|
||||
|]
|
||||
[":status" := status, ":host" := host, ":port" := port, ":rcv_id" := rcvId]
|
||||
|
||||
setRcvQueueConfirmedE2E :: SQLiteStore -> RcvQueue -> C.PublicKeyX25519 -> C.DhSecretX25519 -> m ()
|
||||
setRcvQueueConfirmedE2E st RcvQueue {rcvId, server = SMPServer {host, port}} e2eSndPubKey e2eDhSecret =
|
||||
setRcvQueueConfirmedE2E :: SQLiteStore -> RcvQueue -> C.DhSecretX25519 -> m ()
|
||||
setRcvQueueConfirmedE2E st RcvQueue {rcvId, server = SMPServer {host, port}} e2eDhSecret =
|
||||
liftIO . withTransaction st $ \db ->
|
||||
DB.executeNamed
|
||||
db
|
||||
[sql|
|
||||
UPDATE rcv_queues
|
||||
SET e2e_snd_pub_key = :e2e_snd_pub_key,
|
||||
e2e_dh_secret = :e2e_dh_secret,
|
||||
SET e2e_dh_secret = :e2e_dh_secret,
|
||||
status = :status
|
||||
WHERE host = :host AND port = :port AND rcv_id = :rcv_id
|
||||
|]
|
||||
[ ":status" := Confirmed,
|
||||
":e2e_snd_pub_key" := e2eSndPubKey,
|
||||
":e2e_dh_secret" := e2eDhSecret,
|
||||
":host" := host,
|
||||
":port" := port,
|
||||
@@ -621,15 +619,13 @@ upsertServer_ dbConn SMPServer {host, port, keyHash} = do
|
||||
|
||||
insertRcvQueue_ :: DB.Connection -> ConnId -> RcvQueue -> IO ()
|
||||
insertRcvQueue_ dbConn connId RcvQueue {..} = do
|
||||
let e2eSndPubKey = fst <$> e2eShared :: Maybe C.PublicKeyX25519
|
||||
e2eDhSecret = snd <$> e2eShared :: Maybe C.DhSecretX25519
|
||||
DB.executeNamed
|
||||
dbConn
|
||||
[sql|
|
||||
INSERT INTO rcv_queues
|
||||
( host, port, rcv_id, conn_alias, rcv_private_key, rcv_dh_secret, e2e_priv_key, e2e_snd_pub_key, e2e_dh_secret, snd_id, status)
|
||||
( host, port, rcv_id, conn_alias, rcv_private_key, rcv_dh_secret, e2e_priv_key, e2e_dh_secret, snd_id, status)
|
||||
VALUES
|
||||
(:host,:port,:rcv_id,:conn_alias,:rcv_private_key,:rcv_dh_secret,:e2e_priv_key,:e2e_snd_pub_key,:e2e_dh_secret,:snd_id,:status);
|
||||
(:host,:port,:rcv_id,:conn_alias,:rcv_private_key,:rcv_dh_secret,:e2e_priv_key,:e2e_dh_secret,:snd_id,:status);
|
||||
|]
|
||||
[ ":host" := host server,
|
||||
":port" := port server,
|
||||
@@ -638,7 +634,6 @@ insertRcvQueue_ dbConn connId RcvQueue {..} = do
|
||||
":rcv_private_key" := rcvPrivateKey,
|
||||
":rcv_dh_secret" := rcvDhSecret,
|
||||
":e2e_priv_key" := e2ePrivKey,
|
||||
":e2e_snd_pub_key" := e2eSndPubKey,
|
||||
":e2e_dh_secret" := e2eDhSecret,
|
||||
":snd_id" := sndId,
|
||||
":status" := status
|
||||
@@ -652,16 +647,15 @@ insertSndQueue_ dbConn connId SndQueue {..} = do
|
||||
dbConn
|
||||
[sql|
|
||||
INSERT INTO snd_queues
|
||||
( host, port, snd_id, conn_alias, snd_private_key, e2e_pub_key, e2e_dh_secret, status)
|
||||
( host, port, snd_id, conn_alias, snd_private_key, e2e_dh_secret, status)
|
||||
VALUES
|
||||
(:host,:port,:snd_id,:conn_alias,:snd_private_key,:e2e_pub_key,:e2e_dh_secret,:status);
|
||||
(:host,:port,:snd_id,:conn_alias,:snd_private_key,:e2e_dh_secret,:status);
|
||||
|]
|
||||
[ ":host" := host server,
|
||||
":port" := port server,
|
||||
":snd_id" := sndId,
|
||||
":conn_alias" := connId,
|
||||
":snd_private_key" := sndPrivateKey,
|
||||
":e2e_pub_key" := e2ePubKey,
|
||||
":e2e_dh_secret" := e2eDhSecret,
|
||||
":status" := status
|
||||
]
|
||||
@@ -697,17 +691,16 @@ getRcvQueueByConnAlias_ dbConn connId =
|
||||
dbConn
|
||||
[sql|
|
||||
SELECT s.key_hash, q.host, q.port, q.rcv_id, q.rcv_private_key, q.rcv_dh_secret,
|
||||
q.e2e_priv_key, q.e2e_snd_pub_key, q.e2e_dh_secret, q.snd_id, q.status
|
||||
q.e2e_priv_key, q.e2e_dh_secret, q.snd_id, q.status
|
||||
FROM rcv_queues q
|
||||
INNER JOIN servers s ON q.host = s.host AND q.port = s.port
|
||||
WHERE q.conn_alias = ?;
|
||||
|]
|
||||
(Only connId)
|
||||
where
|
||||
rcvQueue [(keyHash, host, port, rcvId, rcvPrivateKey, rcvDhSecret, e2ePrivKey, e2eSndPubKey, e2eDhSecret, sndId, status)] =
|
||||
rcvQueue [(keyHash, host, port, rcvId, rcvPrivateKey, rcvDhSecret, e2ePrivKey, e2eDhSecret, sndId, status)] =
|
||||
let server = SMPServer host port keyHash
|
||||
e2eShared = (,) <$> e2eSndPubKey <*> e2eDhSecret
|
||||
in Just RcvQueue {server, rcvId, rcvPrivateKey, rcvDhSecret, e2ePrivKey, e2eShared, sndId, status}
|
||||
in Just RcvQueue {server, rcvId, rcvPrivateKey, rcvDhSecret, e2ePrivKey, e2eDhSecret, sndId, status}
|
||||
rcvQueue _ = Nothing
|
||||
|
||||
getSndQueueByConnAlias_ :: DB.Connection -> ConnId -> IO (Maybe SndQueue)
|
||||
@@ -716,17 +709,16 @@ getSndQueueByConnAlias_ dbConn connId =
|
||||
<$> DB.query
|
||||
dbConn
|
||||
[sql|
|
||||
SELECT s.key_hash, q.host, q.port, q.snd_id, q.snd_private_key,
|
||||
q.e2e_pub_key, q.e2e_dh_secret, q.status
|
||||
SELECT s.key_hash, q.host, q.port, q.snd_id, q.snd_private_key, q.e2e_dh_secret, q.status
|
||||
FROM snd_queues q
|
||||
INNER JOIN servers s ON q.host = s.host AND q.port = s.port
|
||||
WHERE q.conn_alias = ?;
|
||||
|]
|
||||
(Only connId)
|
||||
where
|
||||
sndQueue [(keyHash, host, port, sndId, sndPrivateKey, e2ePubKey, e2eDhSecret, status)] =
|
||||
sndQueue [(keyHash, host, port, sndId, sndPrivateKey, e2eDhSecret, status)] =
|
||||
let server = SMPServer host port keyHash
|
||||
in Just SndQueue {server, sndId, sndPrivateKey, e2ePubKey, e2eDhSecret, status}
|
||||
in Just SndQueue {server, sndId, sndPrivateKey, e2eDhSecret, status}
|
||||
sndQueue _ = Nothing
|
||||
|
||||
-- * updateRcvIds helpers
|
||||
|
||||
@@ -815,6 +815,7 @@ cbDecrypt secret (CbNonce nonce) packet
|
||||
tag = Poly1305.auth rs c
|
||||
|
||||
newtype CbNonce = CbNonce {unCbNonce :: ByteString}
|
||||
deriving (Show)
|
||||
|
||||
cbNonce :: ByteString -> CbNonce
|
||||
cbNonce s
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE FlexibleInstances #-}
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
{-# LANGUAGE TypeApplications #-}
|
||||
@@ -66,6 +67,14 @@ instance Encoding ByteString where
|
||||
smpEncode s = B.cons (w2c len) s where len = fromIntegral $ B.length s
|
||||
smpP = A.take . fromIntegral . c2w =<< A.anyChar
|
||||
|
||||
instance Encoding a => Encoding (Maybe a) where
|
||||
smpEncode s = maybe "\0" (("\1" <>) . smpEncode) s
|
||||
smpP =
|
||||
smpP >>= \case
|
||||
'\0' -> pure Nothing
|
||||
'\1' -> Just <$> smpP
|
||||
_ -> fail "invalid Maybe tag"
|
||||
|
||||
newtype Tail = Tail {unTail :: ByteString}
|
||||
|
||||
instance Encoding Tail where
|
||||
|
||||
@@ -322,11 +322,13 @@ data EncMessage = EncMessage
|
||||
emNonce :: C.CbNonce,
|
||||
emBody :: ByteString
|
||||
}
|
||||
deriving (Show)
|
||||
|
||||
data PubHeader = PubHeader
|
||||
{ phVersion :: Word16,
|
||||
phE2ePubDhKey :: C.PublicKeyX25519
|
||||
phE2ePubDhKey :: Maybe C.PublicKeyX25519
|
||||
}
|
||||
deriving (Show)
|
||||
|
||||
instance Encoding PubHeader where
|
||||
smpEncode (PubHeader v k) = smpEncode (v, k)
|
||||
|
||||
@@ -137,9 +137,9 @@ testForeignKeysEnabled =
|
||||
let inconsistentQuery =
|
||||
[sql|
|
||||
INSERT INTO snd_queues
|
||||
( host, port, snd_id, conn_alias, snd_private_key, e2e_pub_key, e2e_dh_secret, status)
|
||||
( host, port, snd_id, conn_alias, snd_private_key, e2e_dh_secret, status)
|
||||
VALUES
|
||||
('smp.simplex.im', '5223', '1234', '2345', x'', x'', x'', 'new');
|
||||
('smp.simplex.im', '5223', '1234', '2345', x'', x'', 'new');
|
||||
|]
|
||||
DB.execute_ db inconsistentQuery
|
||||
`shouldThrow` (\e -> DB.sqlError e == DB.ErrorConstraint)
|
||||
@@ -150,9 +150,6 @@ cData1 = ConnData {connId = "conn1"}
|
||||
testPrivateSignKey :: C.APrivateSignKey
|
||||
testPrivateSignKey = C.APrivateSignKey C.SEd25519 "MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe"
|
||||
|
||||
testPubDhKey :: C.PublicKeyX25519
|
||||
testPubDhKey = "MCowBQYDK2VuAyEAjiswwI3O/NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o="
|
||||
|
||||
testPrivDhKey :: C.PrivateKeyX25519
|
||||
testPrivDhKey = "MC4CAQAwBQYDK2VuBCIEINCzbVFaCiYHoYncxNY8tSIfn0pXcIAhLBfFc0m+gOpk"
|
||||
|
||||
@@ -167,7 +164,7 @@ rcvQueue1 =
|
||||
rcvPrivateKey = testPrivateSignKey,
|
||||
rcvDhSecret = testDhSecret,
|
||||
e2ePrivKey = testPrivDhKey,
|
||||
e2eShared = Nothing,
|
||||
e2eDhSecret = Nothing,
|
||||
sndId = Just "2345",
|
||||
status = New
|
||||
}
|
||||
@@ -178,7 +175,6 @@ sndQueue1 =
|
||||
{ server = SMPServer "smp.simplex.im" (Just "5223") testKeyHash,
|
||||
sndId = "3456",
|
||||
sndPrivateKey = testPrivateSignKey,
|
||||
e2ePubKey = testPubDhKey,
|
||||
e2eDhSecret = testDhSecret,
|
||||
status = New
|
||||
}
|
||||
@@ -309,7 +305,6 @@ testUpgradeRcvConnToDuplex =
|
||||
{ server = SMPServer "smp.simplex.im" (Just "5223") testKeyHash,
|
||||
sndId = "2345",
|
||||
sndPrivateKey = testPrivateSignKey,
|
||||
e2ePubKey = testPubDhKey,
|
||||
e2eDhSecret = testDhSecret,
|
||||
status = New
|
||||
}
|
||||
@@ -331,7 +326,7 @@ testUpgradeSndConnToDuplex =
|
||||
rcvPrivateKey = testPrivateSignKey,
|
||||
rcvDhSecret = testDhSecret,
|
||||
e2ePrivKey = testPrivDhKey,
|
||||
e2eShared = Nothing,
|
||||
e2eDhSecret = Nothing,
|
||||
sndId = Just "4567",
|
||||
status = New
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user