openmls/test_utils/frankenstein/
key_package.rs

1use std::ops::{Deref, DerefMut};
2
3use openmls_basic_credential::SignatureKeyPair;
4use openmls_test::openmls_test;
5use openmls_traits::{signatures::Signer, types::Ciphersuite, OpenMlsProvider};
6use tls_codec::*;
7
8use super::{extensions::FrankenExtension, leaf_node::FrankenLeafNode};
9use crate::{
10    ciphersuite::{
11        signable::{Signable, SignedStruct},
12        signature::{OpenMlsSignaturePublicKey, Signature},
13    },
14    credentials::{BasicCredential, CredentialWithKey},
15    key_packages::{KeyPackage, KeyPackageIn},
16    prelude::KeyPackageBundle,
17    test_utils::OpenMlsRustCrypto,
18    versions::ProtocolVersion,
19};
20
21#[derive(
22    Debug, Clone, PartialEq, Eq, TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize,
23)]
24pub struct FrankenKeyPackage {
25    pub payload: FrankenKeyPackageTbs,
26    pub signature: VLBytes,
27}
28
29impl FrankenKeyPackage {
30    // Re-sign both the KeyPackage and the enclosed LeafNode
31    pub fn resign(&mut self, signer: &impl Signer) {
32        self.payload.leaf_node.resign(None, signer);
33        let new_self = self.payload.clone().sign(signer).unwrap();
34        let _ = std::mem::replace(self, new_self);
35    }
36
37    // Only re-sign the KeyPackage
38    pub fn resign_only_key_package(&mut self, signer: &impl Signer) {
39        let new_self = self.payload.clone().sign(signer).unwrap();
40        let _ = std::mem::replace(self, new_self);
41    }
42}
43
44impl Deref for FrankenKeyPackage {
45    type Target = FrankenKeyPackageTbs;
46
47    fn deref(&self) -> &Self::Target {
48        &self.payload
49    }
50}
51
52impl DerefMut for FrankenKeyPackage {
53    fn deref_mut(&mut self) -> &mut Self::Target {
54        &mut self.payload
55    }
56}
57
58impl SignedStruct<FrankenKeyPackageTbs> for FrankenKeyPackage {
59    fn from_payload(
60        payload: FrankenKeyPackageTbs,
61        signature: Signature,
62        _serialized_payload: Vec<u8>,
63    ) -> Self {
64        Self {
65            payload,
66            signature: signature.as_slice().to_owned().into(),
67        }
68    }
69}
70
71const SIGNATURE_KEY_PACKAGE_LABEL: &str = "KeyPackageTBS";
72
73impl Signable for FrankenKeyPackageTbs {
74    type SignedOutput = FrankenKeyPackage;
75
76    fn unsigned_payload(&self) -> Result<Vec<u8>, tls_codec::Error> {
77        self.tls_serialize_detached()
78    }
79
80    fn label(&self) -> &str {
81        SIGNATURE_KEY_PACKAGE_LABEL
82    }
83}
84
85impl From<KeyPackage> for FrankenKeyPackage {
86    fn from(kp: KeyPackage) -> Self {
87        FrankenKeyPackage::tls_deserialize(&mut kp.tls_serialize_detached().unwrap().as_slice())
88            .unwrap()
89    }
90}
91
92impl From<KeyPackageBundle> for FrankenKeyPackage {
93    fn from(kp: KeyPackageBundle) -> Self {
94        FrankenKeyPackage::tls_deserialize(
95            &mut kp
96                .key_package()
97                .tls_serialize_detached()
98                .unwrap()
99                .as_slice(),
100        )
101        .unwrap()
102    }
103}
104
105impl From<FrankenKeyPackage> for KeyPackage {
106    fn from(fkp: FrankenKeyPackage) -> Self {
107        KeyPackageIn::tls_deserialize(&mut fkp.tls_serialize_detached().unwrap().as_slice())
108            .unwrap()
109            .into()
110    }
111}
112
113impl From<FrankenKeyPackage> for KeyPackageIn {
114    fn from(fkp: FrankenKeyPackage) -> Self {
115        KeyPackageIn::tls_deserialize(&mut fkp.tls_serialize_detached().unwrap().as_slice())
116            .unwrap()
117    }
118}
119
120#[derive(
121    Debug, Clone, PartialEq, Eq, TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize,
122)]
123pub struct FrankenKeyPackageTbs {
124    pub protocol_version: u16,
125    pub ciphersuite: u16,
126    pub init_key: VLBytes,
127    pub leaf_node: FrankenLeafNode,
128    pub extensions: Vec<FrankenExtension>,
129}
130
131#[derive(
132    Debug, Clone, PartialEq, Eq, TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize,
133)]
134pub struct FrankenLifetime {
135    pub not_before: u64,
136    pub not_after: u64,
137}
138
139#[openmls_test]
140fn test_franken_key_package() {
141    let provider = &Provider::default();
142
143    let config = ciphersuite;
144
145    let (credential, signer) = {
146        let credential = BasicCredential::new(b"test identity".to_vec());
147        let signature_keys = SignatureKeyPair::new(ciphersuite.signature_algorithm()).unwrap();
148        signature_keys.store(provider.storage()).unwrap();
149
150        (credential, signature_keys)
151    };
152    let signature_key = OpenMlsSignaturePublicKey::new(
153        signer.to_public_vec().into(),
154        ciphersuite.signature_algorithm(),
155    )
156    .unwrap();
157
158    let credential_with_key = CredentialWithKey {
159        credential: credential.into(),
160        signature_key: signature_key.into(),
161    };
162
163    let kp = KeyPackage::builder()
164        .build(config, provider, &signer, credential_with_key)
165        .unwrap();
166
167    let ser = kp.key_package().tls_serialize_detached().unwrap();
168    let fkp = FrankenKeyPackage::tls_deserialize(&mut ser.as_slice()).unwrap();
169
170    let ser2 = fkp.tls_serialize_detached().unwrap();
171    assert_eq!(ser, ser2);
172
173    let kp2 = KeyPackage::from(fkp.clone());
174    assert_eq!(kp.key_package(), &kp2);
175}