Skip to content

Commit

Permalink
Restore unsupported proposal test
Browse files Browse the repository at this point in the history
  • Loading branch information
pcapriotti committed May 2, 2023
1 parent 6d390fc commit a062b97
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 12 deletions.
27 changes: 23 additions & 4 deletions libs/wire-api/src/Wire/API/MLS/AuthenticatedContent.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

module Wire.API.MLS.AuthenticatedContent
( AuthenticatedContent (..),
TaggedSender (..),
authContentRef,
publicMessageRef,
mkSignedPublicMessage,
Expand All @@ -29,6 +30,7 @@ import Wire.API.MLS.CipherSuite
import Wire.API.MLS.Context
import Wire.API.MLS.Epoch
import Wire.API.MLS.Group
import Wire.API.MLS.LeafNode
import Wire.API.MLS.Message
import Wire.API.MLS.Proposal
import Wire.API.MLS.ProtocolVersion
Expand Down Expand Up @@ -64,16 +66,33 @@ authContentRef cs = ProposalRef . csHash cs proposalContext . mkRawMLS
publicMessageRef :: CipherSuiteTag -> PublicMessage -> ProposalRef
publicMessageRef cs = authContentRef cs . msgAuthContent

-- | Sender, plus with a membership tag in the case of a member sender.
data TaggedSender
= TaggedSenderMember LeafIndex ByteString
| TaggedSenderExternal Word32
| TaggedSenderNewMemberProposal
| TaggedSenderNewMemberCommit

taggedSenderToSender :: TaggedSender -> Sender
taggedSenderToSender (TaggedSenderMember i _) = SenderMember i
taggedSenderToSender (TaggedSenderExternal n) = SenderExternal n
taggedSenderToSender TaggedSenderNewMemberProposal = SenderNewMemberProposal
taggedSenderToSender TaggedSenderNewMemberCommit = SenderNewMemberCommit

taggedSenderMembershipTag :: TaggedSender -> Maybe ByteString
taggedSenderMembershipTag (TaggedSenderMember _ t) = Just t
taggedSenderMembershipTag _ = Nothing

-- | Craft a message with the backend itself as a sender. Return the message and its ref.
mkSignedPublicMessage ::
SecretKey -> PublicKey -> GroupId -> Epoch -> FramedContentData -> PublicMessage
mkSignedPublicMessage priv pub gid epoch payload =
SecretKey -> PublicKey -> GroupId -> Epoch -> TaggedSender -> FramedContentData -> PublicMessage
mkSignedPublicMessage priv pub gid epoch sender payload =
let framedContent =
mkRawMLS
FramedContent
{ groupId = gid,
epoch = epoch,
sender = SenderExternal 0,
sender = taggedSenderToSender sender,
content = payload,
authenticatedData = mempty
}
Expand All @@ -88,5 +107,5 @@ mkSignedPublicMessage priv pub gid epoch payload =
in PublicMessage
{ content = framedContent,
authData = mkRawMLS (FramedContentAuthData sig Nothing),
membershipTag = Nothing
membershipTag = taggedSenderMembershipTag sender
}
1 change: 1 addition & 0 deletions libs/wire-api/test/unit/Test/Wire/API/MLS.hs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ testRemoveProposalMessageSignature = withSystemTempDirectory "mls" $ \tmp -> do
publicKey
gid
(Epoch 1)
(TaggedSenderExternal 0)
(FramedContentProposal proposal)
message = mkMessage $ MessagePublic pmessage
messageFilename = "signed-message.mls"
Expand Down
2 changes: 1 addition & 1 deletion services/galley/src/Galley/API/MLS/Message.hs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ import Wire.API.MLS.SubConversation
-- [ ] restore deleted MLS unit tests
-- [x] pass groupId and epoch to processProposal instead of the whole IncomingMessage
-- [x] remove LWT in planMLSClientRemoval
-- [ ] restore unsupported proposal integration test
-- [x] restore unsupported proposal integration test

-- FUTUREWORK
-- - Check that the capabilities of a leaf node in an add proposal contains all
Expand Down
1 change: 1 addition & 0 deletions services/galley/src/Galley/API/MLS/Removal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ createAndSendRemoveProposals lConvOrSubConv indices qusr cm = do
pubKey
(cnvmlsGroupId meta)
(cnvmlsEpoch meta)
(TaggedSenderExternal 0)
(FramedContentProposal proposal)
msg = mkRawMLS (mkMessage (MessagePublic pmsg))
storeProposal
Expand Down
35 changes: 34 additions & 1 deletion services/galley/test/integration/API/MLS.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import Control.Exception (throw)
import Control.Lens (view)
import Control.Lens.Extras
import qualified Control.Monad.State as State
import Crypto.Error
import qualified Crypto.PubKey.Ed25519 as Ed25519
import qualified Data.Aeson as Aeson
import Data.Domain
import Data.Id
Expand Down Expand Up @@ -60,10 +62,12 @@ import Wire.API.Error.Galley
import Wire.API.Event.Conversation
import Wire.API.Federation.API.Common
import Wire.API.Federation.API.Galley
import Wire.API.MLS.AuthenticatedContent
import Wire.API.MLS.CipherSuite
import Wire.API.MLS.Credential
import Wire.API.MLS.Keys
import Wire.API.MLS.Message
import Wire.API.MLS.Proposal
import Wire.API.MLS.Serialisation
import Wire.API.MLS.SubConversation
import Wire.API.Message
Expand Down Expand Up @@ -1578,8 +1582,37 @@ testPublicKeys = do
)
@?= [Ed25519]

--- | The test manually reads from mls-test-cli's store and extracts a private
--- key. The key is needed for signing an unsupported proposal, which is then
-- forwarded by the backend without being inspected.
propUnsupported :: TestM ()
propUnsupported = pure () -- TODO (app ack does not exist anymore)
propUnsupported = do
users@[_alice, bob] <- createAndConnectUsers (replicate 2 Nothing)
runMLSTest $ do
[alice1, bob1] <- traverse createMLSClient users
void $ uploadNewKeyPackage bob1
(gid, _) <- setupMLSGroup alice1
void $ createAddCommit alice1 [bob] >>= sendAndConsumeCommitBundle

(priv, pub) <- clientKeyPair alice1
pmsg <-
liftIO . throwCryptoErrorIO $
mkSignedPublicMessage
<$> Ed25519.secretKey priv
<*> Ed25519.publicKey pub
<*> pure gid
<*> pure (Epoch 1)
<*> pure (TaggedSenderMember 0 "foo")
<*> pure
( FramedContentProposal
(mkRawMLS (GroupContextExtensionsProposal []))
)

let msg = mkMessage (MessagePublic pmsg)
let msgData = encodeMLS' msg

-- we cannot consume this message, because the membership tag is fake
postMessage alice1 msgData !!! const 201 === statusCode

testBackendRemoveProposalRecreateClient :: TestM ()
testBackendRemoveProposalRecreateClient = do
Expand Down
14 changes: 8 additions & 6 deletions services/galley/test/integration/API/MLS/Util.hs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import Control.Monad.Trans.Maybe
import Data.Aeson.Lens
import Data.Bifunctor
import Data.Binary.Builder (toLazyByteString)
import Data.Binary.Get
import qualified Data.ByteArray as BA
import qualified Data.ByteString as BS
import qualified Data.ByteString.Base64.URL as B64U
Expand Down Expand Up @@ -239,7 +240,8 @@ liftTest = MLSTest . lift

runMLSTest :: MLSTest a -> TestM a
runMLSTest (MLSTest m) =
withSystemTempDirectory "mls" $ \tmp -> do
withSystemTempDirectory "mls" $ \_tmp -> do
let tmp = "/tmp/mls"
saveRemovalKey (tmp </> "removal.key")
evalStateT
m
Expand Down Expand Up @@ -944,11 +946,11 @@ clientKeyPair cid = do
credential <-
liftIO . BS.readFile $
bd </> cid2Str cid </> "store" </> T.unpack (T.decodeUtf8 (B64U.encode "self"))
let s =
credential ^.. key "signature_private_key" . key "value" . _Array . traverse . _Integer
& fmap fromIntegral
& BS.pack
pure $ BS.splitAt 32 s
case runGetOrFail
((,) <$> parseMLSBytes @VarInt <*> parseMLSBytes @VarInt)
(LBS.fromStrict credential) of
Left (_, _, msg) -> liftIO $ assertFailure msg
Right (_, _, keys) -> pure keys

receiveNewRemoteConv ::
(MonadReader TestSetup m, MonadIO m) =>
Expand Down

0 comments on commit a062b97

Please sign in to comment.