xml_sec/xmlenc/
encapsulation.rs1use super::{
4 DataEncryptionAlgorithm, DecryptionKeyResolver, KeyCandidateBudget, KeyEncryptionKeySource,
5 KeyWrapAlgorithm, XmlEncError,
6};
7use crate::provider::{CryptoProvider, KeyDecapsulationKey, RecoveredContentKey};
8
9pub struct EncapsulationDecryptor<'a> {
11 key: RecipientKey<'a>,
12}
13
14enum RecipientKey<'a> {
15 Borrowed(&'a dyn KeyDecapsulationKey),
16 Owned(std::sync::Arc<dyn KeyDecapsulationKey>),
17}
18
19impl RecipientKey<'_> {
20 fn as_ref(&self) -> &dyn KeyDecapsulationKey {
21 match self {
22 Self::Borrowed(key) => *key,
23 Self::Owned(key) => key.as_ref(),
24 }
25 }
26}
27
28impl<'a> EncapsulationDecryptor<'a> {
29 pub fn new(key: &'a dyn KeyDecapsulationKey) -> Self {
31 Self {
32 key: RecipientKey::Borrowed(key),
33 }
34 }
35
36 pub fn provider_key(key: std::sync::Arc<dyn KeyDecapsulationKey>) -> Self {
38 Self {
39 key: RecipientKey::Owned(key),
40 }
41 }
42
43 fn recover(
44 &self,
45 provider: &dyn CryptoProvider,
46 width: usize,
47 descriptor: &crate::key_establishment::EncapsulationMechanism,
48 policy: &crate::policy::DecryptionPolicy,
49 budget: &mut KeyCandidateBudget,
50 ) -> Result<Vec<RecoveredContentKey>, XmlEncError> {
51 if width == 0 || width > 32 {
52 return Err(crate::key_establishment::KeyEstablishmentError::Structure(
53 "consuming key exceeds KEM secret width",
54 )
55 .into());
56 }
57 budget.consume(1)?;
58 budget.key_establishment.commit_all(
59 &policy.key_establishment,
60 0,
61 0,
62 (width + core::mem::size_of::<RecoveredContentKey>()) as u128,
63 )?;
64 let secret = budget.key_establishment.decapsulate(
65 &policy.key_establishment,
66 provider,
67 self.key.as_ref(),
68 descriptor.algorithm,
69 &descriptor.ciphertext,
70 )?;
71 Ok(vec![RecoveredContentKey::confirmed(
80 secret[..width].to_vec(),
81 )])
82 }
83}
84
85impl DecryptionKeyResolver for EncapsulationDecryptor<'_> {
86 fn resolve_key(
87 &self,
88 _: &dyn CryptoProvider,
89 _: DataEncryptionAlgorithm,
90 _: Option<&super::EncryptedKey>,
91 ) -> Result<Vec<u8>, XmlEncError> {
92 Err(XmlEncError::KeyNotFound)
93 }
94
95 fn resolve_encapsulation_content_keys_with_policy(
96 &self,
97 provider: &dyn CryptoProvider,
98 algorithm: DataEncryptionAlgorithm,
99 descriptor: &crate::key_establishment::EncapsulationMechanism,
100 policy: &crate::policy::DecryptionPolicy,
101 budget: &mut KeyCandidateBudget,
102 ) -> Result<Vec<RecoveredContentKey>, XmlEncError> {
103 policy.key_establishment.check_kem_content(algorithm)?;
104 self.recover(provider, algorithm.key_len(), descriptor, policy, budget)
105 }
106
107 fn resolve_key_encryption_keys_with_policy(
108 &self,
109 provider: &dyn CryptoProvider,
110 algorithm: KeyWrapAlgorithm,
111 source: KeyEncryptionKeySource<'_>,
112 policy: &crate::policy::DecryptionPolicy,
113 budget: &mut KeyCandidateBudget,
114 ) -> Result<Vec<RecoveredContentKey>, XmlEncError> {
115 let KeyEncryptionKeySource::Encapsulation(descriptor) = source else {
116 return Err(XmlEncError::KeyNotFound);
117 };
118 self.recover(provider, algorithm.key_len(), descriptor, policy, budget)
119 }
120}