XML Security in pure Rust, built to replace libxmlsec1.
No C dependencies. No cmake. No system libraries. Just cargo add xml-sec.
Warning
Early-stage pre-release. The API is unstable, XMLDSig/XMLEnc coverage is still incomplete, and this crate should not yet be used in production.
- C14N — XML Canonicalization (inclusive + exclusive, W3C compliant)
- XMLDSig — XML Digital Signatures (verify and signing pipelines, X.509
KeyInfo, and xmlsec1 CLI interoperability) - XMLEnc — XML Encryption encrypt/decrypt pipelines (direct, RSA-OAEP, and AES-KW keys)
- X.509 — Certificate-based key extraction and validation
- Native CLI —
xmlsec1command surface backed by the same Rust policy and provider pipelines - Provider-neutral crypto — typed capabilities and opaque key handles with RustCrypto as the pure-Rust default
libxmlsec1 is the established XML Security implementation, but its native dependency stack adds libxml2, a crypto backend, platform packages, and cross-compilation work to every deployment.
xml-sec rebuilds that functionality on memory-safe Rust foundations: roxmltree for parsing,
quick-xml for writing, RustCrypto for cryptography, and x509-parser for certificates. One
Cargo dependency, no system XML or crypto libraries.
Pre-release. API is unstable. Not ready for production use.
Currently implemented (core paths):
- C14N 1.0, C14N 1.1, and Exclusive C14N
- XMLDSig parsing, same-document URI dereference, enveloped/C14N/Base64/XPath 1.0/XPath Filter 2.0 transform chains, and digest verification
- XMLDSig full verify pipeline (
SignedInfocanonicalization +SignatureValueverification) - XMLDSig template signing pipeline (
DigestValuefill +SignedInfocanonicalization +SignatureValuefill), including enveloped SAML Response templates - Unified typed verify/sign/encrypt/decrypt policies own algorithms, key-source and X.509 trust rules, URI/transform semantics, Manifest handling, XML parsing, and shared resource budgets. Caller keys, selected targets, and external bytes remain request context; resolver or per-call options cannot override policy.
- XMLDSig signing KeyInfo writer for embedded X.509 certificates
- Built-in verification-key resolution from embedded X.509/DER/
KeyValuesources and configuredKeyName, X.509 subject, issuer/serial, SKI, or digest selectors - RSA PKCS#1 v1.5 verification helpers for SHA-1 / SHA-256 / SHA-384 / SHA-512
- ECDSA SHA-256/SHA-384 verification for P-256, P-384, and P-521 keys
- Legacy DSA-SHA1 and HMAC-SHA1 verification, including truncated HMAC output
- RSA PKCS#1 v1.5 and ECDSA SHA-256/SHA-384 signing with P-256/P-384 PKCS#8 keys
- Opt-in X.509 certificate-chain validation with explicit trust anchors, validity and path-length checks, NameConstraints, authenticated CRLs, typed path-wide ExtendedKeyUsage policy, and RSA-PSS/Ed25519 certificate-signature support. Duplicate certificate, CRL, and CRL-entry extension OIDs, malformed SAN identities, unsupported delta CRLs,
removeFromCRLentries in complete CRLs, and invalid name constraints are rejected; implemented critical extensions are processed and every other critical extension fails closed. - Caller-supplied external references and X.509
RetrievalMethodresolution with bounded RFC 3986xml:baseprocessing and no implicit I/O - XMLEnc AES-128/256-CBC and AES-128/256-GCM encryption/decryption with direct keys, RSA-OAEP key transport, AES-128/256-KW, multiple recipients, and Element/Content document replacement; document, node, metadata, aggregate recipient, and key-candidate limits plus separate inbound/outbound algorithm policies and outbound RSA key-strength policy cover caller-constructed ciphertext and generated replacement output before expensive work. CBC failures expose no decrypted padding details, but CBC remains unauthenticated and can be excluded by policy
- Provider-neutral digest, signature, X.509 signature, cipher, key-wrap, key-transport, key-agreement, KDF, and RNG contracts. Capability checks include operation parameters; unavailable mechanisms fail closed without falling back to another provider. RustCrypto implements the currently supported algorithms.
Still in progress:
- XMLDSig DSA-SHA256, broader HMAC verification/signing, and RSA-PSS
SignatureMethodalgorithms - Complete XMLDSig and XMLEnc conformance-suite classification
- Expanded fuzz coverage, benchmarks, production hardening, and API stabilization
The libxmlsec1 compatibility ledger tracks the complete upstream 1.3.13 public surface as generated, evidence-linked data. It separates implemented wire behavior from policy-gated compatibility, planned parity work, provider-specific differences, and the not-yet-implemented C ABI.
Install the command-line package and inspect its runtime capability registry:
cargo install xmlsec1-cli
xmlsec1 version
xmlsec1 list-transforms
xmlsec1 list-key-dataThe native binary covers sign/verify, template-preserving encrypt/decrypt, AES
key generation, capability queries, donor option syntax, and deterministic
process statuses through the same policy and provider pipelines as the library.
Unsupported algorithms, formats, providers, and policy controls fail closed;
document-selected certificates require explicit trust unless --insecure is
chosen. Selected unmodified upstream DSig, Enc, and Keys scenarios run against
the Rust binary without network access or a system xmlsec1. See the
CLI compatibility guide for exact commands, formats, key lookup,
diagnostics, and interoperability boundaries.
examples/sign.rs builds an enveloped RSA-SHA256 signature and examples/verify.rs
verifies it through the embedded X.509 certificate:
cargo run --example sign --all-features > signed.xml
cargo run --example verify --all-features -- signed.xmlSee XML Digital Signatures for supported algorithms, transform semantics, key-resolution policy, and validation failure handling.
Enable the xmlenc feature. EncryptedDataBuilder supports direct symmetric keys,
RSA-OAEP recipients, AES Key Wrap recipients, and Element/Content document replacement:
use xml_sec::xmlenc::{DataEncryptionAlgorithm, EncryptedDataBuilder};
fn example() -> Result<(), Box<dyn std::error::Error>> {
let key = [0x42_u8; 16];
let encrypted_data = EncryptedDataBuilder::new(DataEncryptionAlgorithm::Aes128Gcm)
.direct_key(key)
.direct_key_name("application-content-key")
.encrypt_xml("<secret>value</secret>")?;
assert!(encrypted_data.encrypted_data_xml.contains("EncryptedData"));
Ok(())
}See XML Encryption for reciprocal decryption, recipient transport, document replacement, input bounds, and parser security policy.
Current toolchain target: latest stable Rust. Current MSRV: Rust 1.92.
| Spec | Status |
|---|---|
| Canonical XML 1.0 | Implemented; full-document and document-subset vectors |
| Canonical XML 1.1 | Implemented; xml:id and xml:base subset rules |
| Exclusive C14N | Implemented; InclusiveNamespaces PrefixList support |
| XMLDSig | Core sign/verify pipelines and the complete Merlin corpus implemented; additional algorithms and conformance suites in progress |
| XMLEnc | Core AES-CBC/GCM encrypt/decrypt with RSA-OAEP and AES-KW implemented; broader conformance coverage in progress |
Apache-2.0
If xml-sec is useful in your stack, you can help fund continued implementation and maintenance.
USDT (TRC-20): TFDsezHa1cBkoeZT5q2T49Wp66K8t2DmdA