Skip to main content

xml_sec/
lib.rs

1//! # xml-sec — Pure Rust XML Security
2//!
3//! Drop-in replacement for libxmlsec1. XMLDSig, XMLEnc, C14N — no C dependencies.
4//!
5//! ## Features
6//!
7//! - **C14N** — XML Canonicalization (inclusive + exclusive)
8//! - **XMLDSig** — XML Digital Signatures (sign + verify)
9//! - **XMLEnc** — XML Encryption (encrypt + decrypt)
10//! - **X.509** — Certificate-based key extraction
11//!
12//! ## Quick Start
13//!
14//! ```rust
15//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
16//! use xml_sec::c14n::{C14nAlgorithm, C14nMode, canonicalize_xml};
17//!
18//! let xml = b"<root b=\"2\" a=\"1\"><empty/></root>";
19//! let algo = C14nAlgorithm::new(C14nMode::Inclusive1_0, false);
20//! let canonical = canonicalize_xml(xml, &algo)?;
21//! assert_eq!(
22//!     String::from_utf8(canonical)?,
23//!     "<root a=\"1\" b=\"2\"><empty></empty></root>"
24//! );
25//! # Ok(())
26//! # }
27//! ```
28
29#![deny(unsafe_code)]
30#![deny(clippy::unwrap_used)]
31#![warn(missing_docs)]
32
33extern crate alloc;
34#[cfg(feature = "xmldsig")]
35#[macro_use]
36extern crate peresil;
37
38#[cfg(not(any(feature = "xml-backend-xmloxide", feature = "xml-backend-roxmltree")))]
39compile_error!(
40    "compile at least one XML backend: `xml-backend-xmloxide` or `xml-backend-roxmltree`"
41);
42
43pub mod c14n;
44pub mod document;
45pub mod encoding;
46pub mod error;
47mod hard_limits;
48// Checksum-pinned RustCrypto ML-DSA with checked expanded-key import. Keep it
49// inside the published package: Cargo patches do not propagate to consumers.
50#[cfg(feature = "experimental-pq")]
51#[allow(dead_code, unused_imports, missing_docs)]
52#[cfg_attr(test, allow(clippy::unwrap_used, deprecated))]
53#[path = "rustcrypto_ml_dsa/lib.rs"]
54mod rustcrypto_ml_dsa;
55#[cfg(feature = "xmldsig")]
56// The same sources also build as standalone crates for the XSLT workspace member.
57// Only their XPath-facing surface is used by this package.
58#[doc(hidden)]
59#[allow(dead_code, unused_imports, missing_docs)]
60#[cfg_attr(test, allow(clippy::unwrap_used))]
61#[path = "sxd_document/lib.rs"]
62mod sxd_document;
63#[cfg(feature = "xmldsig")]
64#[doc(hidden)]
65#[allow(dead_code, unused_imports, missing_docs)]
66#[cfg_attr(test, allow(clippy::unwrap_used))]
67#[path = "sxd_xpath/lib.rs"]
68mod sxd_xpath;
69#[path = "xml_input/shared.rs"]
70// The internal xml-input crate also compiles this source for XSLT's wider API.
71#[allow(dead_code)]
72mod xml_input_shared;
73/// Bounded XML input decoding and lexical helpers.
74///
75/// [`decode_xml_bounded`] accepts trusted encoding metadata and a caller-supplied
76/// decoded-byte limit. The unbounded internal helpers are not public.
77///
78/// ```compile_fail
79/// use xml_sec::xml_input::decode_xml;
80/// ```
81pub mod xml_input {
82    pub use crate::xml_input_shared::{Error, decode_xml_bounded, lexical};
83}
84#[cfg(all(test, feature = "xmldsig"))]
85pub(crate) use sxd_document::{Package, QName, dom};
86#[cfg(feature = "xmldsig")]
87pub(crate) use sxd_document::{StorageRequirements, XML_NS_PREFIX, XML_NS_URI, str, string_pool};
88#[cfg(all(test, feature = "xmldsig"))]
89pub(crate) use sxd_xpath::{Context, Factory};
90#[cfg(feature = "xmldsig")]
91pub(crate) use sxd_xpath::{
92    LiteralValue, OwnedPrefixedName, OwnedQName, ParseBudget, Value, axis, context, expression,
93    function, node_test, node_to_num_with_context, nodeset, parser, str_to_num, token, tokenizer,
94};
95#[cfg(any(feature = "xmldsig", feature = "xmlenc"))]
96mod operation;
97#[cfg(any(feature = "xmldsig", feature = "xmlenc"))]
98pub mod policy;
99#[cfg(any(feature = "xmldsig", feature = "xmlenc"))]
100pub mod provider;
101mod xml;
102
103pub use xml::IdAttributeRegistration;
104pub use xml::dom::{
105    Ancestors, Attribute, Attributes, Children, Descendants, Document, Document as XmlDomDocument,
106    ExpandedName, Namespace, Namespaces, Node, Node as XmlDomNode, NodeId, NodeId as XmlDomNodeId,
107    NodeType, PI, ParseError, ParseError as XmlDomParseError, ParsingOptions,
108    ParsingOptions as XmlDomParsingOptions, XmlBackend,
109};
110
111#[cfg(feature = "xmldsig")]
112pub mod key_manager;
113#[cfg(feature = "xmldsig")]
114pub mod xmldsig;
115
116#[cfg(feature = "xmlenc")]
117pub mod xmlenc;
118
119#[cfg(any(feature = "xmldsig", feature = "xmlenc"))]
120pub use document::XmlDocumentPolicy;
121pub use document::{
122    AttributeIdentity, DocumentIdentity, DocumentView, NamespaceIdentity, NodeIdentity,
123    SemanticOrder, XmlDocument, XmlDocumentError,
124};
125pub use error::XmlSecError;