Skip to content

feat(seal): eID Easy QES sealing — wire types and decision record - #57

Draft
LKSNDRTMLKV wants to merge 1 commit into
mainfrom
feat/eideasy-qeseal
Draft

feat(seal): eID Easy QES sealing — wire types and decision record#57
LKSNDRTMLKV wants to merge 1 commit into
mainfrom
feat/eideasy-qeseal

Conversation

@LKSNDRTMLKV

Copy link
Copy Markdown
Member

Summary

Draft — parked until eID Easy sandbox credentials arrive. Opened now so the sealing work has a home and stays off every other branch while we wait.

dpp-seal was built against an assumption — the Cloud Signature Consortium API producing JAdES — that does not match the provider actually being onboarded. This records the corrected decision and lands the wire types for it. No behaviour changes: QtspSealAdapter still delegates to GhostSeal, and a production node still refuses to boot while the seal port resolves to a ghost.

Related issue

None. Decision record lives with the crate: crates/dpp-seal/DECISION-eideasy-cades.md.

Changes

  • Provider decision recorded. eID Easy Cloud Direct e-Sealing, aggregating qualified QTSPs (InfoCert, Intesi Group), producing CAdES over the payload digest — not CSC credentials/sign, and not JAdES. The doc separates [verified] facts from [confirm] items still open with the provider.
  • eideasy module addedEsealRequest/EsealFile/EsealResponse/EsealSignatureOut wire types, and hmac_message(), the pure helper that composes METHOD + PATH + X-Timestamp + RAW_BODY. Both are unit-tested against the documented example without network or crypto.
  • client.rs is a reserved seat, not an implementation. The HTTP call is deliberately absent until sandbox credentials exist — the module doc carries the full wiring plan so whoever picks it up does not re-derive it.
  • Stale assumptions marked in place rather than silently left: csc/mod.rs is flagged superseded (retained only as a possible alternate-QTSP path), lib.rs's module doc no longer describes CSC/OAuth as the model, and tests.rs says explicitly that its SealFormat::Jades is stale and awaiting a Cades variant in dpp_domain.

Why CAdES is not a downgrade

eIDAS Art. 35(2) attaches the integrity/origin presumption to a seal being qualified — a qualified certificate from a QTSP — not to the AdES envelope. CAdES, XAdES and PAdES are of equal standing; CAdES is the CMS-based form for arbitrary content, which is exactly digest-sealing. Detached-CAdES-over-hash also fits proof-bound better than enveloped JAdES: only a hash and a detached signature ever leave the node.

Not yet claimable: no public source was found stating the EU DPP registry accepts CAdES specifically. It almost certainly validates the certificate chain rather than the envelope flavour, but until that is confirmed against the registry conformance profile, "registry-conformant CAdES" must not be stated as fact anywhere customer-facing.

What is blocked, and what is not

The sandbox needs no legal entity — it issues developer credentials and seals with eID Easy's own test certificates. The entity, the QTSP document list and the ~2-week registration gate production only. So the entire pipeline can be wired and green-tested before incorporation; going live is then a credential swap against the same code path.

Blocked on: sandbox client_id + e-seal HMAC key (account created, approval pending).

Checklist

  • Tests added or updated for new behaviour
  • just lint passes locally
  • just fmt applied
  • just test passes (unit) — dpp-seal 7/7; no persistence/lifecycle/auth change, so the Docker tiers are unaffected
  • No println!/eprintln!/dbg! in service-crate src/
  • No secrets, credentials, or .env files in the diff
  • Docs updated if a public API, endpoint, or CLI command changed
  • If the DB schema changed — no schema change in this PR

Before this leaves draft

  1. Sandbox credentials in hand; client.rs implemented per the module doc — serialize the body once, HMAC those exact bytes, send those exact bytes. reqwest's .json() re-serializes and silently breaks the HMAC.
  2. SealFormat::Cades added in dpp_domain, and tests.rs switched off Jades.
  3. Green gate per the decision doc §8: real seal against test.eideasy.com, the returned CAdES validated by an independent validator (not our own code), a rotated key producing a clean typed error rather than a panic, and GhostSeal fallback still intact.
  4. The four [confirm] items in §9 closed with the provider.

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 complexity · 0 duplication

Metric Results
Complexity 0
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

Lands the request/response types and the HMAC message helper for eID Easy Cloud Direct e-Sealing, and marks the crate's CSC/JAdES assumptions superseded; the HTTP call is a reserved seat pending sandbox credentials. The provider decision itself is recorded privately as ADR-009, since it carries commercial state.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant