diff --git a/EnvelopeGenerator.Infrastructure.Crypt/README.md b/EnvelopeGenerator.Infrastructure.Crypt/README.md index 4dab4888..678b7abb 100644 --- a/EnvelopeGenerator.Infrastructure.Crypt/README.md +++ b/EnvelopeGenerator.Infrastructure.Crypt/README.md @@ -1,67 +1,83 @@ # EnvelopeGenerator.Infrastructure.Crypt -This project provides PKCS#11-based cryptographic infrastructure for FES (Advanced Electronic Signature) workflows. +PKCS#11-based cryptographic infrastructure for FES (Advanced Electronic Signature) workflows. -If you are new to HSM/SoftHSM: this README is written to let you start from zero and still understand the full path from setup to testing. +Official references: + +- SoftHSMv2 (official): `https://github.com/softhsm/SoftHSMv2` +- OpenSC `pkcs11-tool` docs: `https://github.com/OpenSC/OpenSC/wiki/Using-pkcs11-tool-and-OpenSSL` +- PKCS#11 standard overview (OASIS): `https://www.oasis-open.org/committees/pkcs11/` --- -## 1) What this project is (and what it is not) +## 1) Scope -This project is the cryptography layer only. +This project is the crypto layer only. -- It signs hashes using private keys stored in HSM/SoftHSM. -- It reads certificates from HSM/SoftHSM. -- It verifies signatures. -- It exposes service abstractions for Application/Server integration. +- Signs hashes via keys in HSM/SoftHSM. +- Reads certificates from HSM/SoftHSM. +- Verifies signatures. +- Exposes abstractions for Application/Server integration. -It is **not**: +This project is not: -- a REST API by itself, -- a UI component, -- a full document workflow orchestrator. +- a REST API, +- a UI module, +- a full document orchestration workflow. --- -## 2) SoftHSM and PKCS#11 in one minute +## 2) SoftHSM and PKCS#11 basics -- `SoftHSMv2` is a software HSM implementation. -- It does **not** provide a REST endpoint. -- You access it through a PKCS#11 library/module (`.so`/`.dll`). -- Your app loads that library and calls PKCS#11 functions. +- SoftHSM is a software implementation of an HSM. +- It does not expose REST endpoints. +- Access is via PKCS#11 shared library (`.so`/`.dll`). +- App loads module path and performs PKCS#11 operations. -Two deployment patterns are possible: +Supported deployment patterns: -1. **Direct local module** - - Example library path: `libsofthsm2.so` -2. **PKCS#11 proxy module (remote HSM/SoftHSM)** - - Example library path: `libpkcs11-proxy.so` or proxy DLL +1. Direct module (`libsofthsm2.so`, `softhsm2-x64.dll`, etc.) +2. PKCS#11 proxy module (remote HSM/SoftHSM backend) -Both are valid for this project. +Critical platform rule: + +- A Windows process cannot load a Linux `.so` directly. +- `Crypt:Pkcs11:LibraryPath` must always point to a native library compatible with the host OS of `EnvelopeGenerator.Server`. --- -## 3) How this maps to the FES diagram (Ablauf SignFlow Unternehmenszertifikat) +## 2.1) Windows Server + Linux SoftHSM architecture (decision TODO) -From the shared draw.io/PDF process: +Current business requirement: `EnvelopeGenerator.Server` runs on Windows, SoftHSM runs on Linux. -- Step 6: Backend computes document hash and sends it with PIN context to HSM. - - Implemented by: `ISignatureProvider` / `Pkcs11SignatureProvider` -- Step 7: HSM returns digital signature (and cert context can be resolved). - - Implemented by: `Pkcs11SignatureProvider` + `ICertificateProvider` -- Step 8: Backend embeds signature + certificate into PDF and creates audit trail. - - This project provides crypto primitives for this step. - - PDF embedding and audit document composition are integrated in later layers. +This repository must use one of the following three paths: -So this project is the cryptographic core for diagram steps 6-8. +1. Linux signing service (recommended) + - Windows `EnvelopeGenerator.Server` calls HTTPS signing API. + - Linux service performs PKCS#11 operations against SoftHSM. + - Private keys stay on Linux. +2. PKCS#11 proxy bridge + - Windows app loads a Windows PKCS#11 proxy client DLL. + - Proxy forwards operations to Linux-side PKCS#11 endpoint connected to SoftHSM. +3. Local Windows SoftHSM (dev/test only, optional) + - SoftHSM is also installed on Windows. + - App talks to local Windows PKCS#11 module. -Actor mapping from the diagram: +TODO - architecture lock-in: -- `Ersteller` (sender): creates envelope and defines recipients. -- `Signierer` (recipient/signer): completes 2FA and signs. -- `Backend` (our stack): computes hash, requests HSM signature, embeds proof in PDF. -- `HSM/SoftHSM`: stores private keys and performs cryptographic signing. -- `CA`: issues/renews certificates. +- [ ] Select one path as production standard (`1` is recommended). +- [ ] Document final runtime topology (hosts, ports, TLS, auth). +- [ ] Define where audit metadata (IP/email/phone/device) is stored and signed/linked. +- [ ] Update `SignatureController.Submit` integration contract for FES branch. +- [ ] Add environment-specific runbook for Windows host + Linux HSM operations. + +--- + +## 3) FES flow mapping + +- Step 6: hash is sent to HSM signing operation -> `ISignatureProvider` +- Step 7: signature and certificate context are resolved -> `Pkcs11SignatureProvider`, `ICertificateProvider` +- Step 8: PDF embedding + audit trail are completed by upper layers; this project provides crypto primitives --- @@ -80,19 +96,17 @@ DI entry point: --- -## 5) Required configuration +## 5) Runtime configuration Configuration section: `Crypt:Pkcs11` -Typical keys: - ```json { "Crypt": { "Pkcs11": { "LibraryPath": "/usr/lib/softhsm/libsofthsm2.so", - "SlotId": 0, - "TokenLabel": null, + "SlotId": 1720207650, + "TokenLabel": "DevToken", "UserPin": "***", "PrivateKeyLabel": "sign-key", "PrivateKeyIdHex": null, @@ -103,297 +117,273 @@ Typical keys: } ``` -Security rule: +Security rules: -- Do not commit real PINs to source control. -- Use environment variables / secret vault for production. +- Never commit real PINs. +- Use environment variables or secret vault. +- Use test-only tokens for development. + +Production naming convention used in this repository: + +- Token label: `CompanyProdToken` +- Private key label: `company-sign-key-v1` +- Certificate label: `company-sign-cert-v1` + +These names are also exposed as constants in `EnvelopeGenerator.Infrastructure.Crypt/Options/Pkcs11ProviderOptions.cs`. --- -## 6) The 5 test values you must provide +## 6) Test configuration source -Integration tests need these environment variables: +Crypt tests read PKCS#11 values from `EnvelopeGenerator.Tests/appsettings.json` under `Crypt:Pkcs11`. -- `FES_TEST_PKCS11_LIBRARY_PATH` -- `FES_TEST_PKCS11_SLOT_ID` -- `FES_TEST_PKCS11_USER_PIN` -- `FES_TEST_PKCS11_PRIVATE_KEY_LABEL` -- `FES_TEST_PKCS11_CERTIFICATE_LABEL` +Required keys: -Without these values, integration tests are skipped by design. +- `Crypt:Pkcs11:LibraryPath` +- `Crypt:Pkcs11:SlotId` (or `Crypt:Pkcs11:TokenLabel`) +- `Crypt:Pkcs11:UserPin` +- `Crypt:Pkcs11:PrivateKeyLabel` +- `Crypt:Pkcs11:CertificateLabel` -## 6.1 Which certificate/key should be created? - -This is the most important business decision for IT and architecture. - -Based on your shared diagram, the **primary model** is: - -- one **company certificate + company key pair** in HSM, -- reused for all signers, -- signer identity proven by audit-trail + 2FA evidence. - -What this means in practical terms: - -- Not one key per sender. -- Not one key per recipient by default. -- One company signing identity, many signing events. - -Alternative model (future/optional): - -- per-signer certificate/key pair (more complex CA lifecycle). - -For current fast validation and your FES flow, use the **company-level key/certificate** model. +No environment variable is required for crypt tests in this repository anymore. --- -## 7) How to obtain these values (IT-friendly) +## 7) Full SoftHSM lifecycle runbook (project scope) -## 7.1 If you use direct SoftHSM module - -### A) Find module path - -What it is: - -- PKCS#11 shared library file used by the app to talk to SoftHSM. - -Why needed: - -- Without this exact file path, PKCS#11 cannot be loaded. - -Linux examples: +### 7.1 Discover module path ```bash ldconfig -p | grep softhsm find /usr -name "libsofthsm2.so" 2>/dev/null ``` -Use the resolved full path as `FES_TEST_PKCS11_LIBRARY_PATH`. - -### B) List slots/tokens - -What it is: - -- Slot: logical container position in PKCS#11. -- Token: initialized security container in a slot. - -Why needed: - -- The app must know which slot/token contains the company key and certificate. +### 7.2 List slots/tokens ```bash softhsm2-util --show-slots ``` -Pick your slot as `FES_TEST_PKCS11_SLOT_ID`. - -### C) Identify key and certificate labels - -What it is: - -- `Private key label`: name of the signing private key object. -- `Certificate label`: name of the matching X.509 certificate object. - -Why needed: - -- Tests and runtime use labels to select correct objects in HSM. - -Use `pkcs11-tool` against your module: +### 7.3 Create new token (recommended for new company/test tenant) ```bash -pkcs11-tool --module /path/to/libsofthsm2.so --slot --login --pin --list-objects +softhsm2-util --init-token --slot --label --so-pin --pin ``` -From output: +Important: -- private key label -> `FES_TEST_PKCS11_PRIVATE_KEY_LABEL` -- certificate label -> `FES_TEST_PKCS11_CERTIFICATE_LABEL` +- After init, token is reassigned to a new slot id. +- Re-run `--show-slots` and use the new slot id. -### D) User PIN - -What it is: - -- User authorization secret to open authenticated session on token. - -Why needed: - -- HSM will not allow signing with private key without login. - -PIN is assigned during token initialization and must be provided by IT/security team. - -### E) Optional: Initialize token and create objects (Linux quick bootstrap) - -Only if token/keys are not already provisioned by IT PKI team. +### 7.4 Login and inspect objects ```bash -# 1) Initialize token in slot 0 (example) -softhsm2-util --init-token --slot 0 --label "CompanySignToken" +pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --slot --login --pin --list-objects +``` -# 2) Verify slot/token -softhsm2-util --show-slots +### 7.5 Generate company signing key pair -# 3) Generate RSA key pair inside token (example) -pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --slot 0 --login --pin \ +```bash +pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --slot --login --pin \ --keypairgen --key-type rsa:3072 --label sign-key --id 01 +``` -# 4) Import certificate (already issued by CA) -pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --slot 0 --login --pin \ +### 7.6 Import company certificate + +```bash +pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --slot --login --pin \ --write-object company-sign-cert.der --type cert --label sign-cert --id 01 - -# 5) List objects and confirm labels -pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --slot 0 --login --pin --list-objects ``` -Notes: +### 7.7 Read object metadata (for diagnostics) -- Use this only in non-production unless approved. -- In production, key generation/import should follow company security policy. +```bash +pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --slot --login --pin --list-objects +pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --slot --login --pin --list-mechanisms +``` -## 7.2 If you use PKCS#11 proxy module +### 7.8 Update operations -What it is: +PKCS#11 objects are usually immutable for key/cert payload; updates are done by rotation: -- A local PKCS#11 bridge library that forwards calls to remote HSM/SoftHSM service. +1. Create/import new key/cert with new label or id. +2. Update app config/env labels. +3. Validate with integration tests. +4. Delete old objects when safe. -Why needed: +PIN operations: -- App still loads a local module path, but crypto operations happen remotely. +- User PIN change (while logged in): -Ask IT for: +```bash +pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --slot --login --pin --change-pin --new-pin +``` -- proxy module path (`libpkcs11-proxy.*`) -- slot id or token label -- user pin -- private key label -- certificate label +- User PIN reset via SO credentials: -In proxy mode, values come from proxy-backed token, not local SoftHSM token files. +```bash +softhsm2-util --init-pin --slot --so-pin --pin +``` + +### 7.9 Delete operations + +Delete by label/id/type: + +```bash +pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --slot --login --pin \ + --delete-object --type cert --label sign-cert +``` + +Token-level destructive reset (do not use unless approved): + +```bash +softhsm2-util --delete-token --token +``` --- -## 7.3 Linux handover checklist for IT (copy/paste friendly) +## 8) New company onboarding checklist -1. Confirm module path exists (`libsofthsm2.so` or proxy module). -2. Confirm token exists and slot id is known. -3. Confirm company private key label and certificate label. -4. Confirm user PIN for test environment. -5. Share these five values securely with development team. +For company-level signing model (one company key/cert pair): + +1. Create token with company label (or assign dedicated token in remote HSM). +2. Generate key pair in token. +3. Obtain CA certificate and import into token. +4. Record secure runtime values: + - module path + - slot id or token label + - user pin + - private key label + - certificate label +5. Run crypt integration tests. +6. Store values in vault and wire app environment. --- -## 8) Test execution checklist (single command flow) +## 9) Rotation/update checklist -## 8.1 Set environment variables +1. Create new key/cert (`sign-key-v2`, `sign-cert-v2`). +2. Configure app env to new labels. +3. Run integration tests. +4. Deploy. +5. Keep old key/cert during grace period. +6. Remove old key/cert after legal/operational confirmation. -PowerShell example: +--- -```powershell -$env:FES_TEST_PKCS11_LIBRARY_PATH = "" -$env:FES_TEST_PKCS11_SLOT_ID = "" -$env:FES_TEST_PKCS11_USER_PIN = "" -$env:FES_TEST_PKCS11_PRIVATE_KEY_LABEL = "" -$env:FES_TEST_PKCS11_CERTIFICATE_LABEL = "" -``` +## 10) Running tests -Linux (bash) example: +Before running, configure `EnvelopeGenerator.Tests/appsettings.json` -> `Crypt:Pkcs11` with real Linux SoftHSM values. + +Run crypt tests: ```bash -export FES_TEST_PKCS11_LIBRARY_PATH="/usr/lib/softhsm/libsofthsm2.so" -export FES_TEST_PKCS11_SLOT_ID="0" -export FES_TEST_PKCS11_USER_PIN="" -export FES_TEST_PKCS11_PRIVATE_KEY_LABEL="sign-key" -export FES_TEST_PKCS11_CERTIFICATE_LABEL="sign-cert" -``` - -Verify env values quickly: - -```bash -echo "$FES_TEST_PKCS11_LIBRARY_PATH" -echo "$FES_TEST_PKCS11_SLOT_ID" -echo "$FES_TEST_PKCS11_PRIVATE_KEY_LABEL" -echo "$FES_TEST_PKCS11_CERTIFICATE_LABEL" -``` - -## 8.2 Run only crypt tests - -```powershell dotnet test "EnvelopeGenerator.Tests/EnvelopeGenerator.Tests.csproj" -f net8.0 --filter "FullyQualifiedName~EnvelopeGenerator.Tests.Application.Crypt" ``` -Expected: +--- -- Unit tests pass always. -- Integration tests pass when env values are correct. -- Integration tests skip when env values are missing. +## 11) Common failures -If all five values are correct: - -- integration tests run automatically, -- no code change is required, -- only environment setup is required. +- `CKR_PIN_INCORRECT`: wrong user pin for that token. +- `CRYPT_PROVIDER_UNAVAILABLE`: bad module path or native load issue. +- `CRYPT_SLOT_NOT_FOUND`: wrong slot id or token label. +- `CRYPT_LOGIN_FAILED`: login failed (pin/token mismatch). +- `CRYPT_KEY_NOT_FOUND`: key label/id mismatch. +- `CRYPT_CERT_NOT_FOUND`: certificate label/id mismatch. --- -## 9) Common failure meanings +## 12) Integration note -- `CRYPT_PROVIDER_UNAVAILABLE` - - invalid library path, missing native dependency, provider cannot load -- `CRYPT_SLOT_NOT_FOUND` - - wrong slot id or token label -- `CRYPT_LOGIN_FAILED` - - wrong PIN -- `CRYPT_KEY_NOT_FOUND` - - private key label/id mismatch -- `CRYPT_CERT_NOT_FOUND` - - certificate label/id mismatch - -This is exactly what IT needs for first-level diagnostics. +Current implementation uses `CKM_SHA256_RSA_PKCS` while caller provides hash bytes. Validate mechanism semantics in your provider/HSM policy. If provider expects raw payload instead of digest for selected mechanism, signing flow must be adjusted. --- -## 10) Integration in the full stack architecture +## 13) Production-first onboarding (single-line checkpoints) -Current role by layer: +This section is the authoritative path for production-style setup (critical documents, FES). -- `Infrastructure.Crypt` (this project): PKCS#11 crypto operations -- `Application`: orchestration use-cases and business process steps -- `Server`: API endpoints and presentation concerns +### 13.1 Step 1 - Initialize dedicated company token -Recommended integration path: +One-line command: -1. Stabilize crypt tests and environment setup (this stage). -2. Integrate `ISignatureProvider` + `ICertificateProvider` into Application command flow. -3. Connect Application flow to Server endpoints. -4. Add PDF embedding and audit-trail generation for full step-8 compliance. -5. Add archiving/distribution orchestration for steps 9-10. +```bash +mkdir -p ./fes-prod && cd ./fes-prod && export SO_PIN="$(openssl rand -hex 16)" USER_PIN="$(openssl rand -hex 12)" && softhsm2-util --init-token --slot --label CompanyProdToken --so-pin "$SO_PIN" --pin "$USER_PIN" && softhsm2-util --show-slots +``` ---- +Checkpoint: -## 11) Important note about signing semantics +- Token appears as initialized with label `CompanyProdToken`. +- SoftHSM reassigns token to a new slot ID; use that slot ID in all next commands. -PKCS#11 mechanisms differ in whether they expect raw data or a precomputed digest. +Security note: -Current implementation signs with `CKM_SHA256_RSA_PKCS` and receives hash bytes from caller. -This must be validated in your real provider environment. +- Do not print/store PINs in shell history in real production operations. +- Persist secrets in a vault or protected secret store. -If provider expects raw data for this mechanism, integration may require adjustment. -This is why integration tests are critical. +### 13.2 Step 2 - Generate company signing key pair inside HSM ---- +One-line command: -## 12) Quick FAQ +```bash +pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --slot --login --pin "$USER_PIN" --keypairgen --key-type rsa:3072 --label company-sign-key-v1 --id 01 && pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --slot --login --pin "$USER_PIN" --list-objects +``` -**Q: Do I need REST calls to SoftHSM?** +Checkpoint: -No. SoftHSM is not a REST server. Use PKCS#11 library calls. +- `Private Key Object` and `Public Key Object` exist for label `company-sign-key-v1`, id `01`. +- Private key remains non-extractable in token. -**Q: Can I use proxy and still call it SoftHSM setup?** +### 13.3 Step 3 - Obtain CA-issued certificate for HSM key -Yes. Proxy can forward to SoftHSM-backed token infrastructure. +Required policy: -**Q: Once I provide the 5 values, can tests run directly?** +- Certificate must be issued by enterprise CA for the key generated in token. +- Do not use self-signed cert for production signing identity. -Yes. Set env vars and run the single `dotnet test` command above. +Operational note: -**Q: Will one company cert/key be enough for this phase?** +- CSR generation method depends on installed PKCS#11 OpenSSL integration (`engine_pkcs11` / provider). +- After CA issues certificate, import certificate DER into token with matching id/label family. -Yes, for the diagram-aligned company-signing model, one company key/certificate is enough for initial implementation and validation. +OpenSSL 3 prerequisite check: + +```bash +openssl version && openssl engine -t -c 2>/dev/null | grep -i pkcs11 || true +``` + +If no PKCS#11 engine/provider is listed, install integration packages first (distribution specific), then continue. + +### 13.4 Step 4 - Import CA certificate into token + +One-line command: + +```bash +pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --slot --login --pin "$USER_PIN" --write-object ./company-sign-cert-v1.der --type cert --id 01 --label company-sign-cert-v1 && pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --slot --login --pin "$USER_PIN" --list-objects +``` + +Checkpoint: + +- `Certificate Object` exists with id `01` and expected label. + +### 13.5 Step 5 - Wire runtime/test configuration + +Server runtime (`EnvelopeGenerator.Server/EnvelopeGenerator.Server/appsettings.json`) must include: + +- `Crypt:Pkcs11:LibraryPath` = native PKCS#11 library path for the server host OS + - Windows host: Windows DLL path (vendor DLL or proxy client DLL) + - Linux host: Linux `.so` path +- `Crypt:Pkcs11:SlotId` = `2021549410` (or current company slot) +- `Crypt:Pkcs11:TokenLabel` = `CompanyProdToken` +- `Crypt:Pkcs11:UserPin` = real user pin +- `Crypt:Pkcs11:PrivateKeyLabel` = `company-sign-key-v1` +- `Crypt:Pkcs11:CertificateLabel` = `company-sign-cert-v1` + +Test runtime (`EnvelopeGenerator.Tests/appsettings.json`) must mirror the same `Crypt:Pkcs11` values. + +Then run tests: + +```bash +dotnet test "EnvelopeGenerator.Tests/EnvelopeGenerator.Tests.csproj" -f net8.0 --filter "FullyQualifiedName~EnvelopeGenerator.Tests.Application.Crypt" +``` diff --git a/EnvelopeGenerator.Infrastructure.Crypt/resources/INFRASTRUCTURE_PLAN.md b/EnvelopeGenerator.Infrastructure.Crypt/resources/INFRASTRUCTURE_PLAN.md new file mode 100644 index 00000000..d877e878 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure.Crypt/resources/INFRASTRUCTURE_PLAN.md @@ -0,0 +1,301 @@ +# FES Signature Infrastructure Plan + +## 1. Goal + +Build a reusable and modular cryptography infrastructure in `EnvelopeGenerator.Infrastructure.Crypt` to support FES (Advanced Electronic Signature) workflows. + +This module must: + +- use PKCS#11 providers (SoftHSMv2 first, real HSM later), +- stay independent from UI/API concerns, +- expose clean interfaces to `Application` layer use-cases, +- support future extensions (timestamping, certificate chain validation, multiple key algorithms). + +--- + +## 2. Context and Constraints + +1. SoftHSMv2 is **not** a REST service. It is a PKCS#11 module loaded as a native library. +2. `EnvelopeGenerator.Server` is presentation only; cryptographic implementation belongs to infrastructure. +3. Clean Architecture boundaries must be respected: + - `Application` depends on abstractions. + - `Infrastructure.Crypt` implements abstractions. +4. Initial target framework is `net8.0`. +5. We need production-ready behavior, not only PoC signing. + +--- + +## 3. High-Level Design + +## 3.1 Architecture slice + +- **Application layer (contracts/use-cases):** + - request signing hash/document, + - request certificate/public key material, + - request verification, + - consume signature evidence result. + +- **Infrastructure.Crypt layer (this project):** + - PKCS#11 session handling, + - key/certificate object discovery, + - hash signing operations, + - local cryptographic verification, + - certificate parsing helpers, + - error normalization. + +## 3.2 Provider model + +Define provider-agnostic APIs and add one concrete provider first: + +- `Pkcs11SignatureProvider` (primary) +- future providers: + - `RemoteSigningProvider` (if a dedicated signing gateway is introduced) + - `MockSignatureProvider` (for deterministic test scenarios) + +--- + +## 4. Deliverables (Phase by Phase) + +## Phase 0 - Contracts and Domain Language + +Create neutral models and interfaces in `Infrastructure.Crypt` (or shared abstractions if needed later): + +- `SigningAlgorithm` (enum/value object) +- `Pkcs11ProviderOptions` +- `KeyLocator` (label/id/slot/token selectors) +- `SignHashRequest` +- `SignHashResult` +- `VerifySignatureRequest` +- `VerifySignatureResult` +- `CertificateDescriptor` +- `SignatureEvidence` (technical evidence payload) + +Interfaces: + +- `ISignatureProvider` +- `ICertificateProvider` +- `ISignatureVerifier` +- `ICryptographicHealthCheck` + +Acceptance criteria: + +- no dependency on ASP.NET types, +- no UI/API naming leakage, +- all model names are business-neutral. + +## Phase 1 - PKCS#11 Core Adapter (SoftHSM-ready) + +Implement: + +- `Pkcs11LibraryLoader` +- `Pkcs11SessionFactory` +- `Pkcs11ObjectFinder` +- `Pkcs11SignatureProvider` +- `Pkcs11CertificateProvider` + +Capabilities: + +1. load module path from options (`libsofthsm2.so` or proxy module when required), +2. enumerate slots/tokens, +3. open read-write session, +4. login with user pin, +5. find private key by label/id, +6. sign digest with selected mechanism, +7. read certificate object by label/id. + +Acceptance criteria: + +- deterministic disposal of sessions, +- no leaked native handles, +- detailed typed errors (not raw exception strings only). + +## Phase 2 - Verification and Certificate Utilities + +Implement: + +- `DefaultSignatureVerifier` +- `X509CertificateParser` +- optional `CertificateChainValidator` (toggleable) + +Capabilities: + +1. verify signature using returned certificate/public key, +2. expose certificate metadata (`thumbprint`, `subject`, `issuer`, `notBefore`, `notAfter`), +3. map validation failures into stable error codes. + +Acceptance criteria: + +- same request yields same verification outcome, +- invalid signature returns structured negative result. + +## Phase 3 - Evidence Builder + +Implement: + +- `SignatureEvidenceBuilder` + +Evidence payload should contain: + +- transaction/correlation id, +- algorithm, +- hash metadata, +- key locator snapshot (safe subset), +- certificate fingerprint and subject, +- sign timestamp (UTC), +- verification outcome, +- provider type (`PKCS11`). + +Acceptance criteria: + +- no secret values in evidence (pin, private key id internals), +- evidence serializable for storage/audit. + +## Phase 4 - Dependency Injection Module + +Implement: + +- `CryptInfrastructureDependencyInjection` extension methods + +Methods: + +- `AddCryptInfrastructure(...)` +- `AddPkcs11Provider(...)` + +Acceptance criteria: + +- one-line registration from composition root, +- options validation on startup. + +## Phase 5 - Test Suite (`EnvelopeGenerator.Tests`) + +Add test categories for `net8.0`: + +1. `Unit`: + - request validation, + - algorithm mapping, + - evidence building, + - error mapping. +2. `Integration` (conditional/manual profile): + - SoftHSM slot listing, + - login, + - sign hash, + - verify, + - certificate read. + +Acceptance criteria: + +- unit tests run in CI without native SoftHSM, +- integration tests run when module path + pins are provided via environment variables. + +--- + +## 5. Proposed Project Structure + +```text +EnvelopeGenerator.Infrastructure.Crypt/ + Abstractions/ + ISignatureProvider.cs + ICertificateProvider.cs + ISignatureVerifier.cs + ICryptographicHealthCheck.cs + Models/ + SigningAlgorithm.cs + SignHashRequest.cs + SignHashResult.cs + VerifySignatureRequest.cs + VerifySignatureResult.cs + SignatureEvidence.cs + CertificateDescriptor.cs + KeyLocator.cs + Options/ + Pkcs11ProviderOptions.cs + Pkcs11/ + Pkcs11LibraryLoader.cs + Pkcs11SessionFactory.cs + Pkcs11ObjectFinder.cs + Pkcs11SignatureProvider.cs + Pkcs11CertificateProvider.cs + Verification/ + DefaultSignatureVerifier.cs + X509CertificateParser.cs + Evidence/ + SignatureEvidenceBuilder.cs + DependencyInjection/ + CryptInfrastructureDependencyInjection.cs + Exceptions/ + CryptographicOperationException.cs + Pkcs11ProviderException.cs +``` + +--- + +## 6. Configuration Strategy + +Use options (bound from host config) with environment override support: + +- `Crypt:Provider = PKCS11` +- `Crypt:Pkcs11:LibraryPath` +- `Crypt:Pkcs11:SlotId` or token selectors +- `Crypt:Pkcs11:UserPin` (from secret store/env, not plain committed value) +- `Crypt:Pkcs11:PrivateKeyLabel` +- `Crypt:Pkcs11:CertificateLabel` +- `Crypt:Pkcs11:LoginType` + +Validation rules: + +- library path required, +- at least one key locator required, +- pin required for signing operations. + +--- + +## 7. Error Model + +Define stable error codes to prevent provider-specific leakage: + +- `CRYPT_PROVIDER_UNAVAILABLE` +- `CRYPT_SLOT_NOT_FOUND` +- `CRYPT_LOGIN_FAILED` +- `CRYPT_KEY_NOT_FOUND` +- `CRYPT_CERT_NOT_FOUND` +- `CRYPT_SIGN_FAILED` +- `CRYPT_VERIFY_FAILED` + +Map low-level exceptions to these codes with safe diagnostics. + +--- + +## 8. Non-Functional Requirements + +1. **Security:** never log pins or raw private key handles. +2. **Reliability:** deterministic cleanup (`IDisposable`/`IAsyncDisposable`). +3. **Observability:** structured logs with correlation id. +4. **Performance:** avoid repeated login per operation when a safe session strategy is available. +5. **Extensibility:** algorithm/provider mapping must be open for extension. + +--- + +## 9. Implementation Order (Small Tasks) + +1. Add models + interfaces. +2. Add options + validators. +3. Add PKCS#11 low-level loader/session wrappers. +4. Implement `Pkcs11SignatureProvider` for hash signing. +5. Implement certificate retrieval. +6. Implement verifier. +7. Implement evidence builder. +8. Add DI registration extension. +9. Add unit tests. +10. Add optional integration tests (SoftHSM profile). + +--- + +## 10. Definition of Done + +Done means: + +1. `Infrastructure.Crypt` exposes generic cryptographic services usable by Application use-cases. +2. SoftHSM-backed PKCS#11 sign/verify path works in integration tests. +3. All sensitive configuration is externalized. +4. Structured error codes are returned for expected failure scenarios. +5. Documentation exists for host registration and required settings. diff --git a/EnvelopeGenerator.Infrastructure.Crypt/resources/INTEGRATION_PLAN.md b/EnvelopeGenerator.Infrastructure.Crypt/resources/INTEGRATION_PLAN.md new file mode 100644 index 00000000..1b46d88c --- /dev/null +++ b/EnvelopeGenerator.Infrastructure.Crypt/resources/INTEGRATION_PLAN.md @@ -0,0 +1,228 @@ +# FES (Advanced Electronic Signature) Summary and Integration Plan - EN + +This document summarizes the shared diagram flow (`Ablauf SignFlow Unternehmenszertifikat`) and provides a small-step integration plan for the `EnvelopeGenerator` solution. + +--- + +## 1) Simplified flow summary + +Flow logic: + +1. The sender uploads a document and defines signers. +2. If a valid company certificate already exists in HSM, it is used with the company key pair. +3. If no valid company certificate exists, CA issuance/renewal flow is required. +4. The signer receives an e-mail with a signing link. +5. The signer completes SMS OTP (2FA) and performs UI signature interaction. +6. Backend computes the hash for the current signing stage and sends it to HSM. +7. HSM signs the hash with the private key and returns signature + certificate context. +8. Backend embeds digital signature and certificate into PDF and writes audit trail. +9. After all signers complete, the final artifact is archived. +10. The final signed document is distributed to signers. + +Important: The visible UI signature is not yet the legal electronic signature. The legal signature is produced in backend+HSM steps. + +--- + +## 2) Relation to current codebase (as-is) + +- `EnvelopeGenerator.Server` is the presentation layer host (Blazor + API hosting). +- Business flow is handled in `Application` via MediatR pipelines. +- Current receiver flow is centered around UI overlay/signature capture. +- Missing FES core: PKCS#11 hash-sign-verify + certificate-based PDF embedding pipeline. + +Critical deployment fact: + +- `EnvelopeGenerator.Server` is planned to run on Windows. +- SoftHSM is currently planned to run on Linux. +- A Windows process cannot directly load Linux PKCS#11 module (`libsofthsm2.so`). +- Therefore, architecture must include a compatibility bridge (service or proxy) unless HSM/SoftHSM is local to Windows. + +Conclusion: FES is not a replacement of the current flow; it is a cryptographic hardening layer behind it. + +--- + +## 3) Why SoftHSM tests are foundational + +The tests defined in `SOFTHSM_TEST_KILAVUZU_TR.md` are the technical prerequisite for FES: + +- `slots/login` -> HSM connectivity and authentication +- `certificate` -> certificate retrieval path +- `sign` -> hash signing with private key +- `verify` -> signature and certificate consistency validation + +Without these tests passing, diagram steps 6-8 should not go live. + +--- + +## 4) Target architecture (clean architecture aligned) + +### Deployment topology options (must choose one) + +1. **Linux signing service (recommended)** + - Windows `EnvelopeGenerator.Server` calls Linux signing API over HTTPS. + - Linux signing service performs PKCS#11 operations against SoftHSM. + - Private keys never leave Linux/HSM boundary. + +2. **PKCS#11 proxy bridge** + - Windows host loads a Windows PKCS#11 proxy client DLL. + - Proxy forwards PKCS#11 operations to Linux side connected to SoftHSM. + +3. **Windows-local SoftHSM (dev/test)** + - SoftHSM also installed on Windows and used locally. + - Useful for local testing, not preferred production topology. + +Decision note: + +- For production-critical FES, choose option 1 by default unless enterprise HSM policy requires option 2. +- Keep option 3 for development convenience only. + +### Layer responsibilities + +- `EnvelopeGenerator.Server`: + - API endpoints, auth orchestration, input validation. + - FES branch routing: standard-sign path vs external signing-service/proxy path. + - No private-key material handling. + +- `EnvelopeGenerator.Application`: + - Use cases such as `SignWithHsmCommand`. + - MediatR pipeline orchestration for status/history/audit. + - FES evidence model aggregation (ip/email/phone/user-agent/otp proof/timestamps). + +- `EnvelopeGenerator.Infrastructure`: + - Implementations for `IPkcs11Service`, `IPdfSignatureService`, `ITimestampService`. + - Pkcs11Interop integration and cryptographic operations. + - Optional client for Linux signing service if topology option 1 is selected. + +- `Domain`: + - Signature evidence and audit-trail models. + +--- + +## 5) Small-step integration plan + +## Phase 0 - Scope and contracts + +1. Finalize signing algorithms (for example `SHA256_RSA_PKCS`). +2. Confirm strategy: company certificate vs signer-specific certificate. +3. Freeze mandatory audit fields: + - identity, OTP proof, IP, user-agent, transaction id, timestamps, hash metadata. +4. Freeze deployment topology decision: + - option 1 (Linux signing service), option 2 (PKCS#11 proxy), or option 3 (Windows-local SoftHSM). +5. Define production host mapping: + - where `EnvelopeGenerator.Server` runs, + - where HSM/SoftHSM runs, + - where certificate lifecycle is managed. + +Deliverable: Technical decision record (ADR-style markdown). + +## Phase 1 - PKCS#11 connector (infrastructure) + +1. Define `IPkcs11Service` interface. +2. Add `Pkcs11Interop` implementation. +3. Add config model: + - library path, slot, token label, key label, certificate label. +4. Ensure secure secret handling for PIN. +5. Ensure host-compatible module loading: + - Windows server must load Windows DLL, + - Linux server must load Linux `.so`. + +Deliverable: Testable PKCS#11 service with health/slot/login/sign/verify capabilities. + +## Phase 1.5 - Cross-host bridge implementation + +1. If option 1 selected: + - implement Linux signing service API contract (`/sign`, `/certificate`, `/health`), + - implement authenticated HTTP client in `EnvelopeGenerator.Server`. +2. If option 2 selected: + - install/configure PKCS#11 proxy client DLL on Windows, + - install/configure proxy server on Linux and bind to SoftHSM. + +Deliverable: Windows-to-Linux signing communication path proven end-to-end. + +## Phase 2 - Application use case + +1. Add `SignDocumentHashCommand` (or equivalent). +2. Pipeline flow: + - compute/receive hash, + - sign with HSM, + - attach certificate context, + - verify, + - produce evidence object. +3. Add resilient error mapping and retry strategy. + +Deliverable: HSM signing use case in Application layer. + +## Phase 3 - PDF signature embedding + +1. Implement PDF signature embedding via `IPdfSignatureService`. +2. Build signer-specific audit-trail pages. +3. Append all audit pages to final PDF artifact. + +Deliverable: Signed PDF with certificate context and audit trail pages. + +## Phase 4 - Presentation/API integration + +1. Integrate FES option into submit flow (feature flag guarded). +2. Add operational endpoints: + - HSM health/check + - signature evidence query (restricted roles) +3. Keep DTOs safe; avoid exposing sensitive cryptographic material. +4. In `SignatureController.Submit`, add FES branch that sends signing payload + audit context to selected signing backend. + +Deliverable: API-level orchestration with minimal UI disruption. + +## Phase 5 - Audit, archive, distribution + +1. Persist signature evidence records. +2. Include hash/cert metadata in archival package. +3. Add signed artifact reference to distribution e-mails. + +Deliverable: Alignment with diagram steps 9-10. + +## Phase 6 - Testing and operations + +1. Postman collection + Newman automation. +2. Positive/negative matrix: + - wrong pin, wrong slot, missing cert, expired cert, HSM timeout. +3. Observability: + - structured logs, correlation id, latency metrics. + +Deliverable: Production readiness checklist. + +--- + +## 6) Transition strategy from test API to production flow + +1. Keep `/api/pkcs11-test/*` only for non-production. +2. In production, use the same internal services through business endpoints only. +3. Roll out by feature flag: + - `FesEnabled=false` initially + - pilot sender group + - full rollout + +4. Keep explicit environment matrix: + - local dev (option 3), + - integration/staging (option 1 or 2), + - production (option 1 or 2 only). + +--- + +## 7) Risks and mitigations + +- Certificate expiry risk -> proactive monitoring and renewal alerting. +- HSM connectivity risk -> retry policy, circuit breaker, fallback queue. +- PIN/secret exposure risk -> vault-backed secrets and rotation policy. +- Verification failure risk -> block PDF sealing and move envelope to technical hold state. +- Cross-host connectivity risk -> mTLS/JWT auth + timeout/retry/circuit breaker + health probe. + +--- + +## 8) Short done checklist + +- [ ] PKCS#11 service interface + implementation +- [ ] Application command + pipeline behaviors +- [ ] PDF signature embedding +- [ ] Audit-trail generation +- [ ] API integration + feature flag +- [ ] Postman/Newman regression suite +- [ ] Operational runbook and alerting rules diff --git a/EnvelopeGenerator.Infrastructure.Crypt/resources/flow-diagram.drawio b/EnvelopeGenerator.Infrastructure.Crypt/resources/flow-diagram.drawio new file mode 100644 index 00000000..c45d36f7 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure.Crypt/resources/flow-diagram.drawio @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/EnvelopeGenerator.Infrastructure.Crypt/resources/flow-diagram.pdf b/EnvelopeGenerator.Infrastructure.Crypt/resources/flow-diagram.pdf new file mode 100644 index 00000000..34548d50 Binary files /dev/null and b/EnvelopeGenerator.Infrastructure.Crypt/resources/flow-diagram.pdf differ diff --git a/EnvelopeGenerator.Infrastructure.Crypt/resources/ticket.md b/EnvelopeGenerator.Infrastructure.Crypt/resources/ticket.md new file mode 100644 index 00000000..f1f2cb07 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure.Crypt/resources/ticket.md @@ -0,0 +1,84 @@ +10/6/26, 10:46 PM + +Test SoftHSM : SWINFRA-54 + +Projects / Infrastruktur Software / Issues / + +Enter search… + +SWINFRA-54 + +All… + +Created by Marvin Kamm 3 months ago + +Visible to issue readers 1 + +Updated by Matthias Dewald about 1 month ago + +# **Test SoftHSM** + +Project Priorität Status **SWI** Infrastruktur Softwa H Hoch O Offen re… Bearbeiter Fälligkeit Projekteinfluss MD _ ? ? Matthias Dewald Kein fälligkeit Kein projektbezug Boards No visible boards + +Bitte eine Test-VM mit der Software SoftHSM bereitstellen. + +Laut Info von @Henning Emrich soll die Installation unter Debian Linux deutlich einfacher sein, als unter Windows. Bitte prüfen. + +@Hakan Tek & @OlgunR + +Sollen bitte die API Ansteuerung testen + +FYI + +@Marlon Schreiber @Jan-Ulrich Hoss @Henning Emrich @Hakan Tek @OlgunR + +**Attachments** 1 + +Files Attached to Comments + +**PDF** + +Ablauf SignFlow Un ternehme… 83 kB + +MD _ **Matthias Dewald** Commented 3 months ago Ist für Dienstag 30.6 10:00 Uhr Eingeplant + +HT **Hakan Tek** Commented 3 months ago + +Für die Integration auf der .NET-Seite können wir die Pkcs11Interop-Bibliothek und die entsprechende DevExpress-Infrastruktur verwenden. @OlgunR, falls du noch weitere Vorschläge hast, füge sie bitte hinzu. @Marvin Kamm, @Henning Emrich, @Matthias Dewald, um mit den Tests beginnen zu können, benötigen wir die entsprechenden Verbindungsdaten für SoftHSM (Slot-ID, PIN, Bibliothekspfad usw.). + +FYI + +@Marlon Schreiber @Jan-Ulrich Hoss + +bugtracker.dd:8080/issue/SWINFRA-54/Test-SoftHSM + +1/2 + +10/6/26, 10:46 PM + +Test SoftHSM : SWINFRA-54 + +MD + +## **Matthias Dewald** Commented 3 months ago + +Hallo zusammen, SoftHSM ist auf der 172.24.12.64 installiert: + +Der Proxy läuft auf Port 5657 und erwartet Verbindungen über die Proxy-Bibliothek (libpkcs11-proxy.so) + +@Hakan Tek Bitte testen + +MD + +## **Matthias Dewald** Commented about 1 month ago + +Ablauf SignFlow Unternehmenszertifikat.drawio.pdf + +**PDF** + +Ablauf SignFlow Un ternehme… 83 kB + +bugtracker.dd:8080/issue/SWINFRA-54/Test-SoftHSM + +2/2 +