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#[cfg(feature = "xmldsig")]
49pub mod rsa_encoding;
50// Checksum-pinned RustCrypto ML-DSA with checked expanded-key import. Keep it
51// inside the published package: Cargo patches do not propagate to consumers.
52#[cfg(feature = "experimental-pq")]
53#[allow(dead_code, unused_imports, missing_docs)]
54#[cfg_attr(test, allow(clippy::unwrap_used, deprecated))]
55#[path = "rustcrypto_ml_dsa/lib.rs"]
56mod rustcrypto_ml_dsa;
57#[cfg(feature = "xmldsig")]
58// The same sources also build as standalone crates for the XSLT workspace member.
59// Only their XPath-facing surface is used by this package.
60#[doc(hidden)]
61#[allow(dead_code, unused_imports, missing_docs)]
62#[cfg_attr(test, allow(clippy::unwrap_used))]
63#[path = "sxd_document/lib.rs"]
64mod sxd_document;
65#[cfg(feature = "xmldsig")]
66#[doc(hidden)]
67#[allow(dead_code, unused_imports, missing_docs)]
68#[cfg_attr(test, allow(clippy::unwrap_used))]
69#[path = "sxd_xpath/lib.rs"]
70mod sxd_xpath;
71#[path = "xml_input/shared.rs"]
72// The internal xml-input crate also compiles this source for XSLT's wider API.
73#[allow(dead_code)]
74mod xml_input_shared;
75/// Bounded XML input decoding and lexical helpers.
76///
77/// [`decode_xml_bounded`] accepts trusted encoding metadata and a caller-supplied
78/// decoded-byte limit. The unbounded internal helpers are not public.
79///
80/// ```compile_fail
81/// use xml_sec::xml_input::decode_xml;
82/// ```
83pub mod xml_input {
84    pub use crate::xml_input_shared::{Error, decode_xml_bounded, lexical};
85}
86#[cfg(all(test, feature = "xmldsig"))]
87pub(crate) use sxd_document::{Package, QName, dom};
88#[cfg(feature = "xmldsig")]
89pub(crate) use sxd_document::{StorageRequirements, XML_NS_PREFIX, XML_NS_URI, str, string_pool};
90#[cfg(all(test, feature = "xmldsig"))]
91pub(crate) use sxd_xpath::{Context, Factory};
92#[cfg(feature = "xmldsig")]
93pub(crate) use sxd_xpath::{
94    LiteralValue, OwnedPrefixedName, OwnedQName, ParseBudget, Value, axis, context, expression,
95    function, node_test, node_to_num_with_context, nodeset, parser, str_to_num, token, tokenizer,
96};
97#[cfg(feature = "xmldsig")]
98pub mod key_establishment;
99#[cfg(any(feature = "xmldsig", feature = "xmlenc"))]
100mod operation;
101#[cfg(any(feature = "xmldsig", feature = "xmlenc"))]
102pub mod policy;
103#[cfg(any(feature = "xmldsig", feature = "xmlenc"))]
104pub mod provider;
105mod xml;
106
107pub use xml::IdAttributeRegistration;
108pub use xml::dom::{
109    Ancestors, Attribute, Attributes, Children, Descendants, Document, Document as XmlDomDocument,
110    ExpandedName, Namespace, Namespaces, Node, Node as XmlDomNode, NodeId, NodeId as XmlDomNodeId,
111    NodeType, PI, ParseError, ParseError as XmlDomParseError, ParsingOptions,
112    ParsingOptions as XmlDomParsingOptions, XmlBackend, XmlIdError,
113};
114
115#[cfg(feature = "xmldsig")]
116pub mod key_manager;
117#[cfg(feature = "xmldsig")]
118pub mod xmldsig;
119
120#[cfg(feature = "xmlenc")]
121pub mod xmlenc;
122
123#[cfg(any(feature = "xmldsig", feature = "xmlenc"))]
124pub use document::XmlDocumentPolicy;
125pub use document::{
126    AttributeIdentity, DocumentIdentity, DocumentView, NamespaceIdentity, NodeIdentity,
127    SemanticOrder, XmlDocument, XmlDocumentError,
128};
129pub use error::XmlSecError;