1#![doc = include_str!("../../docs/xmlenc.md")]
15
16use crate::xml::dom::Node;
17
18mod agreement;
19mod encapsulation;
20pub use encapsulation::EncapsulationDecryptor;
21mod cipher_reference;
22pub use agreement::{AgreementDecryptor, AgreementMethod};
23mod decrypt;
24pub use cipher_reference::CipherReferenceContext;
25mod derived_key;
26pub(crate) use decrypt::validate_key_len;
27pub use derived_key::DerivedKey;
28mod encrypt;
29mod hkdf_agreement;
30mod key_derivation;
31pub use hkdf_agreement::{HkdfAgreement, parse_hkdf_agreement_method};
32mod key_establishment_budget;
33pub use key_establishment_budget::KeyEstablishmentBudget;
34mod parse;
35mod types;
36
37pub use decrypt::{
38 DecryptContext, DecryptionKeyResolver, DerivedKeyDecryptor, DerivedKeyInput,
39 DocumentDecryptionOptions, KekDecryptor, KeyCandidateBudget, KeyEncryptionKeySource,
40 OpaqueContentKeyResolver, OpaqueKekDecryptor, PrivateKeyDecryptor, SymmetricKeyDecryptor,
41 decrypt, decrypt_data, decrypt_document, decrypt_document_with_options,
42};
43pub use encrypt::{
44 EncryptedDataBuilder, validate_key_transport_recipient, validate_rsa_recipient_key,
45};
46pub use key_derivation::{
47 ConcatKdfField, KeyDerivationMethod, parse_key_derivation_method,
48 parse_key_derivation_method_with_backend,
49};
50pub use parse::{
51 EncryptedDataInspection, EncryptedDataTemplate, inspect_encrypted_data_node_with_context,
52 inspect_encrypted_data_template_node_with_context, parse_encrypted_data,
53 parse_encrypted_data_node_with_context, parse_encrypted_data_node_with_policy,
54 parse_encrypted_data_node_with_policy_and_backend,
55 parse_encrypted_data_template_node_with_policy,
56 parse_encrypted_data_template_node_with_policy_and_backend,
57};
58pub use types::{
59 ChaChaParameters, ChaChaParametersRef, CipherData, DataEncryptionAlgorithm, DecryptedContent,
60 DocumentEncryptionOptions, EncryptedData, EncryptedDataType, EncryptedKey,
61 EncryptionKeySources, EncryptionMethod, EncryptionRecipient, EncryptionResult,
62 KeyTransportAlgorithm, KeyWrapAlgorithm, OaepDigestAlgorithm, ReferenceList, ReplacementMode,
63 RsaOaepParameters, XmlEncError,
64};
65
66fn map_document_error(
67 error: crate::document::XmlDocumentError,
68 settings: crate::document::DocumentParseSettings,
69) -> XmlEncError {
70 match error.into_policy_violation(settings) {
71 Ok(error) => XmlEncError::Policy(error),
72 Err(crate::document::XmlDocumentError::Parse(error)) => XmlEncError::XmlParse(error),
73 Err(crate::document::XmlDocumentError::ProjectedNodeLimit { maximum }) => {
74 crate::policy::PolicyViolation::ResourceLimit {
75 resource: crate::policy::resource_name::XML_NODES,
76 maximum,
77 actual: maximum.saturating_add(1),
78 }
79 .into()
80 }
81 Err(error) => XmlEncError::Document(error),
82 }
83}
84
85fn has_single_element_with_boundary_trivia(parent: Node<'_, '_>) -> bool {
86 let mut element_count = 0;
87 for node in parent.children() {
88 if node.is_element() {
89 element_count += 1;
90 if element_count > 1 {
91 return false;
92 }
93 } else if node.is_comment() {
94 continue;
95 } else if node.is_text() {
96 if !node.text().is_some_and(|text| {
99 text.chars()
100 .all(|character| matches!(character, ' ' | '\t' | '\n' | '\r'))
101 }) {
102 return false;
103 }
104 } else {
105 return false;
106 }
107 }
108 element_count == 1
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114 use crate::document::{DocumentParseSettings, XmlDocumentError};
115
116 #[test]
117 fn document_errors_have_one_xmlenc_policy_mapping() {
118 let settings = DocumentParseSettings::new_with_depth(false, 8, 3, 128);
121 assert!(matches!(
122 map_document_error(
123 XmlDocumentError::DocumentTooDeep {
124 maximum: 3,
125 actual: 4,
126 },
127 settings,
128 ),
129 XmlEncError::Policy(crate::policy::PolicyViolation::ResourceLimit {
130 resource: crate::policy::resource_name::XML_DEPTH,
131 maximum: 3,
132 actual: 4,
133 })
134 ));
135 assert!(matches!(
136 map_document_error(
137 XmlDocumentError::ProjectedNodeLimit { maximum: 8 },
138 settings,
139 ),
140 XmlEncError::Policy(crate::policy::PolicyViolation::ResourceLimit {
141 resource: crate::policy::resource_name::XML_NODES,
142 maximum: 8,
143 actual: 9,
144 })
145 ));
146 }
147}