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