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(any(feature = "xmldsig", feature = "xmlenc"))]
98mod operation;
99#[cfg(any(feature = "xmldsig", feature = "xmlenc"))]
100pub mod policy;
101#[cfg(any(feature = "xmldsig", feature = "xmlenc"))]
102pub mod provider;
103mod xml;
104
105pub use xml::IdAttributeRegistration;
106pub use xml::dom::{
107    Ancestors, Attribute, Attributes, Children, Descendants, Document, Document as XmlDomDocument,
108    ExpandedName, Namespace, Namespaces, Node, Node as XmlDomNode, NodeId, NodeId as XmlDomNodeId,
109    NodeType, PI, ParseError, ParseError as XmlDomParseError, ParsingOptions,
110    ParsingOptions as XmlDomParsingOptions, XmlBackend,
111};
112
113#[cfg(feature = "xmldsig")]
114pub mod key_manager;
115#[cfg(feature = "xmldsig")]
116pub mod xmldsig;
117
118#[cfg(feature = "xmlenc")]
119pub mod xmlenc;
120
121#[cfg(any(feature = "xmldsig", feature = "xmlenc"))]
122pub use document::XmlDocumentPolicy;
123pub use document::{
124    AttributeIdentity, DocumentIdentity, DocumentView, NamespaceIdentity, NodeIdentity,
125    SemanticOrder, XmlDocument, XmlDocumentError,
126};
127pub use error::XmlSecError;