core_crypto/mls/
key_package.rs1pub use openmls::prelude::KeyPackage as Keypackage;
9use openmls::prelude::{KeyPackageRef as KpHashRef, Lifetime, SignatureScheme};
10
11use crate::{Ciphersuite, CredentialType, MlsError, mls_provider::CRYPTO};
12
13pub trait KeypackageExt {
15 fn make_ref(&self) -> Result<KeypackageRef, MlsError>;
19
20 fn ciphersuite(&self) -> Ciphersuite;
22
23 fn credential_type(&self) -> CredentialType;
25
26 fn is_valid(&self) -> bool;
30}
31
32impl KeypackageExt for Keypackage {
33 fn make_ref(&self) -> Result<KeypackageRef, MlsError> {
34 let hash_ref = self
35 .hash_ref(CRYPTO.as_ref())
36 .map_err(MlsError::wrap("computing keypackage hash ref"))?;
37
38 let ciphersuite = <Self as KeypackageExt>::ciphersuite(self);
39 let credential_type = self.credential_type();
40 let lifetime = self.leaf_node().life_time().cloned();
41
42 Ok(KeypackageRef {
43 hash_ref,
44 ciphersuite,
45 credential_type,
46 lifetime,
47 })
48 }
49
50 fn ciphersuite(&self) -> Ciphersuite {
51 <Keypackage>::ciphersuite(self).into()
52 }
53
54 fn credential_type(&self) -> CredentialType {
55 self.leaf_node()
56 .credential()
57 .credential_type()
58 .try_into()
59 .expect("we should only ever have a key package from a credential that this instance of CC understands")
60 }
61
62 fn is_valid(&self) -> bool {
63 self.leaf_node()
64 .life_time()
65 .is_none_or(|lifetime| lifetime.has_acceptable_range() && lifetime.is_valid())
66 }
67}
68
69#[derive(Debug, Clone, PartialEq, Eq)]
73pub struct KeypackageRef {
74 hash_ref: KpHashRef,
75 ciphersuite: Ciphersuite,
76 credential_type: CredentialType,
77 lifetime: Option<Lifetime>,
78}
79
80impl KeypackageRef {
81 pub fn hash_ref(&self) -> &[u8] {
83 self.hash_ref.as_slice()
84 }
85
86 pub fn ciphersuite(&self) -> Ciphersuite {
88 self.ciphersuite
89 }
90
91 pub fn signature_scheme(&self) -> SignatureScheme {
93 self.ciphersuite.signature_algorithm()
94 }
95
96 pub fn credential_type(&self) -> CredentialType {
98 self.credential_type
99 }
100
101 pub fn lifetime(&self) -> Option<&Lifetime> {
103 self.lifetime.as_ref()
104 }
105
106 pub fn is_valid(&self) -> bool {
110 self.lifetime()
111 .is_none_or(|lifetime| lifetime.has_acceptable_range() && lifetime.is_valid())
112 }
113}
114
115impl KeypackageExt for KeypackageRef {
116 fn make_ref(&self) -> Result<KeypackageRef, MlsError> {
117 Ok(self.clone())
118 }
119
120 fn ciphersuite(&self) -> Ciphersuite {
121 self.ciphersuite
122 }
123
124 fn credential_type(&self) -> CredentialType {
125 self.credential_type
126 }
127
128 fn is_valid(&self) -> bool {
129 <Self>::is_valid(self)
130 }
131}