openmls/extensions/
external_pub_extension.rs

1use tls_codec::{TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize};
2
3use super::{Deserialize, Serialize};
4use crate::ciphersuite::HpkePublicKey;
5
6/// ```c
7/// // draft-ietf-mls-protocol-16
8/// struct {
9///     HPKEPublicKey external_pub;
10/// } ExternalPub;
11/// ```
12#[derive(
13    PartialEq,
14    Eq,
15    Clone,
16    Debug,
17    Serialize,
18    Deserialize,
19    TlsSerialize,
20    TlsDeserialize,
21    TlsDeserializeBytes,
22    TlsSize,
23)]
24pub struct ExternalPubExtension {
25    external_pub: HpkePublicKey,
26}
27
28impl ExternalPubExtension {
29    /// Create a new `external_pub` extension.
30    pub fn new(external_pub: HpkePublicKey) -> Self {
31        Self { external_pub }
32    }
33
34    /// Get a reference to the HPKE public key.
35    pub fn external_pub(&self) -> &HpkePublicKey {
36        &self.external_pub
37    }
38}
39
40#[cfg(test)]
41mod test {
42    use crate::test_utils::OpenMlsRustCrypto;
43    use openmls_traits::{crypto::OpenMlsCrypto, types::Ciphersuite, OpenMlsProvider};
44    use tls_codec::{Deserialize, Serialize};
45
46    use super::*;
47    use crate::prelude_test::Secret;
48
49    #[test]
50    fn test_serialize_deserialize() {
51        let tests = {
52            let provider = OpenMlsRustCrypto::default();
53
54            let mut external_pub_extensions = Vec::new();
55
56            for _ in 0..8 {
57                let hpke_public_key =
58                    {
59                        let ikm = Secret::random(
60                            Ciphersuite::MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519,
61                            provider.rand(),
62                        )
63                        .unwrap();
64                        let init_key = provider.crypto().derive_hpke_keypair(
65                            Ciphersuite::hpke_config(
66                                &Ciphersuite::MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519,
67                            ),
68                            ikm.as_slice(),
69                        ).expect("error deriving hpke key pair");
70                        init_key.public
71                    };
72
73                external_pub_extensions.push(ExternalPubExtension::new(hpke_public_key.into()));
74            }
75
76            external_pub_extensions
77        };
78
79        for expected in tests {
80            let serialized = expected.tls_serialize_detached().unwrap();
81            let got = ExternalPubExtension::tls_deserialize_exact(serialized).unwrap();
82            assert_eq!(expected, got);
83        }
84    }
85}