From 9c641fed9171311bc559740499d0dfaa49bcbaa5 Mon Sep 17 00:00:00 2001 From: brenzi Date: Sat, 3 Oct 2026 16:10:42 +0200 Subject: [PATCH] reject e2e params with kem_ct and without kem_key (#1901) --- src/Simplex/Messaging/Crypto/Ratchet.hs | 12 ++++++++---- tests/AgentTests/ConnectionRequestTests.hs | 5 +++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Simplex/Messaging/Crypto/Ratchet.hs b/src/Simplex/Messaging/Crypto/Ratchet.hs index b38f2b5d1..fe74d772a 100644 --- a/src/Simplex/Messaging/Crypto/Ratchet.hs +++ b/src/Simplex/Messaging/Crypto/Ratchet.hs @@ -119,7 +119,7 @@ import Simplex.Messaging.Crypto.SNTRUP761.Bindings import Simplex.Messaging.Encoding import Simplex.Messaging.Encoding.String import Simplex.Messaging.Parsers (defaultJSON, parseE, parseE') -import Simplex.Messaging.Util (($>>=), (<$?>)) +import Simplex.Messaging.Util ((<$?>)) import Simplex.Messaging.Version import Simplex.Messaging.Version.Internal import UnliftIO.STM @@ -327,9 +327,13 @@ instance StrEncoding AnyE2ERatchetParamsUri where Nothing -> pure $ AnyE2ERatchetParamsUri SRKSProposed a $ E2ERatchetParamsUri vr k1 k2 Nothing _ -> fail "bad e2e params" where - kemP query = - queryParam_ "kem_key" query - $>>= \k -> Just . kemParams k <$> queryParam_ "kem_ct" query + kemP query = do + k_ <- queryParam_ "kem_key" query + ct_ <- queryParam_ "kem_ct" query + case (k_, ct_) of + (Just k, _) -> pure $ Just $ kemParams k ct_ + (Nothing, Nothing) -> pure Nothing + (Nothing, Just _) -> fail "bad e2e params: kem_ct without kem_key" kemParams k = \case Nothing -> ARKP SRKSProposed $ RKParamsProposed k Just ct -> ARKP SRKSAccepted $ RKParamsAccepted ct k diff --git a/tests/AgentTests/ConnectionRequestTests.hs b/tests/AgentTests/ConnectionRequestTests.hs index c3b255139..d76d8d305 100644 --- a/tests/AgentTests/ConnectionRequestTests.hs +++ b/tests/AgentTests/ConnectionRequestTests.hs @@ -20,6 +20,8 @@ module AgentTests.ConnectionRequestTests import AgentTests.EqInstances () import Data.ByteString (ByteString) +import qualified Data.ByteString.Char8 as B +import Data.Either (isLeft) import Network.HTTP.Types (urlEncode) import Simplex.Messaging.Agent.Protocol import qualified Simplex.Messaging.Crypto as C @@ -285,6 +287,9 @@ connectionRequestTests = contactAddressV6 #== ("https://simplex.chat/contact#/?v=1-2&smp=" <> url queueStr) -- adjusted to v6 contactAddressV6 #== ("https://simplex.chat/contact#/?v=2-2&smp=" <> url queueStr) contactAddressClientData #==# ("simplex:/contact#/?v=6-8&smp=" <> url queueStr <> "&data=" <> url "{\"type\":\"group_link\", \"group_link_id\":\"abc\"}") + it "should reject KEM ciphertext without KEM key in e2e params" $ + strDecode @(RcvE2ERatchetParamsUri 'C.X448) (strEncode testE2ERatchetParams <> "&kem_ct=" <> strEncode (B.replicate 1039 '\0')) + `shouldSatisfy` isLeft it "should serialize / parse queue address, connection invitations and contact addresses as binary" $ do smpEncodingTest queue smpEncodingTest queueNoQM -- this passes, no queue mode patch in SMPQueueUri encoding