diff --git a/charts/galley/values.yaml b/charts/galley/values.yaml index 60122db2c23..45d4cbc94a5 100644 --- a/charts/galley/values.yaml +++ b/charts/galley/values.yaml @@ -115,8 +115,8 @@ config: config: protocolToggleUsers: [] defaultProtocol: proteus - allowedCipherSuites: [1] - defaultCipherSuite: 1 + allowedCipherSuites: [2] + defaultCipherSuite: 2 supportedProtocols: [proteus, mls] # must contain defaultProtocol lockStatus: unlocked searchVisibilityInbound: diff --git a/docs/src/developer/reference/config-options.md b/docs/src/developer/reference/config-options.md index 41748ebc3ba..a4a95005572 100644 --- a/docs/src/developer/reference/config-options.md +++ b/docs/src/developer/reference/config-options.md @@ -300,8 +300,8 @@ mls: protocolToggleUsers: [] defaultProtocol: mls supportedProtocols: [proteus, mls] # must contain defaultProtocol - allowedCipherSuites: [1] - defaultCipherSuite: 1 + allowedCipherSuites: [2] + defaultCipherSuite: 2 lockStatus: locked ``` @@ -316,8 +316,8 @@ mls: protocolToggleUsers: [] defaultProtocol: mls supportedProtocols: [proteus, mls] # must contain defaultProtocol - allowedCipherSuites: [1] - defaultCipherSuite: 1 + allowedCipherSuites: [2] + defaultCipherSuite: 2 ``` ### MLS End-to-End Identity diff --git a/integration/test/MLS/Util.hs b/integration/test/MLS/Util.hs index e70fa74d259..68e9fcb3a12 100644 --- a/integration/test/MLS/Util.hs +++ b/integration/test/MLS/Util.hs @@ -90,7 +90,7 @@ mlscli mConvId cs cid args mbstdin = do liftIO (createDirectory (bd cid2Str cid)) `catch` \e -> if (isAlreadyExistsError e) - then assertFailure "client directory for mls state already exists" + then pure () -- creates a file per signature scheme else throwM e -- initialise new keystore diff --git a/integration/test/Test/MLS.hs b/integration/test/Test/MLS.hs index 856f480e983..7c1ab6e88ab 100644 --- a/integration/test/Test/MLS.hs +++ b/integration/test/Test/MLS.hs @@ -390,7 +390,7 @@ testAddUserSimple suite ctype = do -- epoch and ciphersuite, regardless of the API version n <- awaitMatch isConvCreateNotif ws n %. "payload.0.data.epoch" `shouldMatchInt` 0 - n %. "payload.0.data.cipher_suite" `shouldMatchInt` 1 + n %. "payload.0.data.cipher_suite" `shouldMatchInt` 2 pure qcnv resp <- createAddCommit alice1 qcnv [bob] >>= sendAndConsumeCommitBundle @@ -516,7 +516,7 @@ testSelfConversation v = withVersion5 v $ do convId <- objConvId conv conv %. "epoch" `shouldMatchInt` 0 case v of - Version5 -> conv %. "cipher_suite" `shouldMatchInt` 1 + Version5 -> conv %. "cipher_suite" `shouldMatchInt` 2 NoVersion5 -> assertFieldMissing conv "cipher_suite" void $ createAddCommit creator convId [alice] >>= sendAndConsumeCommitBundle diff --git a/integration/test/Test/MLS/KeyPackage.hs b/integration/test/Test/MLS/KeyPackage.hs index 2c49f0206d7..830b1889720 100644 --- a/integration/test/Test/MLS/KeyPackage.hs +++ b/integration/test/Test/MLS/KeyPackage.hs @@ -11,9 +11,10 @@ import Testlib.Prelude testDeleteKeyPackages :: App () testDeleteKeyPackages = do + let suite = Ciphersuite "0x0001" alice <- randomUser OwnDomain def - alice1 <- createMLSClient def def alice - kps <- replicateM 3 (uploadNewKeyPackage def alice1) + alice1 <- createMLSClient suite def alice + kps <- replicateM 3 (uploadNewKeyPackage suite alice1) -- add an extra non-existing key package to the delete request let kps' = "4B701F521EBE82CEC4AD5CB67FDD8E1C43FC4868DE32D03933CE4993160B75E8" : kps @@ -27,26 +28,30 @@ testDeleteKeyPackages = do testKeyPackageMultipleCiphersuites :: App () testKeyPackageMultipleCiphersuites = do + let suite = Ciphersuite "0x0001" alice <- randomUser OwnDomain def - [alice1, alice2] <- replicateM 2 (createMLSClient def def alice) + [alice1, alice2] <- replicateM 2 (createMLSClient suite def alice) - kp <- uploadNewKeyPackage def alice2 + kp <- uploadNewKeyPackage suite alice2 - let suite = Ciphersuite "0xf031" - void $ uploadNewKeyPackage suite alice2 + -- Using 0xf031 as the alternative for 0x0001 is possible without creating a + -- new signature key for this client, since both cipher suites share the same + -- signature scheme. + let altSuite = Ciphersuite "0xf031" + void $ uploadNewKeyPackage altSuite alice2 - -- count key packages with default ciphersuite - bindResponse (countKeyPackages def alice2) $ \resp -> do + -- count key packages with the client's default ciphersuite + bindResponse (countKeyPackages suite alice2) $ \resp -> do resp.status `shouldMatchInt` 200 resp.json %. "count" `shouldMatchInt` 1 - -- claim key packages with default ciphersuite - bindResponse (claimKeyPackages def alice1 alice) $ \resp -> do + -- claim key packages with the client's default ciphersuite + bindResponse (claimKeyPackages suite alice1 alice) $ \resp -> do resp.status `shouldMatchInt` 200 resp.json %. "key_packages.0.key_package_ref" `shouldMatch` kp -- count key package with the other ciphersuite - bindResponse (countKeyPackages suite alice2) $ \resp -> do + bindResponse (countKeyPackages altSuite alice2) $ \resp -> do resp.status `shouldMatchInt` 200 resp.json %. "count" `shouldMatchInt` 1 @@ -207,9 +212,10 @@ testUnsupportedCiphersuite = do testReplaceKeyPackages :: (HasCallStack) => App () testReplaceKeyPackages = do + let suite = Ciphersuite "0x0001" + altSuite = Ciphersuite "0xf031" alice <- randomUser OwnDomain def - [alice1, alice2] <- replicateM 2 $ createMLSClient def def alice - let suite = Ciphersuite "0xf031" + [alice1, alice2] <- replicateM 2 $ createMLSClient suite def alice let checkCount cs n = bindResponse (countKeyPackages cs alice1) $ \resp -> do @@ -218,31 +224,31 @@ testReplaceKeyPackages = do -- setup: upload a batch of key packages for each ciphersuite void - $ replicateM 4 (fmap fst (generateKeyPackage alice1 def)) + $ replicateM 4 (fmap fst (generateKeyPackage alice1 suite)) >>= uploadKeyPackages alice1 >>= getBody 201 void - $ replicateM 5 (fmap fst (generateKeyPackage alice1 suite)) + $ replicateM 5 (fmap fst (generateKeyPackage alice1 altSuite)) >>= uploadKeyPackages alice1 >>= getBody 201 - checkCount def 4 - checkCount suite 5 + checkCount suite 4 + checkCount altSuite 5 do -- generate a new batch of key packages - (kps, refs) <- unzip <$> replicateM 3 (generateKeyPackage alice1 suite) + (kps, refs) <- unzip <$> replicateM 3 (generateKeyPackage alice1 altSuite) -- replace old key packages with new - void $ replaceKeyPackages alice1 (Just [suite]) kps >>= getBody 201 + void $ replaceKeyPackages alice1 (Just [altSuite]) kps >>= getBody 201 - checkCount def 4 - checkCount suite 3 + checkCount suite 4 + checkCount altSuite 3 -- claim all key packages one by one claimed <- replicateM 3 - $ bindResponse (claimKeyPackages suite alice2 alice) + $ bindResponse (claimKeyPackages altSuite alice2 alice) $ \resp -> do resp.status `shouldMatchInt` 200 ks <- resp.json %. "key_packages" & asList @@ -251,31 +257,31 @@ testReplaceKeyPackages = do refs `shouldMatchSet` claimed - checkCount def 4 - checkCount suite 0 + checkCount suite 4 + checkCount altSuite 0 do -- replenish key packages for the second ciphersuite void - $ replicateM 5 (fmap fst (generateKeyPackage alice1 suite)) + $ replicateM 5 (fmap fst (generateKeyPackage alice1 altSuite)) >>= uploadKeyPackages alice1 >>= getBody 201 - checkCount def 4 - checkCount suite 5 + checkCount suite 4 + checkCount altSuite 5 -- replace all key packages with fresh ones - kps1 <- replicateM 2 (fmap fst (generateKeyPackage alice1 def)) - kps2 <- replicateM 2 (fmap fst (generateKeyPackage alice1 suite)) + kps1 <- replicateM 2 (fmap fst (generateKeyPackage alice1 suite)) + kps2 <- replicateM 2 (fmap fst (generateKeyPackage alice1 altSuite)) - void $ replaceKeyPackages alice1 (Just [def, suite]) (kps1 <> kps2) >>= getBody 201 + void $ replaceKeyPackages alice1 (Just [suite, altSuite]) (kps1 <> kps2) >>= getBody 201 - checkCount def 2 checkCount suite 2 + checkCount altSuite 2 do - defKeyPackages <- replicateM 3 (fmap fst (generateKeyPackage alice1 def)) suiteKeyPackages <- replicateM 3 (fmap fst (generateKeyPackage alice1 suite)) + altSuiteKeyPackages <- replicateM 3 (fmap fst (generateKeyPackage alice1 altSuite)) void $ replaceKeyPackages alice1 (Just []) [] @@ -283,12 +289,12 @@ testReplaceKeyPackages = do resp.status `shouldMatchInt` 201 void - $ replaceKeyPackages alice1 Nothing defKeyPackages + $ replaceKeyPackages alice1 Nothing suiteKeyPackages `bindResponse` \resp -> do resp.status `shouldMatchInt` 201 - checkCount def 3 - checkCount suite 2 + checkCount suite 3 + checkCount altSuite 2 let testErrorCases :: (HasCallStack) => Maybe [Ciphersuite] -> [ByteString] -> App () testErrorCases ciphersuites keyPackages = do @@ -297,19 +303,19 @@ testReplaceKeyPackages = do `bindResponse` \resp -> do resp.status `shouldMatchInt` 400 resp.json %. "label" `shouldMatch` "mls-protocol-error" - checkCount def 3 - checkCount suite 2 + checkCount suite 3 + checkCount altSuite 2 - testErrorCases (Just []) defKeyPackages testErrorCases (Just []) suiteKeyPackages + testErrorCases (Just []) altSuiteKeyPackages testErrorCases Nothing [] - testErrorCases Nothing suiteKeyPackages - testErrorCases Nothing (suiteKeyPackages <> defKeyPackages) + testErrorCases Nothing altSuiteKeyPackages + testErrorCases Nothing (altSuiteKeyPackages <> suiteKeyPackages) - testErrorCases (Just [suite]) defKeyPackages - testErrorCases (Just [suite]) (suiteKeyPackages <> defKeyPackages) - testErrorCases (Just [suite]) [] + testErrorCases (Just [altSuite]) suiteKeyPackages + testErrorCases (Just [altSuite]) (altSuiteKeyPackages <> suiteKeyPackages) + testErrorCases (Just [altSuite]) [] - testErrorCases (Just [def]) suiteKeyPackages - testErrorCases (Just [def]) (suiteKeyPackages <> defKeyPackages) - testErrorCases (Just [def]) [] + testErrorCases (Just [suite]) altSuiteKeyPackages + testErrorCases (Just [suite]) (altSuiteKeyPackages <> suiteKeyPackages) + testErrorCases (Just [suite]) [] diff --git a/integration/test/Test/MLS/One2One.hs b/integration/test/Test/MLS/One2One.hs index 660368b7660..55678db4c60 100644 --- a/integration/test/Test/MLS/One2One.hs +++ b/integration/test/Test/MLS/One2One.hs @@ -39,7 +39,7 @@ testGetMLSOne2OneLocalV5 = withVersion5 Version5 $ do [alice, bob] <- createAndConnectUsers [OwnDomain, OwnDomain] let assertConvData conv = do conv %. "epoch" `shouldMatchInt` 0 - conv %. "cipher_suite" `shouldMatchInt` 1 + conv %. "cipher_suite" `shouldMatchInt` 2 convId <- getMLSOne2OneConversationLegacy alice bob `bindResponse` \resp -> do diff --git a/integration/test/Testlib/Types.hs b/integration/test/Testlib/Types.hs index f7f20c36782..85ea37fa4dd 100644 --- a/integration/test/Testlib/Types.hs +++ b/integration/test/Testlib/Types.hs @@ -249,7 +249,7 @@ newtype Ciphersuite = Ciphersuite {code :: String} deriving (Eq, Ord, Show, Generic) instance Default Ciphersuite where - def = Ciphersuite "0x0001" + def = Ciphersuite "0x0002" data ClientGroupState = ClientGroupState { groups :: Map ConvId ByteString, diff --git a/libs/wire-api-federation/src/Wire/API/Federation/API/Brig.hs b/libs/wire-api-federation/src/Wire/API/Federation/API/Brig.hs index 9d099271406..e135d8c2c01 100644 --- a/libs/wire-api-federation/src/Wire/API/Federation/API/Brig.hs +++ b/libs/wire-api-federation/src/Wire/API/Federation/API/Brig.hs @@ -144,14 +144,14 @@ mlsClientsRequestToV0 :: MLSClientsRequest -> MLSClientsRequestV0 mlsClientsRequestToV0 mcr = MLSClientsRequestV0 { userId = mcr.userId, - signatureScheme = Ed25519 + signatureScheme = Ecdsa_secp256r1_sha256 } mlsClientsRequestFromV0 :: MLSClientsRequestV0 -> MLSClientsRequest mlsClientsRequestFromV0 mcr = MLSClientsRequest { userId = mcr.userId, - cipherSuite = tagCipherSuite MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 + cipherSuite = tagCipherSuite MLS_128_DHKEMP256_AES128GCM_SHA256_P256 } -- NOTE: ConversationId for remote connections diff --git a/libs/wire-api-federation/test/golden/testObject_GetOne2OneConversationResponseOk.json b/libs/wire-api-federation/test/golden/testObject_GetOne2OneConversationResponseOk.json index dbfa3343671..032447a6c4e 100644 --- a/libs/wire-api-federation/test/golden/testObject_GetOne2OneConversationResponseOk.json +++ b/libs/wire-api-federation/test/golden/testObject_GetOne2OneConversationResponseOk.json @@ -28,7 +28,7 @@ "type": 2 }, "protocol": { - "cipher_suite": 1, + "cipher_suite": 2, "epoch": 0, "epoch_timestamp": null, "group_id": "Z3JvdXA=", diff --git a/libs/wire-api/src/Wire/API/Conversation/Protocol.hs b/libs/wire-api/src/Wire/API/Conversation/Protocol.hs index ef4be957f28..67cb09d2e4b 100644 --- a/libs/wire-api/src/Wire/API/Conversation/Protocol.hs +++ b/libs/wire-api/src/Wire/API/Conversation/Protocol.hs @@ -109,7 +109,7 @@ optionalActiveMLSConversationDataSchema (Just v) schema <*> fmap (.epochTimestamp) .= field "epoch_timestamp" (named "EpochTimestamp" . nullable . unnamed $ utcTimeSchema) - <*> maybe MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 (.ciphersuite) + <*> maybe MLS_128_DHKEMP256_AES128GCM_SHA256_P256 (.ciphersuite) .= fieldWithDocModifier "cipher_suite" (description ?~ "The cipher suite of the corresponding MLS group") diff --git a/libs/wire-api/src/Wire/API/MLS/CipherSuite.hs b/libs/wire-api/src/Wire/API/MLS/CipherSuite.hs index 5f93d01f8c3..4723621b887 100644 --- a/libs/wire-api/src/Wire/API/MLS/CipherSuite.hs +++ b/libs/wire-api/src/Wire/API/MLS/CipherSuite.hs @@ -21,6 +21,7 @@ module Wire.API.MLS.CipherSuite ( -- * MLS ciphersuites CipherSuite (..), defCipherSuite, + defCipherSuiteV7, CipherSuiteTag (..), cipherSuiteTag, tagCipherSuite, @@ -122,7 +123,13 @@ data CipherSuiteTag deriving (Arbitrary) via (GenericUniform CipherSuiteTag) defCipherSuite :: CipherSuiteTag -defCipherSuite = MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 +defCipherSuite = MLS_128_DHKEMP256_AES128GCM_SHA256_P256 + +-- | default cipher suite as of wire-server 5.8 +-- This cipher suite is used for backward-compatibility in endpoints which did +-- not support choosing the cipher suite in a query parameter from the start. +defCipherSuiteV7 :: CipherSuiteTag +defCipherSuiteV7 = MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 instance S.ToSchema CipherSuiteTag where declareNamedSchema _ = diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs b/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs index a554f2aeba9..37a85d41a0b 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs @@ -1358,7 +1358,7 @@ type CipherSuiteParam = QueryParam' [ Optional, Strict, - Description "Ciphersuite in hex format (e.g. 0xf031) - default is 0x0001" + Description "Ciphersuite in hex format (e.g. 0xf031) - default is 0x0002" ] "ciphersuite" CipherSuite @@ -1367,7 +1367,7 @@ type MultipleCipherSuitesParam = QueryParam' [ Optional, Strict, - Description "Comma-separated list of ciphersuites in hex format (e.g. 0xf031) - default is 0x0001" + Description "Comma-separated list of ciphersuites in hex format (e.g. 0xf031) - default is 0x0002" ] "ciphersuites" (CommaSeparatedList CipherSuite) diff --git a/libs/wire-api/src/Wire/API/Team/Feature.hs b/libs/wire-api/src/Wire/API/Team/Feature.hs index 533bbd8837f..493aaa384a4 100644 --- a/libs/wire-api/src/Wire/API/Team/Feature.hs +++ b/libs/wire-api/src/Wire/API/Team/Feature.hs @@ -113,7 +113,7 @@ import Test.QuickCheck (getPrintableString) import Test.QuickCheck.Arbitrary (arbitrary) import Test.QuickCheck.Gen (suchThat) import Wire.API.Conversation.Protocol -import Wire.API.MLS.CipherSuite (CipherSuiteTag (MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519)) +import Wire.API.MLS.CipherSuite import Wire.API.Routes.Named import Wire.Arbitrary (Arbitrary, GenericUniform (..)) @@ -925,8 +925,8 @@ instance Default MLSConfig where MLSConfig [] ProtocolProteusTag - [MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519] - MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 + [MLS_128_DHKEMP256_AES128GCM_SHA256_P256] + MLS_128_DHKEMP256_AES128GCM_SHA256_P256 [ProtocolProteusTag, ProtocolMLSTag] instance ToSchema MLSConfig where diff --git a/libs/wire-api/test/golden/testObject_Conversation_v2_user_4.json b/libs/wire-api/test/golden/testObject_Conversation_v2_user_4.json index cda477d4510..8eab7834e96 100644 --- a/libs/wire-api/test/golden/testObject_Conversation_v2_user_4.json +++ b/libs/wire-api/test/golden/testObject_Conversation_v2_user_4.json @@ -19,7 +19,7 @@ "guest", "service" ], - "cipher_suite": 1, + "cipher_suite": 2, "creator": "00000000-0000-0000-0000-000200000001", "epoch": 0, "epoch_timestamp": null, diff --git a/libs/wire-api/test/golden/testObject_Conversation_v5_user_4.json b/libs/wire-api/test/golden/testObject_Conversation_v5_user_4.json index e7351a003ce..6ea55d98066 100644 --- a/libs/wire-api/test/golden/testObject_Conversation_v5_user_4.json +++ b/libs/wire-api/test/golden/testObject_Conversation_v5_user_4.json @@ -18,7 +18,7 @@ "guest", "service" ], - "cipher_suite": 1, + "cipher_suite": 2, "creator": "00000000-0000-0000-0000-000200000001", "epoch": 0, "epoch_timestamp": null, diff --git a/libs/wire-api/test/golden/testObject_PublicSubConversation_v5_2.json b/libs/wire-api/test/golden/testObject_PublicSubConversation_v5_2.json index a918c3161ba..edde0bc7c60 100644 --- a/libs/wire-api/test/golden/testObject_PublicSubConversation_v5_2.json +++ b/libs/wire-api/test/golden/testObject_PublicSubConversation_v5_2.json @@ -1,5 +1,5 @@ { - "cipher_suite": 1, + "cipher_suite": 2, "epoch": 0, "epoch_timestamp": null, "group_id": "dGVzdF9ncm91cF8y", diff --git a/services/brig/src/Brig/API/MLS/CipherSuite.hs b/services/brig/src/Brig/API/MLS/CipherSuite.hs index c47bd0fedaa..226cf272705 100644 --- a/services/brig/src/Brig/API/MLS/CipherSuite.hs +++ b/services/brig/src/Brig/API/MLS/CipherSuite.hs @@ -33,14 +33,14 @@ getOneCipherSuite s = (cipherSuiteTag s) getCipherSuite :: Maybe CipherSuite -> Handler r CipherSuiteTag -getCipherSuite = maybe (pure defCipherSuite) getOneCipherSuite +getCipherSuite = maybe (pure defCipherSuiteV7) getOneCipherSuite validateCipherSuites :: Maybe [CipherSuite] -> KeyPackageUpload -> Handler r (Set CipherSuiteTag) validateCipherSuites suites upload = do - suitesQuery <- Set.fromList <$> maybe (pure [defCipherSuite]) (traverse getOneCipherSuite) suites + suitesQuery <- Set.fromList <$> maybe (pure [defCipherSuiteV7]) (traverse getOneCipherSuite) suites when (any isNothing suitesKPM) . void $ mlsProtocolError "uploaded key packages contains unsupported cipher suite" unless (suitesQuery == suitesKP) . void $ mlsProtocolError "uploaded key packages for unannounced cipher suites" pure suitesQuery