diff --git a/libs/wire-api/src/Wire/API/MLS/AuthenticatedContent.hs b/libs/wire-api/src/Wire/API/MLS/AuthenticatedContent.hs index 8efa64193bd..d941b69efa1 100644 --- a/libs/wire-api/src/Wire/API/MLS/AuthenticatedContent.hs +++ b/libs/wire-api/src/Wire/API/MLS/AuthenticatedContent.hs @@ -35,7 +35,8 @@ import Wire.API.MLS.Proposal import Wire.API.MLS.ProtocolVersion import Wire.API.MLS.Serialisation --- Needed to compute proposal refs. +-- | Needed to compute proposal refs. +-- https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-6-7 data AuthenticatedContent = AuthenticatedContent { wireFormat :: WireFormatTag, content :: RawMLS FramedContent, diff --git a/libs/wire-api/src/Wire/API/MLS/Capabilities.hs b/libs/wire-api/src/Wire/API/MLS/Capabilities.hs index bfbb07cc2b4..64386ef72e3 100644 --- a/libs/wire-api/src/Wire/API/MLS/Capabilities.hs +++ b/libs/wire-api/src/Wire/API/MLS/Capabilities.hs @@ -26,6 +26,7 @@ import Wire.API.MLS.ProtocolVersion import Wire.API.MLS.Serialisation import Wire.Arbitrary +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-7.2-2 data Capabilities = Capabilities { versions :: [ProtocolVersion], ciphersuites :: [CipherSuite], diff --git a/libs/wire-api/src/Wire/API/MLS/CipherSuite.hs b/libs/wire-api/src/Wire/API/MLS/CipherSuite.hs index 483a113426f..c1b4d00da1b 100644 --- a/libs/wire-api/src/Wire/API/MLS/CipherSuite.hs +++ b/libs/wire-api/src/Wire/API/MLS/CipherSuite.hs @@ -116,11 +116,13 @@ csVerifySignature MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 pub x sig = sig' <- Ed25519.signature sig pure $ Ed25519.verify pub' x.rmRaw sig' +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-5.2-5 type RefHashInput = SignContent pattern RefHashInput :: ByteString -> RawMLS a -> RefHashInput a pattern RefHashInput label content = SignContent label content +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-5.1.2-6 data SignContent a = SignContent { sigLabel :: ByteString, content :: RawMLS a diff --git a/libs/wire-api/src/Wire/API/MLS/Commit.hs b/libs/wire-api/src/Wire/API/MLS/Commit.hs index b130a6036c8..83cb4277ad4 100644 --- a/libs/wire-api/src/Wire/API/MLS/Commit.hs +++ b/libs/wire-api/src/Wire/API/MLS/Commit.hs @@ -23,6 +23,7 @@ import Wire.API.MLS.Proposal import Wire.API.MLS.Serialisation import Wire.Arbitrary +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-12.4-3 data Commit = Commit { cProposals :: [ProposalOrRef], cPath :: Maybe UpdatePath @@ -41,6 +42,7 @@ instance SerialiseMLS Commit where serialiseMLSVector @VarInt serialiseMLS c.cProposals serialiseMLSOptional serialiseMLS c.cPath +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-7.6-2 data UpdatePath = UpdatePath { upLeaf :: RawMLS LeafNode, upNodes :: [UpdatePathNode] @@ -56,6 +58,7 @@ instance SerialiseMLS UpdatePath where serialiseMLS up.upLeaf serialiseMLSVector @VarInt serialiseMLS up.upNodes +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-7.6-2 data UpdatePathNode = UpdatePathNode { upnPublicKey :: ByteString, upnSecret :: [HPKECiphertext] @@ -71,6 +74,7 @@ instance SerialiseMLS UpdatePathNode where serialiseMLSBytes @VarInt upn.upnPublicKey serialiseMLSVector @VarInt serialiseMLS upn.upnSecret +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-7.6-2 data HPKECiphertext = HPKECiphertext { hcOutput :: ByteString, hcCiphertext :: ByteString diff --git a/libs/wire-api/src/Wire/API/MLS/Credential.hs b/libs/wire-api/src/Wire/API/MLS/Credential.hs index 12a3da5b6dc..0ec9d8d3a23 100644 --- a/libs/wire-api/src/Wire/API/MLS/Credential.hs +++ b/libs/wire-api/src/Wire/API/MLS/Credential.hs @@ -47,6 +47,7 @@ import Wire.Arbitrary -- | An MLS credential. -- -- Only the @BasicCredential@ type is supported. +-- https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-5.3-3 data Credential = BasicCredential ByteString deriving stock (Eq, Show, Generic) deriving (Arbitrary) via GenericUniform Credential diff --git a/libs/wire-api/src/Wire/API/MLS/Extension.hs b/libs/wire-api/src/Wire/API/MLS/Extension.hs index 3c060f6fc42..c40c99ce1d4 100644 --- a/libs/wire-api/src/Wire/API/MLS/Extension.hs +++ b/libs/wire-api/src/Wire/API/MLS/Extension.hs @@ -26,6 +26,7 @@ import Imports import Wire.API.MLS.Serialisation import Wire.Arbitrary +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-7.2-2 data Extension = Extension { extType :: Word16, extData :: ByteString diff --git a/libs/wire-api/src/Wire/API/MLS/GroupInfo.hs b/libs/wire-api/src/Wire/API/MLS/GroupInfo.hs index f563a0818b4..77cf2036627 100644 --- a/libs/wire-api/src/Wire/API/MLS/GroupInfo.hs +++ b/libs/wire-api/src/Wire/API/MLS/GroupInfo.hs @@ -36,6 +36,7 @@ import Wire.API.MLS.ProtocolVersion import Wire.API.MLS.Serialisation import Wire.Arbitrary +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-8.1-2 data GroupContext = GroupContext { protocolVersion :: ProtocolVersion, cipherSuite :: CipherSuite, @@ -69,6 +70,7 @@ instance SerialiseMLS GroupContext where serialiseMLSBytes @VarInt gc.confirmedTranscriptHash serialiseMLSVector @VarInt serialiseMLS gc.extensions +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-12.4.3-7 data GroupInfoTBS = GroupInfoTBS { groupContext :: GroupContext, extensions :: [Extension], @@ -93,6 +95,7 @@ instance SerialiseMLS GroupInfoTBS where serialiseMLSBytes @VarInt tbs.confirmationTag serialiseMLS tbs.signer +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-12.4.3-2 data GroupInfo = GroupInfo { tbs :: GroupInfoTBS, signature_ :: ByteString diff --git a/libs/wire-api/src/Wire/API/MLS/HPKEPublicKey.hs b/libs/wire-api/src/Wire/API/MLS/HPKEPublicKey.hs index 004ed3443d8..3d0d947f083 100644 --- a/libs/wire-api/src/Wire/API/MLS/HPKEPublicKey.hs +++ b/libs/wire-api/src/Wire/API/MLS/HPKEPublicKey.hs @@ -23,6 +23,7 @@ import Imports import Test.QuickCheck import Wire.API.MLS.Serialisation +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-5.1.1-2 newtype HPKEPublicKey = HPKEPublicKey {unHPKEPublicKey :: ByteString} deriving (Show, Eq, Arbitrary) diff --git a/libs/wire-api/src/Wire/API/MLS/KeyPackage.hs b/libs/wire-api/src/Wire/API/MLS/KeyPackage.hs index 4a426a7c5d6..dd7ad72cbc6 100644 --- a/libs/wire-api/src/Wire/API/MLS/KeyPackage.hs +++ b/libs/wire-api/src/Wire/API/MLS/KeyPackage.hs @@ -157,6 +157,7 @@ kpRef' kp = -------------------------------------------------------------------------------- +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-10-6 data KeyPackageTBS = KeyPackageTBS { protocolVersion :: ProtocolVersion, cipherSuite :: CipherSuite, @@ -184,6 +185,7 @@ instance SerialiseMLS KeyPackageTBS where serialiseMLS tbs.leafNode serialiseMLSVector @VarInt serialiseMLS tbs.extensions +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-10-6 data KeyPackage = KeyPackage { tbs :: RawMLS KeyPackageTBS, signature_ :: ByteString diff --git a/libs/wire-api/src/Wire/API/MLS/LeafNode.hs b/libs/wire-api/src/Wire/API/MLS/LeafNode.hs index 064a6c2e55b..6e0d15cef43 100644 --- a/libs/wire-api/src/Wire/API/MLS/LeafNode.hs +++ b/libs/wire-api/src/Wire/API/MLS/LeafNode.hs @@ -44,6 +44,8 @@ import Wire.Arbitrary type LeafIndex = Word32 -- LeafNodeCore contains fields in the intersection of LeafNode and LeafNodeTBS +-- +-- https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-7.2-2 data LeafNodeCore = LeafNodeCore { encryptionKey :: HPKEPublicKey, signatureKey :: ByteString, @@ -56,6 +58,8 @@ data LeafNodeCore = LeafNodeCore deriving (Arbitrary) via (GenericUniform LeafNodeCore) -- extra fields in LeafNodeTBS, but not in LeafNode +-- +-- https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-7.2-2 data LeafNodeTBSExtra = LeafNodeTBSExtraKeyPackage | LeafNodeTBSExtraUpdate GroupId LeafIndex @@ -76,6 +80,7 @@ instance HasField "tag" LeafNodeTBSExtra LeafNodeSourceTag where LeafNodeTBSExtraCommit _ _ -> LeafNodeSourceCommitTag LeafNodeTBSExtraUpdate _ _ -> LeafNodeSourceUpdateTag +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-7.2-2 data LeafNodeTBS = LeafNodeTBS { core :: RawMLS LeafNodeCore, extra :: LeafNodeTBSExtra @@ -107,6 +112,8 @@ instance SerialiseMLS LeafNodeCore where -- | This type can only verify the signature when the LeafNodeSource is -- LeafNodeSourceKeyPackage +-- +-- https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-7.2-2 data LeafNode = LeafNode { core :: RawMLS LeafNodeCore, signature_ :: ByteString @@ -146,6 +153,7 @@ instance HasField "source" LeafNode LeafNodeSource where instance HasField "extensions" LeafNode [Extension] where getField = (.core.rmValue.extensions) +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-7.2-2 data LeafNodeSource = LeafNodeSourceKeyPackage Lifetime | LeafNodeSourceUpdate diff --git a/libs/wire-api/src/Wire/API/MLS/Lifetime.hs b/libs/wire-api/src/Wire/API/MLS/Lifetime.hs index 8a05ce1c42a..0f17c2978d4 100644 --- a/libs/wire-api/src/Wire/API/MLS/Lifetime.hs +++ b/libs/wire-api/src/Wire/API/MLS/Lifetime.hs @@ -31,6 +31,7 @@ newtype Timestamp = Timestamp {timestampSeconds :: Word64} tsPOSIX :: Timestamp -> POSIXTime tsPOSIX = fromIntegral . timestampSeconds +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-7.2-2 data Lifetime = Lifetime { ltNotBefore :: Timestamp, ltNotAfter :: Timestamp diff --git a/libs/wire-api/src/Wire/API/MLS/Message.hs b/libs/wire-api/src/Wire/API/MLS/Message.hs index a98e24f1ddf..bdd2f93f483 100644 --- a/libs/wire-api/src/Wire/API/MLS/Message.hs +++ b/libs/wire-api/src/Wire/API/MLS/Message.hs @@ -80,6 +80,7 @@ instance ParseMLS WireFormatTag where instance SerialiseMLS WireFormatTag where serialiseMLS = serialiseMLSEnum @Word16 +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-6-4 data Message = Message { protocolVersion :: ProtocolVersion, content :: MessageContent @@ -103,6 +104,7 @@ instance SerialiseMLS Message where instance HasField "wireFormat" Message WireFormatTag where getField = (.content.wireFormat) +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-6-4 data MessageContent = MessagePrivate (RawMLS PrivateMessage) | MessagePublic PublicMessage @@ -147,10 +149,12 @@ instance SerialiseMLS MessageContent where instance S.ToSchema Message where declareNamedSchema _ = pure (mlsSwagger "MLSMessage") +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-6.2-2 data PublicMessage = PublicMessage { content :: RawMLS FramedContent, authData :: RawMLS FramedContentAuthData, -- Present iff content.rmValue.sender is of type Member. + -- https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-6.2-4 membershipTag :: Maybe ByteString } deriving (Eq, Show) @@ -175,6 +179,7 @@ instance SerialiseMLS PublicMessage where serialiseMLS msg.authData traverse_ (serialiseMLSBytes @VarInt) msg.membershipTag +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-6.3.1-2 data PrivateMessage = PrivateMessage { groupId :: GroupId, epoch :: Epoch, @@ -195,6 +200,7 @@ instance ParseMLS PrivateMessage where <*> parseMLSBytes @VarInt <*> parseMLSBytes @VarInt +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-6-4 data SenderTag = SenderMemberTag | SenderExternalTag @@ -208,6 +214,7 @@ instance ParseMLS SenderTag where instance SerialiseMLS SenderTag where serialiseMLS = serialiseMLSEnum @Word8 +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-6-4 data Sender = SenderMember LeafIndex | SenderExternal Word32 @@ -241,6 +248,7 @@ needsGroupContext (SenderMember _) = True needsGroupContext (SenderExternal _) = True needsGroupContext _ = False +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-6-4 data FramedContent = FramedContent { groupId :: GroupId, epoch :: Epoch, @@ -279,6 +287,7 @@ instance ParseMLS FramedContentDataTag where instance SerialiseMLS FramedContentDataTag where serialiseMLS = serialiseMLSEnum @Word8 +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-6-4 data FramedContentData = FramedContentApplicationData ByteString | FramedContentProposal (RawMLS Proposal) @@ -309,6 +318,7 @@ instance SerialiseMLS FramedContentData where serialiseMLS FramedContentCommitTag serialiseMLS commit +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-6.1-2 data FramedContentTBS = FramedContentTBS { protocolVersion :: ProtocolVersion, wireFormat :: WireFormatTag, @@ -333,6 +343,7 @@ framedContentTBS ctx msgContent = groupContext = guard (needsGroupContext msgContent.rmValue.sender) $> ctx } +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-6.1-2 data FramedContentAuthData = FramedContentAuthData { signature_ :: ByteString, -- Present iff it is part of a commit. diff --git a/libs/wire-api/src/Wire/API/MLS/Proposal.hs b/libs/wire-api/src/Wire/API/MLS/Proposal.hs index 887114318da..0745c20938c 100644 --- a/libs/wire-api/src/Wire/API/MLS/Proposal.hs +++ b/libs/wire-api/src/Wire/API/MLS/Proposal.hs @@ -37,6 +37,7 @@ import Wire.API.MLS.ProtocolVersion import Wire.API.MLS.Serialisation import Wire.Arbitrary +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-12.1-2 data Proposal = AddProposal (RawMLS KeyPackage) | UpdateProposal (RawMLS LeafNode) @@ -92,6 +93,7 @@ instance SerialiseMLS Proposal where serialiseMLS GroupContextExtensionsProposalTag serialiseMLSVector @VarInt serialiseMLS es +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-8.4-6 data PreSharedKeyTag = ExternalKeyTag | ResumptionKeyTag deriving (Bounded, Enum, Eq, Show) @@ -101,6 +103,7 @@ instance ParseMLS PreSharedKeyTag where instance SerialiseMLS PreSharedKeyTag where serialiseMLS = serialiseMLSEnum @Word8 +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-8.4-6 data PreSharedKeyID = ExternalKeyID ByteString | ResumptionKeyID Resumption deriving stock (Eq, Show, Generic) deriving (Arbitrary) via (GenericUniform PreSharedKeyID) @@ -120,6 +123,7 @@ instance SerialiseMLS PreSharedKeyID where serialiseMLS ResumptionKeyTag serialiseMLS r +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-8.4-6 data Resumption = Resumption { resUsage :: Word8, resGroupId :: GroupId, @@ -141,6 +145,7 @@ instance SerialiseMLS Resumption where serialiseMLS r.resGroupId serialiseMLS r.resEpoch +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-12.1.5-2 data ReInit = ReInit { riGroupId :: GroupId, riProtocolVersion :: ProtocolVersion, diff --git a/libs/wire-api/src/Wire/API/MLS/ProtocolVersion.hs b/libs/wire-api/src/Wire/API/MLS/ProtocolVersion.hs index 9fcbb718470..9d8a0220682 100644 --- a/libs/wire-api/src/Wire/API/MLS/ProtocolVersion.hs +++ b/libs/wire-api/src/Wire/API/MLS/ProtocolVersion.hs @@ -30,6 +30,7 @@ import Imports import Wire.API.MLS.Serialisation import Wire.Arbitrary +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-6-4 newtype ProtocolVersion = ProtocolVersion {pvNumber :: Word16} deriving newtype (Eq, Ord, Show, Binary, Arbitrary, ParseMLS, SerialiseMLS) diff --git a/libs/wire-api/src/Wire/API/MLS/Welcome.hs b/libs/wire-api/src/Wire/API/MLS/Welcome.hs index cacb183cba0..17dc605d8c5 100644 --- a/libs/wire-api/src/Wire/API/MLS/Welcome.hs +++ b/libs/wire-api/src/Wire/API/MLS/Welcome.hs @@ -25,6 +25,7 @@ import Wire.API.MLS.KeyPackage import Wire.API.MLS.Serialisation import Wire.Arbitrary +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-12.4.3.1-5 data Welcome = Welcome { welCipherSuite :: CipherSuite, welSecrets :: [GroupSecrets], @@ -49,6 +50,7 @@ instance SerialiseMLS Welcome where serialiseMLSVector @VarInt serialiseMLS ss serialiseMLSBytes @VarInt gi +-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-12.4.3.1-5 data GroupSecrets = GroupSecrets { gsNewMember :: KeyPackageRef, gsSecrets :: HPKECiphertext