Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
80fab03
feat(cli): add native xmlsec1 command
polaz Aug 13, 2026
91b6876
fix(cli): harden compatibility contracts
polaz Aug 13, 2026
a79bdd3
fix(ci): isolate oracle source checkout
polaz Aug 13, 2026
0e8e501
fix(cli): enforce compatibility contracts
polaz Aug 13, 2026
a3974a7
fix(cli): honor native input contracts
polaz Aug 14, 2026
07415fb
fix(cli): enforce compatibility contracts
polaz Aug 14, 2026
beb9af2
fix(cli): unify explicit key selection
polaz Aug 14, 2026
2763513
fix(cli): harden key and template handling
polaz Aug 14, 2026
404d5ad
fix(cli): align donor command contracts
polaz Aug 14, 2026
b11e45e
test(cli): pin node ceiling failure
polaz Aug 14, 2026
06f2626
fix(cli): honor donor selection contracts
polaz Aug 14, 2026
468e33d
fix(cli): select encrypted recipients by name
polaz Aug 14, 2026
d47f22a
fix(cli): derive help from command registry
polaz Aug 14, 2026
2ce9654
fix(cli): enforce template trust contracts
polaz Aug 14, 2026
da0b15e
fix(cli): align donor signing contracts
polaz Aug 14, 2026
c4bd151
docs(cli): clarify key format scopes
polaz Aug 14, 2026
9cddb71
fix(cli): complete key manager semantics
polaz Aug 15, 2026
33ed66f
fix(cli): preserve key metadata integrity
polaz Aug 15, 2026
7e1f27c
fix(cli): preserve generated key metadata
polaz Aug 15, 2026
79d5f0c
fix(cli): complete recipient metadata handling
polaz Aug 15, 2026
28ad257
fix(cli): validate encryption templates
polaz Aug 15, 2026
ba60657
fix(xmldsig): validate key info mutation
polaz Aug 15, 2026
9a38c18
fix(cli): enforce encryption contracts
polaz Aug 15, 2026
17bcccb
fix(cli): complete review contracts
polaz Aug 15, 2026
9ee0b5b
fix(cli): complete diagnostic contracts
polaz Aug 15, 2026
5a16177
fix(xml): distinguish ID namespace scopes
polaz Aug 15, 2026
0b42262
fix(cli): validate cipher template shape
polaz Aug 15, 2026
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
26 changes: 21 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ jobs:
with:
toolchain: "1.92.0"
- uses: Swatinem/rust-cache@v2
- name: Check native CLI upstream fixture snapshot
run: scripts/import-xmlsec1-cli-fixtures.sh --check
- run: >-
cargo run -p xml-sec-capability-ledger -- check
donors/xmlsec
Expand All @@ -59,7 +61,7 @@ jobs:
with:
toolchain: ${{ matrix.rust }}
- uses: Swatinem/rust-cache@v2
- run: cargo build --all-features
- run: cargo build --workspace --all-features

build:
runs-on: ubuntu-latest
Expand All @@ -79,20 +81,34 @@ jobs:
- uses: actions/checkout@v7
with:
persist-credentials: false
- name: Read pinned donor revision
id: test-donor-revision
run: |
commit="$(cat compatibility/libxmlsec1-1.3.13-donor-commit.txt)"
[[ "$commit" =~ ^[0-9a-f]{40}$ ]]
echo "commit=$commit" >> "$GITHUB_OUTPUT"
- uses: actions/checkout@v7
with:
repository: lsh123/xmlsec
ref: ${{ steps.test-donor-revision.outputs.commit }}
path: donors/xmlsec
persist-credentials: false
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust }}
- uses: taiki-e/install-action@nextest
- name: Refresh apt package index
run: sudo apt-get update
- name: Build pinned xmlsec1 for XMLDSig interop tests
- name: Build pinned xmlsec1 for external-oracle tests
env:
XMLSEC1_SOURCE_DIR: ${{ github.workspace }}/donors/xmlsec
run: |
sudo apt-get install --yes autoconf automake build-essential libltdl-dev libssl-dev libtool libxml2-dev pkg-config
scripts/install-xmlsec1.sh
"$XMLSEC1_BIN" --version
- uses: Swatinem/rust-cache@v2
- run: cargo nextest run --all-features
- run: cargo test --doc --all-features
- run: cargo nextest run --workspace --all-features
- run: cargo test --doc --workspace --all-features

test:
runs-on: ubuntu-latest
Expand All @@ -111,7 +127,7 @@ jobs:
with:
components: clippy
- uses: Swatinem/rust-cache@v2
- run: cargo clippy --all-features --all-targets -- -D warnings
- run: cargo clippy --workspace --all-features --all-targets -- -D warnings

fmt:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ categories = ["cryptography", "web-programming", "authentication"]
readme = "README.md"

[workspace]
members = [".", "tools/capability-ledger"]
members = [".", "tools/capability-ledger", "tools/xmlsec1"]
Comment thread
polaz marked this conversation as resolved.
resolver = "3"

[[example]]
Expand Down
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ XML Security in pure Rust, built to replace libxmlsec1.
- **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** — `xmlsec1` command surface backed by the same Rust policy and provider pipelines

## Why?

Expand Down Expand Up @@ -65,6 +66,46 @@ 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:

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

The native binary supports sign/verify, template-preserving encrypt/decrypt,
AES key generation, capability checks, libxmlsec1 key aliases and option syntax,
certificate-chain embedding, stdin input, signature selection by node ID, and
deterministic process statuses. `help-all` enumerates the same registered
commands and options accepted by the parser; donor option multiplicity is
enforced across canonical and alias spellings, and `--print-xml-debug` emits
parseable operation diagnostics separately from `--output`. Named signing keys require a
template `KeyName`, while repeatable named verification and encryption/decryption
options form key sets from which the selected XML `KeyName` must identify exactly
one key unless lax lookup is requested; unnamed templates still use their sole
explicit verification or encryption key. Certificate companions are validated
even when no output `KeyInfo` placeholder is present; embedding a chain fills an
empty `X509Data` placeholder without discarding sibling `KeyInfo` sources.
Populated `KeyInfo` is materialized before reference digests, allowing it to be
signed by ID; writer attributes are merged without overwriting conflicting
template identity. Preserved XMLEnc recipient key or certificate metadata must
match its selected RSA wrapping key, and multi-recipient templates wrap the
content key independently for every named recipient.
Document-supplied X.509 certificates require a caller trust anchor unless
`--insecure` is explicit. XML payload encryption materializes inferred Element
metadata, and direct AES keys reject templates containing recipient
`EncryptedKey` metadata they cannot refresh. Its process tests run a minimal
checked-in
snapshot of the unmodified upstream DSig, Enc, and Keys runners without network
access or a system `xmlsec1` installation.
Unsupported algorithms, key formats, providers, and policy controls fail closed
instead of being silently ignored. See the [CLI compatibility guide](docs/cli.md)
for commands, examples, current format coverage, and upstream runner validation.

## XMLDSig Usage

`examples/sign.rs` builds an enveloped RSA-SHA256 signature and `examples/verify.rs`
Expand Down
31 changes: 29 additions & 2 deletions compatibility/libxmlsec1-1.3.13-rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
"test": "capability_ledger::backend_surface_distinguishes_provider_capabilities_from_unimplemented_apis",
"description": "Only backend transform classes backed by native provider operations are provider-limited; every other backend-specific C entry point remains planned."
},
"native-cli-tests": {
"test": "capability_ledger::native_cli_claims_match_process_and_upstream_runner_tests",
"description": "Process tests cover native command parsing, exit statuses, sign/verify and encrypt/decrypt paths; the unmodified upstream DSig, Enc, and Keys runners exercise the same binary and capability registry."
},
"planned-surface": {
"test": "capability_ledger::planned_surface_is_never_reported_as_supported",
"description": "Unimplemented backend APIs, CLI, registry, format, URI, and donor-suite entries remain machine-readable planned work."
Expand Down Expand Up @@ -110,11 +114,34 @@
"rationale": "libxmlsec1 registry entry points are inventoried for the future compatibility layer and are not exposed by the native API.",
"evidence": "planned-surface"
},
{
"id": "native-cli-commands",
"kinds": ["cli-command"],
"outcome": "behavior-compatible",
"rationale": "The native binary implements the libxmlsec1 command spelling and dispatch contract while capability checks delimit the available algorithm and key-data subsets.",
"evidence": "native-cli-tests"
},
{
"id": "native-cli-options",
"kinds": ["cli-option"],
"name_regex": "^--(?:aes-key|binary-data|crypto|gen-key|help|ignore-manifests|insecure|node-id|output|pkcs8-der|pkcs8-pem|privkey-der|privkey-pem|pubkey-cert-der|pubkey-cert-pem|pubkey-der|pubkey-pem|trusted-der|trusted-pem|untrusted-der|untrusted-pem|xml-data)$",
"outcome": "provider-limited",
"rationale": "The native CLI parses and executes this option for the RustCrypto-backed formats and algorithms advertised by its capability registry.",
"evidence": "native-cli-tests"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
},
{
"id": "native-cli-exit-status",
"kinds": ["cli-exit-status"],
"name_regex": "^(?:success|failure)$",
"outcome": "behavior-compatible",
"rationale": "Successful operations exit zero and parse, policy, capability, verification, cryptographic, and I/O failures exit non-zero.",
"evidence": "native-cli-tests"
},
{
"id": "planned-cli-surface",
"kinds": ["cli-command", "cli-option", "cli-exit-status"],
"kinds": ["cli-option", "cli-exit-status"],
"outcome": "planned",
"rationale": "A command-compatible xmlsec1 CLI is not yet shipped; commands, typed options, and exit semantics remain explicit roadmap surface.",
"rationale": "This libxmlsec1 option or special status behavior is inventoried but is not yet reproduced by the native CLI.",
"evidence": "planned-surface"
},
{
Expand Down
Loading