Skip to content

Commit 51e3a51

Browse files
committed
smp protocol: create notification credentials via NEW command that creates the queue
1 parent d3e2d9a commit 51e3a51

File tree

9 files changed

+118
-100
lines changed

9 files changed

+118
-100
lines changed

src/Simplex/Messaging/Agent.hs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -953,12 +953,11 @@ newRcvConnSrv c nm userId connId enableNtfs cMode userData_ clientData pqInitKey
953953
createRcvQueue :: Maybe C.CbNonce -> ClntQueueReqData -> C.KeyPairX25519 -> AM (RcvQueue, SMPQueueUri)
954954
createRcvQueue nonce_ qd e2eKeys = do
955955
AgentConfig {smpClientVRange = vr} <- asks config
956-
-- TODO [notifications] send correct NTF credentials here
957-
-- let ntfCreds_ = Nothing
958-
(rq, qUri, tSess, sessId) <- newRcvQueue_ c nm userId connId srvWithAuth vr qd subMode nonce_ e2eKeys `catchAgentError` \e -> liftIO (print e) >> throwE e
956+
(rq, qUri, tSess, sessId) <- newRcvQueue_ c nm userId connId srvWithAuth vr qd enableNtfs subMode nonce_ e2eKeys `catchAgentError` \e -> liftIO (print e) >> throwE e
959957
atomically $ incSMPServerStat c userId srv connCreated
960958
rq' <- withStore c $ \db -> updateNewConnRcv db connId rq
961959
lift . when (subMode == SMSubscribe) $ addNewQueueSubscription c rq' tSess sessId
960+
-- TODO [notifications] send next command if already created
962961
when enableNtfs $ do
963962
ns <- asks ntfSupervisor
964963
atomically $ sendNtfSubCommand ns (NSCCreate, [connId])
@@ -981,7 +980,7 @@ newRcvConnSrv c nm userId connId enableNtfs cMode userData_ clientData pqInitKey
981980
nonce@(C.CbNonce corrId) <- atomically $ C.randomCbNonce g
982981
sigKeys@(_, privSigKey) <- atomically $ C.generateKeyPair @'C.Ed25519 g
983982
AgentConfig {smpClientVRange = vr, smpAgentVRange} <- asks config
984-
-- TODO [notifications] the remaining 24 bytes are reserved for notifier ID
983+
-- the remaining 24 bytes are reserved, possibly for notifier ID in the new notifications protocol
985984
let sndId = SMP.EntityId $ B.take 24 $ C.sha3_384 corrId
986985
qm = case cMode of SCMContact -> QMContact; SCMInvitation -> QMMessaging
987986
qUri = SMPQueueUri vr $ SMPQueueAddress srv sndId e2eDhKey (Just qm)
@@ -1192,12 +1191,12 @@ joinConnSrvAsync _c _userId _connId _enableNtfs (CRContactUri _) _cInfo _subMode
11921191

11931192
createReplyQueue :: AgentClient -> NetworkRequestMode -> ConnData -> SndQueue -> SubscriptionMode -> SMPServerWithAuth -> AM (SMPQueueInfo, Maybe ClientServiceId)
11941193
createReplyQueue c nm ConnData {userId, connId, enableNtfs} SndQueue {smpClientVersion} subMode srv = do
1195-
-- TODO [notifications] send correct NTF credentials here
1196-
(rq, qUri, tSess, sessId) <- newRcvQueue c nm userId connId srv (versionToRange smpClientVersion) SCMInvitation subMode -- Nothing
1194+
(rq, qUri, tSess, sessId) <- newRcvQueue c nm userId connId srv (versionToRange smpClientVersion) SCMInvitation enableNtfs subMode
11971195
atomically $ incSMPServerStat c userId (qServer rq) connCreated
11981196
let qInfo = toVersionT qUri smpClientVersion
11991197
rq' <- withStore c $ \db -> upgradeSndConnToDuplex db connId rq
12001198
lift . when (subMode == SMSubscribe) $ addNewQueueSubscription c rq' tSess sessId
1199+
-- TODO [notifications] send next command if already created
12011200
when enableNtfs $ do
12021201
ns <- asks ntfSupervisor
12031202
atomically $ sendNtfSubCommand ns (NSCCreate, [connId])
@@ -1984,17 +1983,17 @@ switchConnection' c nm connId =
19841983
_ -> throwE $ CMD PROHIBITED "switchConnection: not duplex"
19851984

19861985
switchDuplexConnection :: AgentClient -> NetworkRequestMode -> Connection 'CDuplex -> RcvQueue -> AM ConnectionStats
1987-
switchDuplexConnection c nm (DuplexConnection cData@ConnData {connId, userId} rqs sqs) rq@RcvQueue {server, dbQueueId = DBEntityId dbQueueId, sndId} = do
1986+
switchDuplexConnection c nm (DuplexConnection cData@ConnData {connId, userId, enableNtfs} rqs sqs) rq@RcvQueue {server, dbQueueId = DBEntityId dbQueueId, sndId} = do
19881987
checkRQSwchStatus rq RSSwitchStarted
19891988
clientVRange <- asks $ smpClientVRange . config
19901989
-- try to get the server that is different from all queues, or at least from the primary rcv queue
19911990
srvAuth@(ProtoServerWithAuth srv _) <- getNextSMPServer c userId $ map qServer (L.toList rqs) <> map qServer (L.toList sqs)
19921991
srv' <- if srv == server then getNextSMPServer c userId [server] else pure srvAuth
1993-
-- TODO [notifications] send correct NTF credentials here
1994-
(q, qUri, tSess, sessId) <- newRcvQueue c nm userId connId srv' clientVRange SCMInvitation SMSubscribe -- Nothing
1992+
(q, qUri, tSess, sessId) <- newRcvQueue c nm userId connId srv' clientVRange SCMInvitation enableNtfs SMSubscribe
19951993
let rq' = (q :: NewRcvQueue) {primary = True, dbReplaceQueueId = Just dbQueueId}
19961994
rq'' <- withStore c $ \db -> addConnRcvQueue db connId rq'
19971995
lift $ addNewQueueSubscription c rq'' tSess sessId
1996+
-- TODO [notifications] send ntf supervisor command
19981997
void . enqueueMessages c cData sqs SMP.noMsgFlags $ QADD [(qUri, Just (server, sndId))]
19991998
rq1 <- withStore' c $ \db -> setRcvSwitchStatus db rq $ Just RSSendingQADD
20001999
let rqs' = updatedQs rq1 rqs <> [rq'']

src/Simplex/Messaging/Agent/Client.hs

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,6 @@ import Simplex.Messaging.Protocol
251251
ErrorType,
252252
MsgFlags (..),
253253
MsgId,
254-
NtfPublicAuthKey,
255254
NtfServer,
256255
NtfServerWithAuth,
257256
ProtoServer,
@@ -261,12 +260,14 @@ import Simplex.Messaging.Protocol
261260
ProtocolType (..),
262261
ProtocolTypeI (..),
263262
QueueIdsKeys (..),
263+
ServerNtfCreds (..),
264264
RcvMessage (..),
265265
RcvNtfPublicDhKey,
266266
SMPMsgMeta (..),
267267
SProtocolType (..),
268268
SndPublicAuthKey,
269269
SubscriptionMode (..),
270+
NewNtfCreds (..),
270271
QueueReqData (..),
271272
QueueLinkData,
272273
UserProtocol,
@@ -283,7 +284,7 @@ import Simplex.Messaging.Session
283284
import Simplex.Messaging.Agent.Store.Entity
284285
import Simplex.Messaging.TMap (TMap)
285286
import qualified Simplex.Messaging.TMap as TM
286-
import Simplex.Messaging.Transport (SMPVersion, SessionId, THandleParams (sessionId, thVersion), TransportError (..), TransportPeer (..), sndAuthKeySMPVersion, shortLinksSMPVersion)
287+
import Simplex.Messaging.Transport (SMPVersion, SessionId, THandleParams (sessionId, thVersion), TransportError (..), TransportPeer (..), sndAuthKeySMPVersion, shortLinksSMPVersion, newNtfCredsSMPVersion)
287288
import Simplex.Messaging.Transport.Client (TransportHost (..))
288289
import Simplex.Messaging.Util
289290
import Simplex.Messaging.Version
@@ -1240,8 +1241,7 @@ runSMPServerTest c nm userId (ProtoServerWithAuth srv auth) = do
12401241
(sKey, spKey) <- atomically $ C.generateAuthKeyPair sa g
12411242
(dhKey, _) <- atomically $ C.generateKeyPair g
12421243
r <- runExceptT $ do
1243-
-- TODO [notifications]
1244-
SMP.QIK {rcvId, sndId, queueMode} <- liftError (testErr TSCreateQueue) $ createSMPQueue smp nm Nothing rKeys dhKey auth SMSubscribe (QRMessaging Nothing) -- Nothing
1244+
SMP.QIK {rcvId, sndId, queueMode} <- liftError (testErr TSCreateQueue) $ createSMPQueue smp nm Nothing rKeys dhKey auth SMSubscribe (QRMessaging Nothing) Nothing
12451245
liftError (testErr TSSecureQueue) $
12461246
case queueMode of
12471247
Just QMMessaging -> secureSndSMPQueue smp nm spKey sndId sKey
@@ -1352,12 +1352,11 @@ getSessionMode :: MonadIO m => AgentClient -> m TransportSessionMode
13521352
getSessionMode = fmap sessionMode . getNetworkConfig
13531353
{-# INLINE getSessionMode #-}
13541354

1355-
-- TODO [notifications]
1356-
newRcvQueue :: AgentClient -> NetworkRequestMode -> UserId -> ConnId -> SMPServerWithAuth -> VersionRangeSMPC -> SConnectionMode c -> SubscriptionMode -> AM (NewRcvQueue, SMPQueueUri, SMPTransportSession, SessionId)
1357-
newRcvQueue c nm userId connId srv vRange cMode subMode = do
1355+
newRcvQueue :: AgentClient -> NetworkRequestMode -> UserId -> ConnId -> SMPServerWithAuth -> VersionRangeSMPC -> SConnectionMode c -> Bool -> SubscriptionMode -> AM (NewRcvQueue, SMPQueueUri, SMPTransportSession, SessionId)
1356+
newRcvQueue c nm userId connId srv vRange cMode enableNtfs subMode = do
13581357
let qrd = case cMode of SCMInvitation -> CQRMessaging Nothing; SCMContact -> CQRContact Nothing
13591358
e2eKeys <- atomically . C.generateKeyPair =<< asks random
1360-
newRcvQueue_ c nm userId connId srv vRange qrd subMode Nothing e2eKeys
1359+
newRcvQueue_ c nm userId connId srv vRange qrd enableNtfs subMode Nothing e2eKeys
13611360

13621361
data ClntQueueReqData
13631362
= CQRMessaging (Maybe (CQRData (SMP.SenderId, QueueLinkData)))
@@ -1374,21 +1373,21 @@ queueReqData = \case
13741373
CQRMessaging d -> QRMessaging $ srvReq <$> d
13751374
CQRContact d -> QRContact $ srvReq <$> d
13761375

1377-
newRcvQueue_ :: AgentClient -> NetworkRequestMode -> UserId -> ConnId -> SMPServerWithAuth -> VersionRangeSMPC -> ClntQueueReqData -> SubscriptionMode -> Maybe C.CbNonce -> C.KeyPairX25519 -> AM (NewRcvQueue, SMPQueueUri, SMPTransportSession, SessionId)
1378-
newRcvQueue_ c nm userId connId (ProtoServerWithAuth srv auth) vRange cqrd subMode nonce_ (e2eDhKey, e2ePrivKey) = do
1376+
newRcvQueue_ :: AgentClient -> NetworkRequestMode -> UserId -> ConnId -> SMPServerWithAuth -> VersionRangeSMPC -> ClntQueueReqData -> Bool -> SubscriptionMode -> Maybe C.CbNonce -> C.KeyPairX25519 -> AM (NewRcvQueue, SMPQueueUri, SMPTransportSession, SessionId)
1377+
newRcvQueue_ c nm userId connId (ProtoServerWithAuth srv auth) vRange cqrd enableNtfs subMode nonce_ (e2eDhKey, e2ePrivKey) = do
13791378
C.AuthAlg a <- asks (rcvAuthAlg . config)
13801379
g <- asks random
13811380
rKeys@(_, rcvPrivateKey) <- atomically $ C.generateAuthKeyPair a g
13821381
(dhKey, privDhKey) <- atomically $ C.generateKeyPair g
13831382
logServer "-->" c srv NoEntity "NEW"
13841383
tSess <- mkTransportSession c userId srv connId
1385-
-- TODO [notifications]
1386-
r@(thParams', QIK {rcvId, sndId, rcvPublicDhKey, queueMode, serviceId}) <-
1387-
withClient c nm tSess $ \(SMPConnectedClient smp _) ->
1388-
(thParams smp,) <$> createSMPQueue smp nm nonce_ rKeys dhKey auth subMode (queueReqData cqrd)
1384+
(thParams', ntfKeys, qik@QIK {rcvId, sndId, rcvPublicDhKey, queueMode, serviceId, serverNtfCreds}) <-
1385+
withClient c nm tSess $ \(SMPConnectedClient smp _) -> do
1386+
(ntfKeys, ntfCreds) <- liftIO $ mkNtfCreds a g smp
1387+
(thParams smp,ntfKeys,) <$> createSMPQueue smp nm nonce_ rKeys dhKey auth subMode (queueReqData cqrd) ntfCreds
13891388
-- TODO [certs rcv] validate that serviceId is the same as in the client session
13901389
liftIO . logServer "<--" c srv NoEntity $ B.unwords ["IDS", logSecret rcvId, logSecret sndId]
1391-
shortLink <- mkShortLinkCreds r
1390+
shortLink <- mkShortLinkCreds thParams' qik
13921391
let rq =
13931392
RcvQueue
13941393
{ userId,
@@ -1409,14 +1408,26 @@ newRcvQueue_ c nm userId connId (ProtoServerWithAuth srv auth) vRange cqrd subMo
14091408
dbReplaceQueueId = Nothing,
14101409
rcvSwchStatus = Nothing,
14111410
smpClientVersion = maxVersion vRange,
1412-
clientNtfCreds = Nothing,
1411+
clientNtfCreds = mkClientNtfCreds ntfKeys serverNtfCreds,
14131412
deleteErrors = 0
14141413
}
14151414
qUri = SMPQueueUri vRange $ SMPQueueAddress srv sndId e2eDhKey queueMode
14161415
pure (rq, qUri, tSess, sessionId thParams')
14171416
where
1418-
mkShortLinkCreds :: (THandleParams SMPVersion 'TClient, QueueIdsKeys) -> AM (Maybe ShortLinkCreds)
1419-
mkShortLinkCreds (thParams', QIK {sndId, queueMode, linkId}) = case (cqrd, queueMode) of
1417+
mkNtfCreds :: (C.AlgorithmI a, C.AuthAlgorithm a) => C.SAlgorithm a -> TVar ChaChaDRG -> SMPClient -> IO (Maybe (C.AAuthKeyPair, C.PrivateKeyX25519), Maybe NewNtfCreds)
1418+
mkNtfCreds a g smp
1419+
| enableNtfs && thVersion (thParams smp) >= newNtfCredsSMPVersion = do
1420+
authKeys@(k, _) <- atomically $ C.generateAuthKeyPair a g
1421+
(dhk, dhpk) <- atomically $ C.generateKeyPair g
1422+
pure (Just (authKeys, dhpk), Just $ NewNtfCreds k dhk)
1423+
| otherwise = pure (Nothing, Nothing)
1424+
mkClientNtfCreds :: Maybe (C.AAuthKeyPair, C.PrivateKeyX25519) -> Maybe ServerNtfCreds -> Maybe ClientNtfCreds
1425+
mkClientNtfCreds ntfKeys serverNtfCreds = case (ntfKeys, serverNtfCreds) of
1426+
(Just ((ntfPublicKey, ntfPrivateKey), dhpk), Just (ServerNtfCreds notifierId dhk')) ->
1427+
Just ClientNtfCreds {ntfPublicKey, ntfPrivateKey, notifierId, rcvNtfDhSecret = C.dh' dhk' dhpk}
1428+
_ -> Nothing
1429+
mkShortLinkCreds :: THandleParams SMPVersion 'TClient -> QueueIdsKeys -> AM (Maybe ShortLinkCreds)
1430+
mkShortLinkCreds thParams' QIK {sndId, queueMode, linkId} = case (cqrd, queueMode) of
14201431
(CQRMessaging ld, Just QMMessaging) ->
14211432
withLinkData ld $ \lnkId CQRData {linkKey, privSigKey, srvReq = (sndId', d)} ->
14221433
if sndId == sndId'
@@ -1807,7 +1818,7 @@ getQueueInfo c nm rq@RcvQueue {server, rcvId, rcvPrivateKey, sndId, status, clie
18071818
where
18081819
enc = decodeLatin1 . B64.encode . unEntityId
18091820

1810-
agentNtfRegisterToken :: AgentClient -> NetworkRequestMode -> NtfToken -> NtfPublicAuthKey -> C.PublicKeyX25519 -> AM (NtfTokenId, C.PublicKeyX25519)
1821+
agentNtfRegisterToken :: AgentClient -> NetworkRequestMode -> NtfToken -> SMP.NtfPublicAuthKey -> C.PublicKeyX25519 -> AM (NtfTokenId, C.PublicKeyX25519)
18111822
agentNtfRegisterToken c nm NtfToken {deviceToken, ntfServer, ntfPrivKey} ntfPubKey pubDhKey =
18121823
withClient c nm (0, ntfServer, Nothing) $ \ntf -> ntfRegisterToken ntf nm ntfPrivKey (NewNtfTkn deviceToken ntfPubKey pubDhKey)
18131824

src/Simplex/Messaging/Agent/Store/AgentStore.hs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,15 +1969,22 @@ insertRcvQueue_ db connId' rq@RcvQueue {..} serverKeyHash_ = do
19691969
INSERT INTO rcv_queues
19701970
( host, port, rcv_id, conn_id, rcv_private_key, rcv_dh_secret, e2e_priv_key, e2e_dh_secret,
19711971
snd_id, queue_mode, status, rcv_queue_id, rcv_primary, replace_rcv_queue_id, smp_client_version, server_key_hash,
1972-
link_id, link_key, link_priv_sig_key, link_enc_fixed_data
1973-
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);
1972+
link_id, link_key, link_priv_sig_key, link_enc_fixed_data,
1973+
ntf_public_key, ntf_private_key, ntf_id, rcv_ntf_dh_secret
1974+
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);
19741975
|]
19751976
( (host server, port server, rcvId, connId', rcvPrivateKey, rcvDhSecret, e2ePrivKey, e2eDhSecret)
19761977
:. (sndId, queueMode, status, qId, BI primary, dbReplaceQueueId, smpClientVersion, serverKeyHash_)
19771978
:. (shortLinkId <$> shortLink, shortLinkKey <$> shortLink, linkPrivSigKey <$> shortLink, linkEncFixedData <$> shortLink)
1979+
:. ntfCredsFields
19781980
)
19791981
-- TODO [certs rcv] save client service
19801982
pure (rq :: NewRcvQueue) {connId = connId', dbQueueId = qId, clientService = Nothing}
1983+
where
1984+
ntfCredsFields = case clientNtfCreds of
1985+
Just ClientNtfCreds {ntfPublicKey, ntfPrivateKey, notifierId, rcvNtfDhSecret} ->
1986+
(Just ntfPublicKey, Just ntfPrivateKey, Just notifierId, Just rcvNtfDhSecret)
1987+
Nothing -> (Nothing, Nothing, Nothing, Nothing)
19811988

19821989
-- * createSndConn helpers
19831990

src/Simplex/Messaging/Client.hs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -793,11 +793,10 @@ createSMPQueue ::
793793
Maybe BasicAuth ->
794794
SubscriptionMode ->
795795
QueueReqData ->
796-
-- TODO [notifications]
797-
-- Maybe NewNtfCreds ->
796+
Maybe NewNtfCreds ->
798797
ExceptT SMPClientError IO QueueIdsKeys
799-
createSMPQueue c nm nonce_ (rKey, rpKey) dhKey auth subMode qrd =
800-
sendProtocolCommand_ c nm nonce_ Nothing (Just rpKey) NoEntity (Cmd SCreator $ NEW $ NewQueueReq rKey dhKey auth subMode (Just qrd)) >>= \case
798+
createSMPQueue c nm nonce_ (rKey, rpKey) dhKey auth subMode qrd ntfCreds =
799+
sendProtocolCommand_ c nm nonce_ Nothing (Just rpKey) NoEntity (Cmd SCreator $ NEW $ NewQueueReq rKey dhKey auth subMode (Just qrd) ntfCreds) >>= \case
801800
IDS qik -> pure qik
802801
r -> throwE $ unexpectedResponse r
803802

0 commit comments

Comments
 (0)