xml_sec/xmlenc/
derived_key.rs1use crate::xml::dom::Node;
4
5use super::parse::{bounded_simple_text_with_limit, validate_metadata_len};
6use super::{
7 KeyDerivationMethod, XmlEncError,
8 types::{XMLENC_NS, XMLENC11_NS},
9};
10
11#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct DerivedKey {
15 pub method: Option<KeyDerivationMethod>,
17 pub derived_key_name: Option<String>,
19 pub master_key_name: Option<String>,
21 pub recipient: Option<String>,
23 pub id: Option<String>,
25 pub key_type: Option<String>,
27 pub reference_list: Option<super::ReferenceList>,
29}
30
31pub(super) fn parse(
32 node: Node<'_, '_>,
33 resources: &crate::policy::ResourcePolicy,
34) -> Result<DerivedKey, XmlEncError> {
35 let maximum = resources.max_encryption_metadata_bytes;
36 super::parse::require_element(node, XMLENC11_NS, "DerivedKey")?;
37 let attribute = |name| -> Result<_, XmlEncError> {
38 let value = node.attribute(name);
39 if let Some(value) = value {
40 validate_metadata_len(value.len(), maximum)?;
41 }
42 Ok(value.map(str::to_owned))
43 };
44 for child in node.children() {
45 if child.is_text()
46 && child.text().is_some_and(|text| {
47 !text
48 .bytes()
49 .all(|b| matches!(b, b' ' | b'\t' | b'\r' | b'\n'))
50 })
51 {
52 return Err(XmlEncError::InvalidStructure(
53 "DerivedKey contains character data".into(),
54 ));
55 }
56 }
57 let mut children = node.children().filter(Node::is_element).peekable();
58 let method = if children
59 .peek()
60 .is_some_and(|child| child.has_tag_name((XMLENC11_NS, "KeyDerivationMethod")))
61 {
62 Some(super::key_derivation::parse_node(
63 children.next().expect("peeked child"),
64 maximum,
65 )?)
66 } else {
67 None
68 };
69 let reference_list = if children
70 .peek()
71 .is_some_and(|child| child.has_tag_name((XMLENC_NS, "ReferenceList")))
72 {
73 Some(super::parse::parse_reference_list_with_resources(
74 children.next().expect("peeked child"),
75 resources,
76 )?)
77 } else {
78 None
79 };
80 let mut name = |tag| -> Result<_, XmlEncError> {
81 if children
82 .peek()
83 .is_some_and(|child| child.has_tag_name((XMLENC11_NS, tag)))
84 {
85 Ok(Some(bounded_simple_text_with_limit(
86 children.next().expect("peeked child"),
87 tag,
88 maximum,
89 )?))
90 } else {
91 Ok(None)
92 }
93 };
94 let derived_key_name = name("DerivedKeyName")?;
98 let master_key_name = name("MasterKeyName")?;
99 if children.next().is_some() {
100 return Err(XmlEncError::InvalidStructure(
101 "unexpected or unordered DerivedKey child".into(),
102 ));
103 }
104 Ok(DerivedKey {
105 method,
106 derived_key_name,
107 master_key_name,
108 reference_list,
109 recipient: attribute("Recipient")?,
110 id: attribute("Id")?,
111 key_type: attribute("Type")?,
112 })
113}