Skip to content

Commit c2eb680

Browse files
authored
clients, servers: drop support of SMP protocol versions before 01/2025 (#1837)
* servers: drop support of versions before 01/2025 * fix agent tests * fix ntf tests * fix test * remove code for non-batched transmissions * fix batching test * fix ntf * comment
1 parent 7d0820d commit c2eb680

17 files changed

Lines changed: 199 additions & 650 deletions

File tree

src/Simplex/FileTransfer/Client.hs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,6 @@ data XFTPClientConfig = XFTPClientConfig
109109
clientALPN :: Maybe [ALPN]
110110
}
111111

112-
data XFTPChunkBody = XFTPChunkBody
113-
{ chunkSize :: Int,
114-
chunkPart :: Int -> IO ByteString,
115-
http2Body :: HTTP2Body
116-
}
117-
118112
data XFTPChunkSpec = XFTPChunkSpec
119113
{ filePath :: FilePath,
120114
chunkOffset :: Int64,
@@ -147,7 +141,7 @@ getXFTPClient transportSession@(_, srv, _) config@XFTPClientConfig {clientALPN,
147141
let HTTP2Client {sessionId, sessionALPN} = http2Client
148142
v = VersionXFTP 1
149143
thServerVRange = versionToRange v
150-
thParams0 = THandleParams {sessionId, blockSize = xftpBlockSize, thVersion = v, thServerVRange, thAuth = Nothing, implySessId = False, encryptBlock = Nothing, batch = True, serviceAuth = False}
144+
thParams0 = THandleParams {sessionId, blockSize = xftpBlockSize, thVersion = v, thServerVRange, thAuth = Nothing, implySessId = False, encryptBlock = Nothing, serviceAuth = False}
151145
logDebug $ "Client negotiated handshake protocol: " <> tshow sessionALPN
152146
thParams@THandleParams {thVersion} <- case sessionALPN of
153147
Just alpn

src/Simplex/FileTransfer/Server.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ xftpServer cfg@XFTPServerConfig {xftpPort, transportConfig, inactiveClientExpira
157157
reqBody <- getHTTP2Body r xftpBlockSize
158158
let v = VersionXFTP 1
159159
thServerVRange = versionToRange v
160-
thParams0 = THandleParams {sessionId, blockSize = xftpBlockSize, thVersion = v, thServerVRange, thAuth = Nothing, implySessId = False, encryptBlock = Nothing, batch = True, serviceAuth = False}
160+
thParams0 = THandleParams {sessionId, blockSize = xftpBlockSize, thVersion = v, thServerVRange, thAuth = Nothing, implySessId = False, encryptBlock = Nothing, serviceAuth = False}
161161
req0 = XFTPTransportRequest {thParams = thParams0, request = r, reqBody, sendResponse, sniUsed, addCORS = addCORS'}
162162
flip runReaderT env $ case sessionALPN of
163163
Nothing -> processRequest req0

src/Simplex/Messaging/Agent/Client.hs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ import Simplex.Messaging.Session
308308
import Simplex.Messaging.SystemTime
309309
import Simplex.Messaging.TMap (TMap)
310310
import qualified Simplex.Messaging.TMap as TM
311-
import Simplex.Messaging.Transport (HandshakeError (..), SMPServiceRole (..), SMPVersion, ServiceCredentials (..), SessionId, THClientService' (..), THandleAuth (..), THandleParams (sessionId, thAuth, thVersion), TransportError (..), TransportPeer (..), sndAuthKeySMPVersion, shortLinksSMPVersion, newNtfCredsSMPVersion)
311+
import Simplex.Messaging.Transport (HandshakeError (..), SMPServiceRole (..), SMPVersion, ServiceCredentials (..), SessionId, THClientService' (..), THandleAuth (..), THandleParams (sessionId, thAuth, thVersion), TransportError (..), TransportPeer (..), shortLinksSMPVersion, newNtfCredsSMPVersion)
312312
import Simplex.Messaging.Transport.Client (TransportHost (..))
313313
import Simplex.Messaging.Transport.Credentials
314314
import Simplex.Messaging.Util
@@ -1504,9 +1504,7 @@ newRcvQueue_ c nm userId connId (ProtoServerWithAuth srv auth) vRange cqrd enabl
15041504
if sndId == sndId' && lnkId == lnkId'
15051505
then pure $ Just $ ShortLinkCreds lnkId linkKey privSigKey Nothing (fst d)
15061506
else newErr "different sender or link IDs"
1507-
(_, Nothing) -> case linkId of
1508-
Nothing | v < sndAuthKeySMPVersion -> pure Nothing
1509-
_ -> newErr "unexpected link ID"
1507+
(_, Nothing) -> newErr "unexpected link ID"
15101508
_ -> newErr "unexpected queue mode"
15111509
where
15121510
v = thVersion thParams'

src/Simplex/Messaging/Client.hs

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,8 @@ smpClientStub g sessionId thVersion thAuth = do
227227
thServerVRange = supportedServerSMPRelayVRange,
228228
thAuth,
229229
blockSize = smpBlockSize,
230-
implySessId = thVersion >= authCmdsSMPVersion,
230+
implySessId = True,
231231
encryptBlock = Nothing,
232-
batch = True,
233232
serviceAuth = thVersion >= serviceCertsSMPVersion
234233
},
235234
sessionTs = ts,
@@ -1110,17 +1109,15 @@ deleteSMPQueues = okSMPCommands DEL
11101109
-- send PRXY :: SMPServer -> Maybe BasicAuth -> Command Sender
11111110
-- receives PKEY :: SessionId -> X.CertificateChain -> X.SignedExact X.PubKey -> BrokerMsg
11121111
connectSMPProxiedRelay :: SMPClient -> NetworkRequestMode -> SMPServer -> Maybe BasicAuth -> ExceptT SMPClientError IO ProxiedRelay
1113-
connectSMPProxiedRelay c@ProtocolClient {client_ = PClient {tcpConnectTimeout, tcpTimeout}} nm relayServ@ProtocolServer {port = relayPort, keyHash = C.KeyHash kh} proxyAuth
1114-
| thVersion (thParams c) >= sendingProxySMPVersion =
1115-
sendProtocolCommand_ c nm Nothing tOut Nothing NoEntity (Cmd SProxiedClient (PRXY relayServ proxyAuth)) >>= \case
1116-
PKEY sId vr (CertChainPubKey chain key) ->
1117-
case supportedClientSMPRelayVRange `compatibleVersion` vr of
1118-
Nothing -> throwE $ transportErr TEVersion
1119-
Just (Compatible v) -> do
1120-
relayKey <- liftEitherWith (const $ transportErr $ TEHandshake IDENTITY) =<< liftIO (runExceptT $ validateRelay chain key)
1121-
pure $ ProxiedRelay sId v proxyAuth relayKey
1122-
r -> throwE $ unexpectedResponse r
1123-
| otherwise = throwE $ PCETransportError TEVersion
1112+
connectSMPProxiedRelay c@ProtocolClient {client_ = PClient {tcpConnectTimeout, tcpTimeout}} nm relayServ@ProtocolServer {port = relayPort, keyHash = C.KeyHash kh} proxyAuth =
1113+
sendProtocolCommand_ c nm Nothing tOut Nothing NoEntity (Cmd SProxiedClient (PRXY relayServ proxyAuth)) >>= \case
1114+
PKEY sId vr (CertChainPubKey chain key) ->
1115+
case supportedClientSMPRelayVRange `compatibleVersion` vr of
1116+
Nothing -> throwE $ transportErr TEVersion
1117+
Just (Compatible v) -> do
1118+
relayKey <- liftEitherWith (const $ transportErr $ TEHandshake IDENTITY) =<< liftIO (runExceptT $ validateRelay chain key)
1119+
pure $ ProxiedRelay sId v proxyAuth relayKey
1120+
r -> throwE $ unexpectedResponse r
11241121
where
11251122
tOut = Just $ netTimeoutInt tcpConnectTimeout nm + netTimeoutInt tcpTimeout nm
11261123
transportErr = PCEProtocolError . PROXY . BROKER . TRANSPORT
@@ -1351,7 +1348,7 @@ sendProtocolCommand c nm = sendProtocolCommand_ c nm Nothing Nothing
13511348
--
13521349
-- Please note: if nonce is passed it is also used as a correlation ID
13531350
sendProtocolCommand_ :: forall v err msg. Protocol v err msg => ProtocolClient v err msg -> NetworkRequestMode -> Maybe C.CbNonce -> Maybe Int -> Maybe C.APrivateAuthKey -> EntityId -> ProtoCommand msg -> ExceptT (ProtocolClientError err) IO msg
1354-
sendProtocolCommand_ c@ProtocolClient {client_ = PClient {sndQ}, thParams = THandleParams {batch, blockSize, serviceAuth}} nm nonce_ tOut pKey entId cmd =
1351+
sendProtocolCommand_ c@ProtocolClient {client_ = PClient {sndQ}, thParams = THandleParams {blockSize, serviceAuth}} nm nonce_ tOut pKey entId cmd =
13551352
ExceptT $ uncurry sendRecv =<< mkTransmission_ c nonce_ (entId, pKey, cmd)
13561353
where
13571354
-- two separate "atomically" needed to avoid blocking
@@ -1364,9 +1361,7 @@ sendProtocolCommand_ c@ProtocolClient {client_ = PClient {sndQ}, thParams = THan
13641361
nonBlockingWriteTBQueue sndQ (Just r, s)
13651362
response <$> getResponse c nm tOut r
13661363
where
1367-
s
1368-
| batch = tEncodeBatch1 serviceAuth t
1369-
| otherwise = tEncode serviceAuth t
1364+
s = tEncodeBatch1 serviceAuth t
13701365

13711366
nonBlockingWriteTBQueue :: TBQueue a -> a -> IO ()
13721367
nonBlockingWriteTBQueue q x = do

src/Simplex/Messaging/Notifications/Protocol.hs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ import Simplex.Messaging.Agent.Store.DB (FromField (..), ToField (..), fromTextF
6161
import qualified Simplex.Messaging.Crypto as C
6262
import Simplex.Messaging.Encoding
6363
import Simplex.Messaging.Encoding.String
64-
import Simplex.Messaging.Notifications.Transport (NTFVersion, invalidReasonNTFVersion, ntfClientHandshake)
64+
import Simplex.Messaging.Notifications.Transport (NTFVersion, ntfClientHandshake)
6565
import Simplex.Messaging.Protocol hiding (Command (..), CommandTag (..))
6666
import Simplex.Messaging.Util (eitherToMaybe, (<$?>))
6767

@@ -329,18 +329,12 @@ data NtfResponse
329329

330330
instance ProtocolEncoding NTFVersion ErrorType NtfResponse where
331331
type Tag NtfResponse = NtfResponseTag
332-
encodeProtocol v = \case
332+
encodeProtocol _v = \case
333333
NRTknId entId dhKey -> e (NRTknId_, ' ', entId, dhKey)
334334
NRSubId entId -> e (NRSubId_, ' ', entId)
335335
NROk -> e NROk_
336336
NRErr err -> e (NRErr_, ' ', err)
337-
NRTkn stat -> e (NRTkn_, ' ', stat')
338-
where
339-
stat'
340-
| v >= invalidReasonNTFVersion = stat
341-
| otherwise = case stat of
342-
NTInvalid _ -> NTInvalid Nothing
343-
_ -> stat
337+
NRTkn stat -> e (NRTkn_, ' ', stat)
344338
NRSub stat -> e (NRSub_, ' ', stat)
345339
NRPong -> e NRPong_
346340
where

src/Simplex/Messaging/Notifications/Transport.hs

Lines changed: 18 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,15 @@ module Simplex.Messaging.Notifications.Transport
1212
VersionRangeNTF,
1313
pattern VersionNTF,
1414
THandleNTF,
15-
invalidReasonNTFVersion,
1615
supportedClientNTFVRange,
1716
supportedServerNTFVRange,
1817
alpnSupportedNTFHandshakes,
1918
ntfServerHandshake,
2019
ntfClientHandshake,
2120
) where
2221

23-
import Control.Monad (forM)
2422
import Control.Monad.Except
2523
import Control.Monad.Trans.Except
26-
import Data.Attoparsec.ByteString.Char8 (Parser)
27-
import Data.ByteString.Char8 (ByteString)
28-
import qualified Data.ByteString.Char8 as B
2924
import Data.Word (Word16)
3025
import qualified Data.X509 as X
3126
import qualified Simplex.Messaging.Crypto as C
@@ -50,13 +45,10 @@ pattern VersionNTF :: Word16 -> VersionNTF
5045
pattern VersionNTF v = Version v
5146

5247
initialNTFVersion :: VersionNTF
53-
initialNTFVersion = VersionNTF 1
48+
initialNTFVersion = VersionNTF 3
5449

55-
authBatchCmdsNTFVersion :: VersionNTF
56-
authBatchCmdsNTFVersion = VersionNTF 2
57-
58-
invalidReasonNTFVersion :: VersionNTF
59-
invalidReasonNTFVersion = VersionNTF 3
50+
_invalidReasonNTFVersion :: VersionNTF
51+
_invalidReasonNTFVersion = VersionNTF 3
6052

6153
currentClientNTFVersion :: VersionNTF
6254
currentClientNTFVersion = VersionNTF 3
@@ -67,9 +59,6 @@ currentServerNTFVersion = VersionNTF 3
6759
supportedClientNTFVRange :: VersionRangeNTF
6860
supportedClientNTFVRange = mkVersionRange initialNTFVersion currentClientNTFVersion
6961

70-
legacyServerNTFVRange :: VersionRangeNTF
71-
legacyServerNTFVRange = mkVersionRange initialNTFVersion initialNTFVersion
72-
7362
supportedServerNTFVRange :: VersionRangeNTF
7463
supportedServerNTFVRange = mkVersionRange initialNTFVersion currentServerNTFVersion
7564

@@ -82,7 +71,7 @@ data NtfServerHandshake = NtfServerHandshake
8271
{ ntfVersionRange :: VersionRangeNTF,
8372
sessionId :: SessionId,
8473
-- pub key to agree shared secrets for command authorization and entity ID encryption.
85-
authPubKey :: Maybe (X.SignedExact X.PubKey)
74+
authPubKey :: X.SignedExact X.PubKey
8675
}
8776

8877
data NtfClientHandshake = NtfClientHandshake
@@ -94,25 +83,13 @@ data NtfClientHandshake = NtfClientHandshake
9483

9584
instance Encoding NtfServerHandshake where
9685
smpEncode NtfServerHandshake {ntfVersionRange, sessionId, authPubKey} =
97-
B.concat
98-
[ smpEncode (ntfVersionRange, sessionId),
99-
encodeAuthEncryptCmds (maxVersion ntfVersionRange) $ C.SignedObject <$> authPubKey
100-
]
86+
smpEncode (ntfVersionRange, sessionId, C.SignedObject authPubKey)
10187

10288
smpP = do
10389
(ntfVersionRange, sessionId) <- smpP
104-
-- TODO drop SMP v6: remove special parser and make key non-optional
105-
authPubKey <- authEncryptCmdsP (maxVersion ntfVersionRange) $ C.getSignedExact <$> smpP
90+
authPubKey <- C.getSignedExact <$> smpP
10691
pure NtfServerHandshake {ntfVersionRange, sessionId, authPubKey}
10792

108-
encodeAuthEncryptCmds :: Encoding a => VersionNTF -> Maybe a -> ByteString
109-
encodeAuthEncryptCmds v k
110-
| v >= authBatchCmdsNTFVersion = maybe "" smpEncode k
111-
| otherwise = ""
112-
113-
authEncryptCmdsP :: VersionNTF -> Parser a -> Parser (Maybe a)
114-
authEncryptCmdsP v p = if v >= authBatchCmdsNTFVersion then Just <$> p else pure Nothing
115-
11693
instance Encoding NtfClientHandshake where
11794
smpEncode NtfClientHandshake {ntfVersion, keyHash} =
11895
smpEncode (ntfVersion, keyHash)
@@ -122,11 +99,10 @@ instance Encoding NtfClientHandshake where
12299

123100
-- | Notifcations server transport handshake.
124101
ntfServerHandshake :: forall c. Transport c => C.APrivateSignKey -> c 'TServer -> C.KeyPairX25519 -> C.KeyHash -> VersionRangeNTF -> ExceptT TransportError IO (THandleNTF c 'TServer)
125-
ntfServerHandshake serverSignKey c (k, pk) kh ntfVRange = do
102+
ntfServerHandshake serverSignKey c (k, pk) kh ntfVersionRange = do
126103
let th@THandle {params = THandleParams {sessionId}} = ntfTHandle c
127-
let sk = C.signX509 serverSignKey $ C.publicToX509 k
128-
let ntfVersionRange = maybe legacyServerNTFVRange (const ntfVRange) $ getSessionALPN c
129-
sendHandshake th $ NtfServerHandshake {sessionId, ntfVersionRange, authPubKey = Just sk}
104+
authPubKey = C.signX509 serverSignKey $ C.publicToX509 k
105+
sendHandshake th $ NtfServerHandshake {sessionId, ntfVersionRange, authPubKey}
130106
getHandshake th >>= \case
131107
NtfClientHandshake {ntfVersion = v, keyHash}
132108
| keyHash /= kh ->
@@ -140,36 +116,35 @@ ntfServerHandshake serverSignKey c (k, pk) kh ntfVRange = do
140116
ntfClientHandshake :: forall c. Transport c => c 'TClient -> C.KeyHash -> VersionRangeNTF -> Bool -> Maybe (ServiceCredentials, C.KeyPairEd25519) -> ExceptT TransportError IO (THandleNTF c 'TClient)
141117
ntfClientHandshake c keyHash ntfVRange _proxyServer _serviceKeys = do
142118
let th@THandle {params = THandleParams {sessionId}} = ntfTHandle c
143-
NtfServerHandshake {sessionId = sessId, ntfVersionRange, authPubKey = sk'} <- getHandshake th
119+
NtfServerHandshake {sessionId = sessId, ntfVersionRange, authPubKey} <- getHandshake th
144120
if sessionId /= sessId
145121
then throwE TEBadSession
146122
else case ntfVersionRange `compatibleVRange` ntfVRange of
147123
Just (Compatible vr) -> do
148-
ck_ <- forM sk' $ \signedKey -> liftEitherWith (const $ TEHandshake BAD_AUTH) $ do
124+
ck <- liftEitherWith (const $ TEHandshake BAD_AUTH) $ do
149125
serverKey <- getServerVerifyKey c
150-
pubKey <- C.verifyX509 serverKey signedKey
151-
(,CertChainPubKey (getPeerCertChain c) signedKey) <$> C.x509ToPublic' pubKey
126+
pubKey <- C.verifyX509 serverKey authPubKey
127+
(,CertChainPubKey (getPeerCertChain c) authPubKey) <$> C.x509ToPublic' pubKey
152128
let v = maxVersion vr
153129
sendHandshake th $ NtfClientHandshake {ntfVersion = v, keyHash}
154-
pure $ ntfThHandleClient th v vr ck_
130+
pure $ ntfThHandleClient th v vr ck
155131
Nothing -> throwE TEVersion
156132

157133
ntfThHandleServer :: forall c. THandleNTF c 'TServer -> VersionNTF -> VersionRangeNTF -> C.PrivateKeyX25519 -> THandleNTF c 'TServer
158134
ntfThHandleServer th v vr pk =
159135
let thAuth = THAuthServer {serverPrivKey = pk, peerClientService = Nothing, sessSecret' = Nothing}
160136
in ntfThHandle_ th v vr (Just thAuth)
161137

162-
ntfThHandleClient :: forall c. THandleNTF c 'TClient -> VersionNTF -> VersionRangeNTF -> Maybe (C.PublicKeyX25519, CertChainPubKey) -> THandleNTF c 'TClient
138+
ntfThHandleClient :: forall c. THandleNTF c 'TClient -> VersionNTF -> VersionRangeNTF -> (C.PublicKeyX25519, CertChainPubKey) -> THandleNTF c 'TClient
163139
ntfThHandleClient th v vr ck_ =
164-
let thAuth = clientTHParams <$> ck_
140+
let thAuth = Just $ clientTHParams ck_
165141
clientTHParams (k, ck) = THAuthClient {peerServerPubKey = k, peerServerCertKey = ck, clientService = Nothing, sessSecret = Nothing}
166142
in ntfThHandle_ th v vr thAuth
167143

168144
ntfThHandle_ :: forall c p. THandleNTF c p -> VersionNTF -> VersionRangeNTF -> Maybe (THandleAuth p) -> THandleNTF c p
169145
ntfThHandle_ th@THandle {params} v vr thAuth =
170146
-- TODO drop SMP v6: make thAuth non-optional
171-
let v3 = v >= authBatchCmdsNTFVersion
172-
params' = params {thVersion = v, thServerVRange = vr, thAuth, implySessId = v3, batch = v3}
147+
let params' = params {thVersion = v, thServerVRange = vr, thAuth}
173148
in (th :: THandleNTF c p) {params = params'}
174149

175150
ntfTHandle :: Transport c => c p -> THandleNTF c p
@@ -183,8 +158,7 @@ ntfTHandle c = THandle {connection = c, params}
183158
thVersion = v,
184159
thServerVRange = versionToRange v,
185160
thAuth = Nothing,
186-
implySessId = False,
161+
implySessId = True,
187162
encryptBlock = Nothing,
188-
batch = False,
189163
serviceAuth = False
190164
}

0 commit comments

Comments
 (0)