Skip to content

Commit

Permalink
Merge branch 'wireapp:develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
offsoc authored Dec 24, 2024
2 parents 2edf49e + bbd8071 commit 49a3383
Show file tree
Hide file tree
Showing 25 changed files with 477 additions and 215 deletions.
27 changes: 27 additions & 0 deletions changelog.d/0-release-notes/WPB-15004
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
We changed the default MLS cipher suite from

- MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519

to

- MLS_128_DHKEMP256_AES128GCM_SHA256_P256

and the allowed MLS cipher suites from only

- MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519

to _only_

- MLS_128_DHKEMP256_AES128GCM_SHA256_P256.

ATTENTION: This breaks your MLS clients if they used the previous defaults
before. This is even true if you allow several cipher suites, since current MLS
clients only support _one_ cipher suite at a time.

[Adjust the defaults in the server
configuration](https://github.com/wireapp/wire-server/blob/develop/docs/src/developer/reference/config-options.md#mls)
to switch the values of `defaultCipherSuite` and `allowedCipherSuites` back to
the previous defaults, `1` and `[1]`, respectively. Once MLS clients support
several cipher suites, you could even use `[1,2]` or a list of other cipher
suites in `allowedCipherSuites`. Make sure that this list contains the currently
used cipher suite!
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Revive and translate old integration test.
4 changes: 2 additions & 2 deletions charts/galley/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
8 changes: 4 additions & 4 deletions docs/src/developer/reference/config-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,8 @@ mls:
protocolToggleUsers: []
defaultProtocol: mls
supportedProtocols: [proteus, mls] # must contain defaultProtocol
allowedCipherSuites: [1]
defaultCipherSuite: 1
allowedCipherSuites: [2]
defaultCipherSuite: 2
lockStatus: locked
```

Expand All @@ -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
Expand Down
23 changes: 18 additions & 5 deletions integration/test/API/Brig.hs
Original file line number Diff line number Diff line change
Expand Up @@ -358,16 +358,29 @@ countKeyPackages suite cid = do
req
& addQueryParams [("ciphersuite", suite.code)]

deleteKeyPackages :: ClientIdentity -> [String] -> App Response
deleteKeyPackages cid kps = do
deleteKeyPackages :: Ciphersuite -> ClientIdentity -> [String] -> App Response
deleteKeyPackages suite cid kps = do
req <- baseRequest cid Brig Versioned ("/mls/key-packages/self/" <> cid.client)
submit "DELETE" $ req & addJSONObject ["key_packages" .= kps]
submit "DELETE" $
req
& addQueryParams [("ciphersuite", suite.code)]
& addJSONObject ["key_packages" .= kps]

replaceKeyPackages :: ClientIdentity -> Maybe [Ciphersuite] -> [ByteString] -> App Response
replaceKeyPackages cid mSuites kps = do
replaceKeyPackages :: ClientIdentity -> [Ciphersuite] -> [ByteString] -> App Response
replaceKeyPackages cid suites kps = do
req <-
baseRequest cid Brig Versioned $
"/mls/key-packages/self/" <> cid.client
submit "PUT" $
req
& addQueryParams [("ciphersuites", intercalate "," (map (.code) suites))]
& addJSONObject ["key_packages" .= map (T.decodeUtf8 . Base64.encode) kps]

replaceKeyPackagesV7 :: ClientIdentity -> Maybe [Ciphersuite] -> [ByteString] -> App Response
replaceKeyPackagesV7 cid mSuites kps = do
req <-
baseRequest cid Brig (ExplicitVersion 7) $
"/mls/key-packages/self/" <> cid.client
submit "PUT" $
req
& maybe id (\suites -> addQueryParams [("ciphersuites", intercalate "," (map (.code) suites))]) mSuites
Expand Down
17 changes: 15 additions & 2 deletions integration/test/API/Galley.hs
Original file line number Diff line number Diff line change
Expand Up @@ -717,10 +717,23 @@ getTeamFeature user tid featureName = do
req <- baseRequest user Galley Versioned (joinHttpPath ["teams", tidStr, "features", featureName])
submit "GET" req

setTeamFeatureConfig :: (HasCallStack, MakesValue user, MakesValue team, MakesValue featureName, MakesValue payload) => user -> team -> featureName -> payload -> App Response
setTeamFeatureConfig ::
(HasCallStack, MakesValue user, MakesValue team, MakesValue featureName, MakesValue payload) =>
user ->
team ->
featureName ->
payload ->
App Response
setTeamFeatureConfig = setTeamFeatureConfigVersioned Versioned

setTeamFeatureConfigVersioned :: (HasCallStack, MakesValue user, MakesValue team, MakesValue featureName, MakesValue payload) => Versioned -> user -> team -> featureName -> payload -> App Response
setTeamFeatureConfigVersioned ::
(HasCallStack, MakesValue user, MakesValue team, MakesValue featureName, MakesValue payload) =>
Versioned ->
user ->
team ->
featureName ->
payload ->
App Response
setTeamFeatureConfigVersioned versioned user team featureName payload = do
tid <- asString team
fn <- asString featureName
Expand Down
16 changes: 14 additions & 2 deletions integration/test/API/GalleyInternal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,27 @@ generateVerificationCode' domain email = do
emailStr <- asString email
submit "POST" $ req & addJSONObject ["email" .= emailStr, "action" .= "login"]

setTeamFeatureConfig :: (HasCallStack, MakesValue domain, MakesValue team, MakesValue featureName, MakesValue payload) => domain -> team -> featureName -> payload -> App Response
setTeamFeatureConfig ::
(HasCallStack, MakesValue domain, MakesValue team, MakesValue featureName, MakesValue payload) =>
domain ->
team ->
featureName ->
payload ->
App Response
setTeamFeatureConfig domain team featureName payload = do
tid <- asString team
fn <- asString featureName
p <- make payload
req <- baseRequest domain Galley Unversioned $ joinHttpPath ["i", "teams", tid, "features", fn]
submit "PUT" $ req & addJSON p

patchTeamFeatureConfig :: (HasCallStack, MakesValue domain, MakesValue team, MakesValue featureName, MakesValue payload) => domain -> team -> featureName -> payload -> App Response
patchTeamFeatureConfig ::
(HasCallStack, MakesValue domain, MakesValue team, MakesValue featureName, MakesValue payload) =>
domain ->
team ->
featureName ->
payload ->
App Response
patchTeamFeatureConfig domain team featureName payload = do
tid <- asString team
fn <- asString featureName
Expand Down
17 changes: 13 additions & 4 deletions integration/test/MLS/Util.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -156,18 +156,27 @@ instance Default InitMLSClient where

-- | Create new mls client and register with backend.
createMLSClient :: (MakesValue u, HasCallStack) => Ciphersuite -> InitMLSClient -> u -> App ClientIdentity
createMLSClient ciphersuite opts u = do
createMLSClient ciphersuite = createMLSClientWithCiphersuites [ciphersuite]

-- | Create new mls client and register with backend.
createMLSClientWithCiphersuites :: (MakesValue u, HasCallStack) => [Ciphersuite] -> InitMLSClient -> u -> App ClientIdentity
createMLSClientWithCiphersuites ciphersuites opts u = do
cid <- createWireClient u opts.clientArgs
setClientGroupState cid def {credType = opts.credType}

-- set public key
pkey <- mlscli Nothing ciphersuite cid ["public-key"] Nothing
suitePKeys <- for ciphersuites $ \ciphersuite -> (ciphersuite,) <$> mlscli Nothing ciphersuite cid ["public-key"] Nothing
bindResponse
( updateClient
cid
def
{ mlsPublicKeys =
Just (object [csSignatureScheme ciphersuite .= T.decodeUtf8 (Base64.encode pkey)])
Just
( object
[ csSignatureScheme ciphersuite .= T.decodeUtf8 (Base64.encode pkey)
| (ciphersuite, pkey) <- suitePKeys
]
)
}
)
$ \resp -> resp.status `shouldMatchInt` 200
Expand Down
4 changes: 2 additions & 2 deletions integration/test/Test/FeatureFlags/Util.hs
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ defAllFeatures =
[ "protocolToggleUsers" .= ([] :: [String]),
"defaultProtocol" .= "proteus",
"supportedProtocols" .= ["proteus", "mls"],
"allowedCipherSuites" .= ([1] :: [Int]),
"defaultCipherSuite" .= A.Number 1
"allowedCipherSuites" .= ([2] :: [Int]),
"defaultCipherSuite" .= A.Number 2
]
],
"searchVisibilityInbound" .= disabled,
Expand Down
43 changes: 37 additions & 6 deletions integration/test/Test/LegalHold.hs
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,11 @@ testLHPreventAddingNonConsentingUsers v = do
m %. "qualified_id"
mems `shouldMatchSet` forM us (\m -> m %. "qualified_id")

testLHGetAndUpdateSettings :: (HasCallStack) => LhApiVersion -> App ()
testLHGetAndUpdateSettings v = do
testLHGetAndUpdateSettings :: (HasCallStack) => ImplicitConsent -> LhApiVersion -> App ()
testLHGetAndUpdateSettings implicitConsent v = ensureLHFeatureConfigForServer implicitConsent $ \dom -> do
withMockServer def (lhMockAppV v) $ \lhDomAndPort _chan -> do
(owner, tid, [alice]) <- createTeam OwnDomain 2
stranger <- randomUser OwnDomain def
(owner, tid, [alice]) <- createTeam dom 2
stranger <- randomUser dom def

let getSettingsWorks :: (HasCallStack) => Value -> String -> App ()
getSettingsWorks target status = bindResponse (getLegalHoldSettings tid target) $ \resp -> do
Expand All @@ -127,8 +127,13 @@ testLHGetAndUpdateSettings v = do
getSettingsWorks owner "disabled"
getSettingsWorks alice "disabled"

legalholdWhitelistTeam tid owner >>= assertSuccess
legalholdIsTeamInWhitelist tid owner >>= assertSuccess
case implicitConsent of
ImplicitConsent -> do
legalholdWhitelistTeam tid owner >>= assertSuccess
legalholdIsTeamInWhitelist tid owner >>= assertSuccess
ExplicitConsent -> do
let payload = object ["status" .= "enabled"] -- legalhold has implicit lock status "unlocked"
API.GalleyInternal.setTeamFeatureConfig dom tid "legalhold" payload >>= assertSuccess

getSettingsFails stranger
getSettingsWorks owner "not_configured"
Expand Down Expand Up @@ -1102,3 +1107,29 @@ testNoCommonVersion = do
bindResponse (requestLegalHoldDevice tid alice bob) $ \resp -> do
resp.status `shouldMatchInt` 500
resp.json %. "label" `shouldMatch` "server-error"

-- | LH can be configured in a way that does not require users to give preliminary consent to
-- LH when being added to a team. The user still has to approve the LH device before the
-- recording starts. This is called "implicit consent", was introduced to accomodate specific
-- work flows, and there is some hope that it'll be removed in the future.
--
-- Explicit consent requires users to consent on entering the team, and then approve the
-- actual being put under recording again if it happens.
--
-- This flag allows to make tests run through both configurations with minimal adjustment.
data ImplicitConsent = ImplicitConsent | ExplicitConsent
deriving (Eq, Show, Generic)

-- | Ensure that the LH config is as expected: Either by expecting it from the
-- current server's config. Or, by creating a new one.
ensureLHFeatureConfigForServer :: ImplicitConsent -> (String {- domain -} -> App ()) -> App ()
ensureLHFeatureConfigForServer ImplicitConsent app = do
-- This should be set in the server's config file. Thus, we only assert here
-- (to guard against accidential change.)
cfg <- readServiceConfig Galley
(cfg %. "settings.featureFlags.legalhold") `shouldMatch` "whitelist-teams-and-implicit-consent"
app =<< asString OwnDomain
ensureLHFeatureConfigForServer ExplicitConsent app =
withModifiedBackend (def {galleyCfg = upd}) app
where
upd = setField "settings.featureFlags.legalhold" "disabled-by-default"
Loading

0 comments on commit 49a3383

Please sign in to comment.