Skip to content

Repository files navigation

xml-sec

crates.io docs.rs CI MSRV License

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.

Features

  • 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 CLIxmlsec1 command 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

Why?

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.

Status

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 (SignedInfo canonicalization + SignatureValue verification)
  • XMLDSig template signing pipeline (DigestValue fill + SignedInfo canonicalization + SignatureValue fill), 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/KeyValue sources and configured KeyName, 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, removeFromCRL entries 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 RetrievalMethod resolution with bounded RFC 3986 xml:base processing 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 SignatureMethod algorithms
  • 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.

Native CLI

Install the command-line package and inspect its runtime capability registry:

cargo install xmlsec1-cli
xmlsec1 version
xmlsec1 list-transforms
xmlsec1 list-key-data

The 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.

XMLDSig Usage

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.xml

See XML Digital Signatures for supported algorithms, transform semantics, key-resolution policy, and validation failure handling.

XMLEnc Usage

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.

Specifications

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

License

Apache-2.0

Support the Project

If xml-sec is useful in your stack, you can help fund continued implementation and maintenance.

USDT TRC-20 Donation QR Code

USDT (TRC-20): TFDsezHa1cBkoeZT5q2T49Wp66K8t2DmdA

About

Pure Rust XML Security: XMLDSig, XMLEnc, C14N. Drop-in replacement for libxmlsec1.

Topics

Resources

Stars

5 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages