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 CipherData, DataEncryptionAlgorithm, DecryptedContent, DocumentEncryptionOptions,
60 EncryptedData, EncryptedDataType, EncryptedKey, EncryptionKeySources, EncryptionMethod,
61 EncryptionRecipient, EncryptionResult, KeyTransportAlgorithm, KeyWrapAlgorithm,
62 OaepDigestAlgorithm, ReferenceList, ReplacementMode, RsaOaepParameters, XmlEncError,
63};
64
65fn map_document_error(
66 error: crate::document::XmlDocumentError,
67 settings: crate::document::DocumentParseSettings,
68) -> XmlEncError {
69 match error.into_policy_violation(settings) {
70 Ok(error) => XmlEncError::Policy(error),
71 Err(crate::document::XmlDocumentError::Parse(error)) => XmlEncError::XmlParse(error),
72 Err(crate::document::XmlDocumentError::ProjectedNodeLimit { maximum }) => {
73 crate::policy::PolicyViolation::ResourceLimit {
74 resource: crate::policy::resource_name::XML_NODES,
75 maximum,
76 actual: maximum.saturating_add(1),
77 }
78 .into()
79 }
80 Err(error) => XmlEncError::Document(error),
81 }
82}
83
84fn has_single_element_with_boundary_trivia(parent: Node<'_, '_>) -> bool {
85 let mut element_count = 0;
86 for node in parent.children() {
87 if node.is_element() {
88 element_count += 1;
89 if element_count > 1 {
90 return false;
91 }
92 } else if node.is_comment() {
93 continue;
94 } else if node.is_text() {
95 if !node.text().is_some_and(|text| {
98 text.chars()
99 .all(|character| matches!(character, ' ' | '\t' | '\n' | '\r'))
100 }) {
101 return false;
102 }
103 } else {
104 return false;
105 }
106 }
107 element_count == 1
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113 use crate::document::{DocumentParseSettings, XmlDocumentError};
114
115 #[test]
116 fn document_errors_have_one_xmlenc_policy_mapping() {
117 let settings = DocumentParseSettings::new_with_depth(false, 8, 3, 128);
120 assert!(matches!(
121 map_document_error(
122 XmlDocumentError::DocumentTooDeep {
123 maximum: 3,
124 actual: 4,
125 },
126 settings,
127 ),
128 XmlEncError::Policy(crate::policy::PolicyViolation::ResourceLimit {
129 resource: crate::policy::resource_name::XML_DEPTH,
130 maximum: 3,
131 actual: 4,
132 })
133 ));
134 assert!(matches!(
135 map_document_error(
136 XmlDocumentError::ProjectedNodeLimit { maximum: 8 },
137 settings,
138 ),
139 XmlEncError::Policy(crate::policy::PolicyViolation::ResourceLimit {
140 resource: crate::policy::resource_name::XML_NODES,
141 maximum: 8,
142 actual: 9,
143 })
144 ));
145 }
146}