mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-10-06 22:57:20 +00:00
smp-server: reject corrId nonces of wrong size
This commit is contained in:
+48
-1
@@ -26,7 +26,7 @@ import qualified Data.List.NonEmpty as L
|
||||
import Data.Time.Clock (getCurrentTime)
|
||||
import SMPAgentClient
|
||||
import SMPClient
|
||||
import ServerTests (decryptMsgV3, sendRecv)
|
||||
import ServerTests (decryptMsgV3, sendRecv, wrongSizeCorrIds)
|
||||
import Simplex.Messaging.Agent hiding (createConnection, joinConnection, sendMessage)
|
||||
import qualified Simplex.Messaging.Agent as A
|
||||
import Simplex.Messaging.Agent.Env.SQLite (AgentConfig (..), InitialAgentServers (..))
|
||||
@@ -36,11 +36,13 @@ import Simplex.Messaging.Client
|
||||
import qualified Simplex.Messaging.Crypto as C
|
||||
import Simplex.Messaging.Crypto.Ratchet (pattern PQSupportOn)
|
||||
import qualified Simplex.Messaging.Crypto.Ratchet as CR
|
||||
import Simplex.Messaging.Encoding (smpEncode)
|
||||
import Simplex.Messaging.Protocol (EncRcvMsgBody (..), MsgBody, QueueReqData (..), RcvMessage (..), SubscriptionMode (..), maxMessageLength, noMsgFlags)
|
||||
import qualified Simplex.Messaging.Protocol as SMP
|
||||
import Simplex.Messaging.Server.Env.STM (AStoreType (..), ServerConfig (..))
|
||||
import Simplex.Messaging.Server.MsgStore.Types (SQSType (..))
|
||||
import Simplex.Messaging.Transport
|
||||
import qualified Simplex.Messaging.Transport.Client as TC
|
||||
import Simplex.Messaging.Util (bshow, tshow)
|
||||
import Simplex.Messaging.Version (mkVersionRange)
|
||||
import System.FilePath (splitExtensions)
|
||||
@@ -58,6 +60,9 @@ smpProxyTests = do
|
||||
describe "server configuration" $ do
|
||||
it "refuses proxy handshake unless enabled" testNoProxy
|
||||
it "checks basic auth in proxy requests" testProxyAuth
|
||||
describe "corrId used as nonce" $ do
|
||||
it "proxy rejects PFWD with corrId of wrong size" testPFWDCorrIdSize
|
||||
it "relay rejects RFWD with corrId of wrong size" testRFWDCorrIdSize
|
||||
describe "relay reconnection" $ do
|
||||
it "recovers when unresponsive relay restarts (control, no disconnect)" $ \_ ->
|
||||
testProxyRecoversWithoutDisconnect
|
||||
@@ -441,6 +446,48 @@ testProxyAuth msType = do
|
||||
where
|
||||
proxyCfgAuth = updateCfg (proxyCfgMS msType) $ \cfg_ -> cfg_ {newQueueBasicAuth = Just "correct"}
|
||||
|
||||
testPFWDCorrIdSize :: AStoreType -> IO ()
|
||||
testPFWDCorrIdSize msType =
|
||||
withSmpServerConfigOn (transport @TLS) (proxyCfgMS msType) testPort $ \_ ->
|
||||
testSMPClient_ "127.0.0.1" testPort supportedServerSMPRelayVRange Nothing $ \(th@THandle {params} :: THandleSMP TLS 'TClient) -> do
|
||||
g <- C.newRandom
|
||||
(cmdKey, _ :: C.PrivateKeyX25519) <- atomically $ C.generateKeyPair g
|
||||
let pfwd corrId = do
|
||||
(_, _, reply) <- sendRecv th (Nothing, corrId, SMP.EntityId "unknown session", SMP.PFWD (thVersion params) cmdKey $ SMP.EncTransmission "invalid")
|
||||
pure reply
|
||||
corrId <- atomically $ C.randomBytes 24 g
|
||||
pfwd corrId `shouldReturn` Right (SMP.ERR $ SMP.PROXY SMP.NO_SESSION)
|
||||
forM_ (wrongSizeCorrIds corrId) $ \badCorrId ->
|
||||
pfwd badCorrId `shouldReturn` Right (SMP.ERR $ SMP.CMD SMP.SYNTAX)
|
||||
|
||||
testRFWDCorrIdSize :: AStoreType -> IO ()
|
||||
testRFWDCorrIdSize msType =
|
||||
withSmpServerConfigOn (transport @TLS) (cfgMS msType) testPort2 $ \_ ->
|
||||
testProxyModeClient $ \th@THandle {params = THandleParams {thVersion, thAuth}} -> do
|
||||
Just THAuthClient {sessSecret = Just sessSecret} <- pure thAuth
|
||||
g <- C.newRandom
|
||||
(fwdKey, _ :: C.PrivateKeyX25519) <- atomically $ C.generateKeyPair g
|
||||
let rfwd corrId fwdCorrId = do
|
||||
let fwdT = SMP.FwdTransmission {fwdCorrId = SMP.CorrId fwdCorrId, fwdVersion = thVersion, fwdKey, fwdTransmission = SMP.EncTransmission "invalid"}
|
||||
eft = SMP.EncFwdTransmission $ C.cbEncryptNoPad sessSecret (C.cbNonce corrId) (smpEncode fwdT)
|
||||
(_, _, reply) <- sendRecv th (Nothing, corrId, NoEntity, SMP.RFWD eft)
|
||||
pure reply
|
||||
corrId <- atomically $ C.randomBytes 24 g
|
||||
fwdCorrId <- atomically $ C.randomBytes 24 g
|
||||
rfwd corrId fwdCorrId `shouldReturn` Right (SMP.ERR SMP.CRYPTO)
|
||||
forM_ (wrongSizeCorrIds corrId) $ \badCorrId -> do
|
||||
rfwd badCorrId fwdCorrId `shouldReturn` Right (SMP.ERR $ SMP.CMD SMP.SYNTAX)
|
||||
rfwd corrId badCorrId `shouldReturn` Right (SMP.ERR $ SMP.CMD SMP.SYNTAX)
|
||||
|
||||
-- Connect to the relay on testPort2 the same way the proxy does, with the session secret.
|
||||
testProxyModeClient :: (THandleSMP TLS 'TClient -> IO a) -> IO a
|
||||
testProxyModeClient client = do
|
||||
g <- C.newRandom
|
||||
ks <- atomically $ C.generateKeyPair g
|
||||
let tcConfig = TC.defaultTransportClientConfig {TC.clientALPN = Just alpnSupportedSMPHandshakes}
|
||||
TC.runTransportClient tcConfig Nothing "127.0.0.1" testPort2 (Just testKeyHash) $ \h ->
|
||||
runExceptT (smpClientHandshake h (Just ks) testKeyHash supportedClientSMPRelayVRange True Nothing) >>= either (fail . show) client
|
||||
|
||||
-- Connect a sender client to the proxy and request a relay session to testSMPServer2 (PRXY).
|
||||
-- On success the reply is PKEY; otherwise it is the proxy error for the relay connection.
|
||||
requestRelaySession :: IO (Either SMP.ErrorType SMP.BrokerMsg)
|
||||
|
||||
Reference in New Issue
Block a user