openmls / openmls

Rust implementation of the Messaging Layer Security (MLS) protocol
https://openmls.tech
MIT License
624 stars 75 forks source link

Custom Extension doesn't show up in VerifiableGroupInfo.extensions() object #1665

Open erskingardner opened 21 hours ago

erskingardner commented 21 hours ago

I have created a custom GroupContext extension to store some application specific data. I noticed while building out the welcome flow that the extension isn't present in the VerifiableGroupInfo.extensions() response. Which comes back with just the ratchet tree extension.

I'm not sure if this is the expected behavior or not. I would have expected to get a list of all extensions for the group in the welcome objects so that I can inspect (and ultimately show the user) some of that context before they decide to join the group. There doesn't seem to be another easy way to get to the group_context directly via the ProcessedWelcome or StagedWelcome structs given the group_context is a private prop.

My extension uses Unknown(65385) as the identifier and you can see it here when I inspect the full VerifiableGroupInfo object

VerifiableGroupInfo:
  payload:
    GroupInfoTBS:
      group_context:
        GroupContext:
          protocol_version: Mls10
          ciphersuite: MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519
          group_id:
            GroupId:
              value:
                VLBytes: 0xd7e16ab6ac8c63c5b15276bfad4e1321
          epoch: GroupEpoch(1)
          tree_hash:
            VLBytes: 0x1e174054c40a9fe91e54baa85997a57096b609ef15df6e3039c242a6f9378d84
          confirmed_transcript_hash:
            VLBytes: 0x35fe0f69fa794866c59c1dbb4fdc2b96cf5117d400542763ffc6ab6a9c96312d
          extensions:
            Extensions:
              unique:
                - Unknown(65385, UnknownExtension([225, 131, 79, 194, 169, 192, 127, 107, 229, 207, 110, 223, 122, 10, 215, 242, 131, 45, 60, 108, 165, 64, 153, 169, 25, 8, 104, 192, 218, 220, 12, 117, 9, 83, 101, 99, 117, 114, 101, 32, 68, 77, 0, 64, 132, 64, 64, 101, 101, 55, 51, 102, 51, 54, 52, 50, 101, 98, 99, 50, 99, 102, 100, 49, 48, 101, 53, 102, 54, 55, 98, 50, 56, 53, 101, 48, 54, 97, 102, 53, 54, 55, 50, 52, 49, 54, 98, 52, 98, 57, 49, 54, 101, 57, 98, 101, 51, 56, 48, 50, 48, 99, 99, 100, 102, 53, 101, 49, 97, 56, 52, 64, 64, 49, 55, 51, 57, 100, 57, 51, 55, 100, 99, 56, 99, 48, 99, 55, 51, 55, 48, 97, 97, 50, 55, 53, 56, 53, 57, 51, 56, 99, 49, 49, 57, 101, 50, 53, 99, 52, 49, 102, 54, 99, 52, 52, 49, 97, 53, 100, 51, 52, 99, 54, 100, 51, 56, 53, 48, 51, 101, 51, 49, 51, 54, 101, 102, 20, 19, 119, 115, 58, 47, 47, 108, 111, 99, 97, 108, 104, 111, 115, 116, 58, 56, 48, 56, 48]))
      extensions:
        Extensions:
          unique:
            - RatchetTree(RatchetTreeExtension):
                ratchet_tree:
                  RatchetTreeIn:
                    - Some(LeafNode(LeafNodeIn)):
                        payload:
                          LeafNodePayload:
                            encryption_key:
                              EncryptionKey:
                                key:
                                  VLBytes: 0x8940e56d3a1fa7a48d3456169744ca02ffae51825e9a368785d7e7b6d6ea6626
                            signature_key:
                              SignaturePublicKey:
                                value:
                                  VLBytes: 0x6a1fabdaa351a9a8cad6eb83f9d915f4b2597054577f8f2c76dc1a55157b82b5
                            credential:
                              Credential:
                                credential_type: Basic
                                serialized_credential_content:
                                  VLBytes: 0x65653733663336343265626332636664313065356636376232383565303661663536373234313662346239313665396265333830323063636466356531613834
                            capabilities:
                              Capabilities:
                                versions: [Mls10]
                                ciphersuites: [VerifiableCiphersuite(1)]
                                extensions: [RequiredCapabilities, LastResort, Unknown(65385)]
                                proposals: []
                                credentials: [Basic]
                            leaf_node_source:
                              Commit:
                                VLBytes: 0x4099e93183d7e731a67398d3bfa21fcd98ea4ac14b98b29640ffd23276a78179
                            extensions:
                              Extensions:
                                unique: []
                        signature:
                          Signature:
                            value:
                              VLBytes: 0x01b04cda27baa2f9e9f0ff5b0dc76aefc5be14336b3122e5cf7a39eb39584770368a5b3a47dd50a00370ff411a92649e9ad8f5941a4f6c51e4049f62128aca0a
                    - Some(ParentNode(ParentNode)):
                        encryption_key:
                          EncryptionKey:
                            key:
                              VLBytes: 0xc3c103df8060021635263d3a5ee1e01aa76ada9128c84bad9510ff8463becc53
                        parent_hash:
                          VLBytes: ""
                        unmerged_leaves:
                          UnmergedLeaves:
                            list: []
                    - Some(LeafNode(LeafNodeIn)):
                        payload:
                          LeafNodePayload:
                            encryption_key:
                              EncryptionKey:
                                key:
                                  VLBytes: 0x3b4f4e01130cd7e35f3643089fda0b668848214918ed34cc5b7ad94f73665a3d
                            signature_key:
                              SignaturePublicKey:
                                value:
                                  VLBytes: 0x5a8db7dee7746ed19d9c0a1b9c6c2ab020c28eb3c155206f2a5bef789dd4a83a
                            credential:
                              Credential:
                                credential_type: Basic
                                serialized_credential_content:
                                  VLBytes: 0x31373339643933376463386330633733373061613237353835393338633131396532356334316636633434316135643334633664333835303365333133366566
                            capabilities:
                              Capabilities:
                                versions: [Mls10]
                                ciphersuites: [VerifiableCiphersuite(1)]
                                extensions: [RequiredCapabilities, LastResort, Unknown(65385)]
                                proposals: []
                                credentials: [Basic]
                            leaf_node_source:
                              KeyPackage:
                                Lifetime:
                                  not_before: 1729000047
                                  not_after: 1736261247
                            extensions:
                              Extensions:
                                unique: []
                        signature:
                          Signature:
                            value:
                              VLBytes: 0x1920d456d026ff29d216d21f15e78c861cfa39df2c4661a07a66f491d7aa3a183ef40ce10ac856dea8f86b008d29fac75cc43e01c8c51c48cbe9303477dec803
            - ExternalPub(ExternalPubExtension):
                external_pub:
                  VLBytes: 0x1b26066256072579004141c57304f3cc33e4fea7915ac3d1ddd1c58fcd68aa05
      confirmation_tag:
        ConfirmationTag:
          Mac:
            mac_value:
              VLBytes: 0xbf51533c2694d02edc39be477bbc9dc8d1eb1e3f499dde072680593777898742
      signer: LeafNodeIndex(0)
  signature:
    Signature:
      value:
        VLBytes: 0x76e07eb0272c9ed843dd642f182032330115e2292dec26b369aa83ad1ca44d2757c71c7ad8106b58228d07c77353380db97893c46353872c28e27e81c3345d04

When I call VerifiableGroupInfo.extensions() I get this back:

Extensions:
  unique:
    - RatchetTree(RatchetTreeExtension):
        ratchet_tree:
          RatchetTreeIn:
            - Some(LeafNode(LeafNodeIn)):
                payload:
                  LeafNodePayload:
                    encryption_key:
                      EncryptionKey:
                        key:
                          VLBytes: 0x8940e56d3a1fa7a48d3456169744ca02ffae51825e9a368785d7e7b6d6ea6626
                    signature_key:
                      SignaturePublicKey:
                        value:
                          VLBytes: 0x6a1fabdaa351a9a8cad6eb83f9d915f4b2597054577f8f2c76dc1a55157b82b5
                    credential:
                      Credential:
                        credential_type: Basic
                        serialized_credential_content:
                          VLBytes: 0x65653733663336343265626332636664313065356636376232383565303661663536373234313662346239313665396265333830323063636466356531613834
                    capabilities:
                      Capabilities:
                        versions: [Mls10]
                        ciphersuites: [VerifiableCiphersuite(1)]
                        extensions: [RequiredCapabilities, LastResort, Unknown(65385)]
                        proposals: []
                        credentials: [Basic]
                    leaf_node_source:
                      Commit:
                        VLBytes: 0x4099e93183d7e731a67398d3bfa21fcd98ea4ac14b98b29640ffd23276a78179
                    extensions:
                      Extensions:
                        unique: []
                signature:
                  Signature:
                    value:
                      VLBytes: 0x01b04cda27baa2f9e9f0ff5b0dc76aefc5be14336b3122e5cf7a39eb39584770368a5b3a47dd50a00370ff411a92649e9ad8f5941a4f6c51e4049f62128aca0a
            - Some(ParentNode(ParentNode)):
                encryption_key:
                  EncryptionKey:
                    key:
                      VLBytes: 0xc3c103df8060021635263d3a5ee1e01aa76ada9128c84bad9510ff8463becc53
                parent_hash:
                  VLBytes: ""
                unmerged_leaves:
                  UnmergedLeaves:
                    list: []
            - Some(LeafNode(LeafNodeIn)):
                payload:
                  LeafNodePayload:
                    encryption_key:
                      EncryptionKey:
                        key:
                          VLBytes: 0x3b4f4e01130cd7e35f3643089fda0b668848214918ed34cc5b7ad94f73665a3d
                    signature_key:
                      SignaturePublicKey:
                        value:
                          VLBytes: 0x5a8db7dee7746ed19d9c0a1b9c6c2ab020c28eb3c155206f2a5bef789dd4a83a
                    credential:
                      Credential:
                        credential_type: Basic
                        serialized_credential_content:
                          VLBytes: 0x31373339643933376463386330633733373061613237353835393338633131396532356334316636633434316135643334633664333835303365333133366566
                    capabilities:
                      Capabilities:
                        versions: [Mls10]
                        ciphersuites: [VerifiableCiphersuite(1)]
                        extensions: [RequiredCapabilities, LastResort, Unknown(65385)]
                        proposals: []
                        credentials: [Basic]
                    leaf_node_source:
                      KeyPackage:
                        Lifetime:
                          not_before: 1729000047
                          not_after: 1736261247
                    extensions:
                      Extensions:
                        unique: []
                signature:
                  Signature:
                    value:
                      VLBytes: 0x1920d456d026ff29d216d21f15e78c861cfa39df2c4661a07a66f491d7aa3a183ef40ce10ac856dea8f86b008d29fac75cc43e01c8c51c48cbe9303477dec803
    - ExternalPub(ExternalPubExtension):
        external_pub:
          VLBytes: 0x1b26066256072579004141c57304f3cc33e4fea7915ac3d1ddd1c58fcd68aa05
kkohbrok commented 20 hours ago

The .extensions() function of GroupInfo will give you GroupInfo extensions, which are conceptually different from GroupContext extensions. The missing piece here seems to be access to the GroupContext s.t. you can get access to the GroupContext extensions. There really should be a getter for the GroupContext for the StagedWelcome. Do you want to create a PR for that?

erskingardner commented 20 hours ago

Happy to. Thanks!

erskingardner commented 20 hours ago

@kkohbrok https://github.com/openmls/openmls/pull/1666