Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: cargo
directory: /
schedule:
interval: weekly
open-pull-requests-limit: 10
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
46 changes: 46 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]

env:
CARGO_TERM_COLOR: always
RUSTFLAGS: -Dwarnings

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo build --all-features

test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo test --all-features

clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: Swatinem/rust-cache@v2
- run: cargo clippy --all-features --all-targets -- -D warnings

fmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- run: cargo fmt --all -- --check
24 changes: 24 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Release
on:
push:
tags: ["v*"]

permissions:
contents: write

jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- run: cargo publish --token ${{ secrets.CRATES_IO_TOKEN }}

github-release:
runs-on: ubuntu-latest
needs: publish
steps:
- uses: actions/checkout@v6
- uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/target
Cargo.lock
*.swp
*.swo
.DS_Store
donors/
.refs/
37 changes: 37 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[package]
name = "xml-sec"
version = "0.1.0"
edition = "2021"
rust-version = "1.75"
license = "Apache-2.0"
description = "Pure Rust XML Security: XMLDSig, XMLEnc, C14N. Drop-in replacement for libxmlsec1."
repository = "https://github.com/structured-world/xml-sec"
homepage = "https://github.com/structured-world/xml-sec"
documentation = "https://docs.rs/xml-sec"
keywords = ["xml", "xmldsig", "xmlenc", "c14n", "saml"]
categories = ["cryptography", "web-programming", "authentication"]
readme = "README.md"

[dependencies]
# XML parsing
roxmltree = "0.20"

# Crypto
ring = "0.17"

# X.509 certificates
x509-parser = "0.16"
der = "0.7"

# Error handling
thiserror = "2"

[dev-dependencies]
# W3C test vectors
base64 = "0.22"

[features]
default = ["xmldsig", "c14n"]
xmldsig = [] # XML Digital Signatures (sign + verify)
xmlenc = [] # XML Encryption (encrypt + decrypt)
c14n = [] # XML Canonicalization (inclusive + exclusive)
39 changes: 38 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,39 @@
# xml-sec
Pure Rust XML Security: XMLDSig, XMLEnc, C14N. Drop-in replacement for libxmlsec1.

Pure Rust XML Security library. Drop-in replacement for libxmlsec1.

**No C dependencies. No cmake. No system libraries. Just `cargo add xml-sec`.**

## Features

- **C14N** — XML Canonicalization (inclusive + exclusive, W3C compliant)
- **XMLDSig** — XML Digital Signatures (sign + verify, enveloped/enveloping/detached)
- **XMLEnc** — XML Encryption (symmetric + asymmetric)
- **X.509** — Certificate-based key extraction and validation

## Why?

Every SAML, SOAP, and WS-Security implementation depends on libxmlsec1 — a C library that:
- Requires cmake + libxml2 + OpenSSL/NSS/GnuTLS to build
- Breaks on Alpine/musl static linking
- Has decades of CVEs in XML parsing and signature validation
- Cannot cross-compile easily

`xml-sec` is a ground-up Rust rewrite using `roxmltree` + `ring` + `x509-parser`. Single `cargo build`, works everywhere Rust works.

## Status

**Pre-release.** API is unstable. Not ready for production use.

## Specifications

| Spec | Status |
|------|--------|
| [Canonical XML 1.0](https://www.w3.org/TR/xml-c14n/) | Planned |
| [Exclusive C14N](https://www.w3.org/TR/xml-exc-c14n/) | Planned |
| [XMLDSig](https://www.w3.org/TR/xmldsig-core1/) | Planned |
| [XMLEnc](https://www.w3.org/TR/xmlenc-core1/) | Planned |

## License

Apache-2.0
75 changes: 75 additions & 0 deletions pr
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@

---
Промпт 1 — Source Tree Inventory

Мне нужно проанализировать кодовые базы-доноры для проекта xml-sec (Pure Rust XML Security).

### Агент 1: xmlsec1 (~/projects/sw/xml-sec/donors/xmlsec/)

Ты анализируешь исходный код xmlsec1 (C, XML Security Library) для справочного каталога.

ЗАДАЧА: Создать структурированный каталог исходников.

ПРАВИЛА ФИЛЬТРАЦИИ:
- ВКЛЮЧАТЬ: .c/.h файлы из: src/ (core), src/openssl/ (crypto backend), include/xmlsec/
- ВКЛЮЧАТЬ: tests/aleksey/ (reference test vectors — W3C compliance)
- ИСКЛЮЧАТЬ: src/nss/, src/gnutls/, src/mscrypto/, src/mscng/ (alternative crypto backends)
- ИСКЛЮЧАТЬ: win32/, docs/, scripts/, m4/
- ИСКЛЮЧАТЬ: файлы < 20 строк

ФОРМАТ ВЫВОДА — файл ~/projects/sw/xml-sec/.refs/xmlsec-tree.md

ПРОЦЕДУРА:
1. cd ~/projects/sw/xml-sec/donors/xmlsec/ && git rev-parse HEAD
2. Focus: src/c14n.c (canonicalization), src/xmldsig.c (signatures), src/xmlenc.c (encryption),
src/transforms.c (transform chain), src/keys.c (key management), src/x509.c (certificates)
3. Для каждого файла: read first 100 lines → describe struct/function signatures

### Агент 2: samael (~/projects/sw/xml-sec/donors/samael/)

Ты анализируешь исходный код samael (Rust, SAML2 library) — reference для XML signature handling.

ПРАВИЛА ФИЛЬТРАЦИИ:
- ВКЛЮЧАТЬ: src/ (all .rs files)
- ИСКЛЮЧАТЬ: tests/, examples/

Focus: как samael делает XML signature verification, где вызывает C xmlsec1, какие Rust structures определены.

ФОРМАТ ВЫВОДА — файл ~/projects/sw/xml-sec/.refs/samael-tree.md

---

Промпт 2 — Feature-Targeted Deep Analysis

FEATURE-БЛОКИ (8 штук):

1. C14N Inclusive — xmlsec1 src/c14n.c, алгоритм каноникализации, namespace processing, attribute sorting
2. C14N Exclusive — xmlsec1 src/c14n.c (exclusive mode), namespace rendering rules
3. XMLDSig Verify — xmlsec1 src/xmldsig.c, verification pipeline: Reference → DigestValue → SignatureValue
4. XMLDSig Sign — xmlsec1 src/xmldsig.c, signing pipeline: transforms → digest → sign
5. Transform Chain — xmlsec1 src/transforms.c, enveloped-signature transform, XPath filter
6. XMLEnc — xmlsec1 src/xmlenc.c, symmetric/asymmetric encryption, key wrapping
7. Key Management — xmlsec1 src/keys.c, src/x509.c, KeyInfo element processing
8. samael Integration — samael src/xmlsec.rs, how Rust SAML calls xmlsec1 FFI, what we replace

---

Промпт 3 — Architecture Documents

Создать ~/projects/sw/xml-sec/arch/ с документами:
- arch/c14n.md — Canonicalization design
- arch/xmldsig.md — Digital Signatures design
- arch/xmlenc.md — Encryption design
- arch/transforms.md — Transform pipeline design
- arch/keys.md — Key management design
- arch/ROADMAP.md — Phased implementation plan
- arch/DECISIONS.md — ADR log

---

Промпт 4 — Roadmap

Phase 1 (3 мес): C14N + XMLDSig verify-only → samael can use xml-sec for SAML assertion validation
Phase 2 (3 мес): XMLDSig sign + KeyInfo → full SAML IdP support
Phase 3 (3 мес): XMLEnc + full transform pipeline
Phase 4 (3 мес): W3C conformance test suite, production hardening, 1.0 release
23 changes: 23 additions & 0 deletions src/c14n/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//! XML Canonicalization (C14N).
//!
//! Implements:
//! - [Canonical XML 1.0](https://www.w3.org/TR/xml-c14n/)
//! - [Canonical XML 1.1](https://www.w3.org/TR/xml-c14n11/)
//! - [Exclusive XML Canonicalization](https://www.w3.org/TR/xml-exc-c14n/)

/// Canonicalization algorithm selection.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum C14nAlgorithm {
/// Canonical XML 1.0 (with comments).
Inclusive10WithComments,
/// Canonical XML 1.0 (without comments).
Inclusive10,
/// Canonical XML 1.1 (with comments).
Inclusive11WithComments,
/// Canonical XML 1.1 (without comments).
Inclusive11,
/// Exclusive Canonical XML (with comments).
Exclusive10WithComments,
/// Exclusive Canonical XML (without comments).
Exclusive10,
}
33 changes: 33 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//! Error types for xml-sec.

/// Errors that can occur during XML security operations.
#[derive(Debug, thiserror::Error)]
pub enum XmlSecError {
/// XML parsing error.
#[error("XML parse error: {0}")]
XmlParse(String),

/// Canonicalization error.
#[error("C14N error: {0}")]
Canonicalization(String),

/// Signature verification failed.
#[error("Signature verification failed: {0}")]
SignatureInvalid(String),

/// Unsupported algorithm.
#[error("Unsupported algorithm: {0}")]
UnsupportedAlgorithm(String),

/// Certificate error.
#[error("Certificate error: {0}")]
Certificate(String),

/// Cryptographic operation failed.
#[error("Crypto error: {0}")]
Crypto(String),

/// Key not found or invalid.
#[error("Key error: {0}")]
Key(String),
}
36 changes: 36 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//! # xml-sec — Pure Rust XML Security
//!
//! Drop-in replacement for libxmlsec1. XMLDSig, XMLEnc, C14N — no C dependencies.
//!
//! ## Features
//!
//! - **C14N** — XML Canonicalization (inclusive + exclusive)
//! - **XMLDSig** — XML Digital Signatures (sign + verify)
//! - **XMLEnc** — XML Encryption (encrypt + decrypt)
//! - **X.509** — Certificate-based key extraction
//!
//! ## Quick Start
//!
//! ```rust,no_run
//! use xml_sec::{XmlSigner, XmlVerifier};
//!
//! // Verify a signed XML document
//! let doc = std::fs::read_to_string("signed.xml").unwrap();
//! let cert = std::fs::read("cert.pem").unwrap();
//! let valid = XmlVerifier::new(&cert).verify(&doc).unwrap();
//! ```

#![deny(unsafe_code)]
#![deny(clippy::unwrap_used)]
#![warn(missing_docs)]

pub mod c14n;
pub mod error;

#[cfg(feature = "xmldsig")]
pub mod xmldsig;

#[cfg(feature = "xmlenc")]
pub mod xmlenc;

pub use error::XmlSecError;
3 changes: 3 additions & 0 deletions src/xmldsig/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//! XML Digital Signatures (XMLDSig).
//!
//! Implements [XML Signature Syntax and Processing](https://www.w3.org/TR/xmldsig-core1/).
3 changes: 3 additions & 0 deletions src/xmlenc/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//! XML Encryption (XMLEnc).
//!
//! Implements [XML Encryption Syntax and Processing](https://www.w3.org/TR/xmlenc-core1/).
Loading