@@ -35,6 +35,7 @@ import Data.String (IsString (..))
35
35
import Data.Type.Equality
36
36
import qualified Data.X509.Validation as XV
37
37
import GHC.Stack (withFrozenCallStack )
38
+ import qualified Network.TLS as TLS
38
39
import SMPClient
39
40
import qualified Simplex.Messaging.Crypto as C
40
41
import Simplex.Messaging.Encoding
@@ -49,6 +50,7 @@ import Simplex.Messaging.Server.MsgStore.Types (MsgStoreClass (..), SMSType (..)
49
50
import Simplex.Messaging.Server.Stats (PeriodStatsData (.. ), ServerStatsData (.. ))
50
51
import Simplex.Messaging.Server.StoreLog (StoreLogRecord (.. ), closeStoreLog )
51
52
import Simplex.Messaging.Transport
53
+ import Simplex.Messaging.Transport.Credentials
52
54
import Simplex.Messaging.Util (whenM )
53
55
import Simplex.Messaging.Version (mkVersionRange )
54
56
import System.Directory (doesDirectoryExist , doesFileExist , removeDirectoryRecursive , removeFile )
@@ -78,6 +80,8 @@ serverTests = do
78
80
describe " GET & SUB commands" testGetSubCommands
79
81
describe " Exceeding queue quota" testExceedQueueQuota
80
82
describe " Concurrent sending and delivery" testConcurrentSendDelivery
83
+ describe " Service message subscriptions" $ do
84
+ testServiceDeliverSubscribe
81
85
describe " Store log" testWithStoreLog
82
86
describe " Restore messages" testRestoreMessages
83
87
describe " Restore messages (old / v2)" testRestoreExpireMessages
@@ -104,6 +108,9 @@ pattern New rPub dhPub = NEW (NewQueueReq rPub dhPub Nothing SMSubscribe (Just (
104
108
pattern Ids :: RecipientId -> SenderId -> RcvPublicDhKey -> BrokerMsg
105
109
pattern Ids rId sId srvDh <- IDS (QIK rId sId srvDh _sndSecure _linkId Nothing Nothing )
106
110
111
+ pattern Ids_ :: RecipientId -> SenderId -> RcvPublicDhKey -> ServiceId -> BrokerMsg
112
+ pattern Ids_ rId sId srvDh serviceId <- IDS (QIK rId sId srvDh _sndSecure _linkId (Just serviceId) Nothing )
113
+
107
114
pattern Msg :: MsgId -> MsgBody -> BrokerMsg
108
115
pattern Msg msgId body <- MSG RcvMessage {msgId, msgBody = EncRcvMsgBody body}
109
116
@@ -129,10 +136,15 @@ serviceSignSendRecv h pk serviceKey t = do
129
136
pure r
130
137
131
138
signSendRecv_ :: forall c p . (Transport c , PartyI p ) => THandleSMP c 'TClient -> C. APrivateAuthKey -> Maybe C. PrivateKeyEd25519 -> (ByteString , EntityId , Command p ) -> IO (NonEmpty (Transmission (Either ErrorType BrokerMsg )))
132
- signSendRecv_ h@ THandle {params} (C. APrivateAuthKey a pk) serviceKey_ (corrId, qId, cmd) = do
139
+ signSendRecv_ h pk serviceKey_ t = do
140
+ signSend_ h pk serviceKey_ t
141
+ liftIO $ tGetClient h
142
+
143
+ signSend_ :: forall c p . (Transport c , PartyI p ) => THandleSMP c 'TClient -> C. APrivateAuthKey -> Maybe C. PrivateKeyEd25519 -> (ByteString , EntityId , Command p ) -> IO ()
144
+ signSend_ h@ THandle {params} (C. APrivateAuthKey a pk) serviceKey_ (corrId, qId, cmd) = do
133
145
let TransmissionForAuth {tForAuth, tToSend} = encodeTransmissionForAuth params (CorrId corrId, qId, cmd)
134
146
Right () <- tPut1 h (authorize tForAuth, tToSend)
135
- liftIO $ tGetClient h
147
+ pure ()
136
148
where
137
149
authorize t = (,(`C.sign'` t) <$> serviceKey_) <$> case a of
138
150
C. SEd25519 -> Just . TASignature . C. ASignature C. SEd25519 $ C. sign' pk t'
@@ -653,6 +665,68 @@ testConcurrentSendDelivery =
653
665
Resp " 4" _ OK <- signSendRecv rh rKey (" 4" , rId, ACK mId2)
654
666
pure ()
655
667
668
+ testServiceDeliverSubscribe :: SpecWith (ASrvTransport , AStoreType )
669
+ testServiceDeliverSubscribe =
670
+ it " " $ \ (at@ (ATransport t), msType) -> do
671
+ g <- C. newRandom
672
+ creds <- genCredentials g Nothing (0 , 2400 ) " localhost"
673
+ let (_fp, tlsCred) = tlsCredentials [creds]
674
+ serviceKeys@ (_, servicePK) <- atomically $ C. generateKeyPair g
675
+ let aServicePK = C. APrivateAuthKey C. SEd25519 servicePK
676
+ withSmpServerConfigOn at (cfgMS msType) testPort $ \ _ -> runClient t $ \ h -> do
677
+ (rPub, rKey) <- atomically $ C. generateAuthKeyPair C. SEd25519 g
678
+ (dhPub, dhPriv :: C. PrivateKeyX25519 ) <- atomically $ C. generateKeyPair g
679
+ (sPub, sKey) <- atomically $ C. generateAuthKeyPair C. SEd25519 g
680
+
681
+ (rId, sId, dec, serviceId) <- runServiceClient t (tlsCred, serviceKeys) $ \ sh -> do
682
+ Resp " 1" NoEntity (ERR SERVICE ) <- signSendRecv sh rKey (" 1" , NoEntity , New rPub dhPub)
683
+ Resp " 2" NoEntity (Ids_ rId sId srvDh serviceId) <- serviceSignSendRecv sh rKey servicePK (" 2" , NoEntity , New rPub dhPub)
684
+ let dec = decryptMsgV3 $ C. dh' srvDh dhPriv
685
+ Resp " 3" sId' OK <- signSendRecv h sKey (" 3" , sId, SKEY sPub)
686
+ sId' `shouldBe` sId
687
+ Resp " 4" _ OK <- signSendRecv h sKey (" 4" , sId, _SEND " hello" )
688
+ Resp " 5" _ OK <- signSendRecv h sKey (" 5" , sId, _SEND " hello 2" )
689
+ Resp " " rId' (Msg mId1 msg1) <- tGet1 sh
690
+ rId' `shouldBe` rId
691
+ dec mId1 msg1 `shouldBe` Right " hello"
692
+ -- ACK doesn't need service signature
693
+ Resp " 6" _ (Msg mId2 msg2) <- signSendRecv sh rKey (" 6" , rId, ACK mId1)
694
+ dec mId2 msg2 `shouldBe` Right " hello 2"
695
+ Resp " 7" _ (ERR NO_MSG ) <- signSendRecv sh rKey (" 7" , rId, ACK mId1)
696
+ Resp " 8" _ OK <- signSendRecv sh rKey (" 8" , rId, ACK mId2)
697
+ Resp " 9" _ OK <- signSendRecv h sKey (" 9" , sId, _SEND " hello 3" )
698
+ pure (rId, sId, dec, serviceId)
699
+
700
+ runServiceClient t (tlsCred, serviceKeys) $ \ sh -> do
701
+ Resp " 10" NoEntity (ERR (CMD NO_AUTH )) <- signSendRecv sh aServicePK (" 10" , NoEntity , SUBS )
702
+ mId3 <- signSendRecv sh aServicePK (" 11" , serviceId, SUBS ) >>= \ case -- possible race between SOKS response and MSG
703
+ Resp " 11" serviceId' (SOKS n) -> do
704
+ n `shouldBe` 1
705
+ serviceId' `shouldBe` serviceId
706
+ Resp " " rId'' (Msg mId3 msg3) <- tGet1 sh
707
+ rId'' `shouldBe` rId
708
+ dec mId3 msg3 `shouldBe` Right " hello 3"
709
+ pure mId3
710
+ Resp " " rId'' (Msg mId3 msg3) -> do
711
+ rId'' `shouldBe` rId
712
+ dec mId3 msg3 `shouldBe` Right " hello 3"
713
+ Resp " 11" serviceId' (SOKS n) <- tGet1 sh
714
+ n `shouldBe` 1
715
+ serviceId' `shouldBe` serviceId
716
+ pure mId3
717
+ r -> error $ " unexpected response " <> take 100 (show r)
718
+ Resp " 12" _ OK <- signSendRecv sh rKey (" 12" , rId, ACK mId3)
719
+ Resp " 14" _ OK <- signSendRecv h sKey (" 14" , sId, _SEND " hello 4" )
720
+ Resp " " _ (Msg mId4 msg4) <- tGet1 sh
721
+ dec mId4 msg4 `shouldBe` Right " hello 4"
722
+ Resp " 15" _ OK <- signSendRecv sh rKey (" 15" , rId, ACK mId4)
723
+ pure ()
724
+ where
725
+ runClient :: Transport c => TProxy c 'TServer -> (THandleSMP c 'TClient -> IO a ) -> IO a
726
+ runClient _ test' = testSMPClient test'
727
+ runServiceClient :: Transport c => TProxy c 'TServer -> (TLS. Credential , C. KeyPairEd25519 ) -> (THandleSMP c 'TClient -> IO a ) -> IO a
728
+ runServiceClient _ serviceCreds test' = testSMPServiceClient serviceCreds test'
729
+
656
730
testWithStoreLog :: SpecWith (ASrvTransport , AStoreType )
657
731
testWithStoreLog =
658
732
it " should store simplex queues to log and restore them after server restart" $ \ (at@ (ATransport t), msType) -> do
0 commit comments