Update README with PKCS#11 integration details
Added a detailed README for the `EnvelopeGenerator.Infrastructure.Crypt` project, explaining its purpose, functionality, and integration with PKCS#11-based cryptographic workflows. Highlights include: - Overview of the project's role in FES workflows. - Explanation of SoftHSM and PKCS#11 deployment patterns. - Mapping of functionality to FES diagram steps 6-8. - Documentation of service interfaces and DI entry point. - Configuration guidance with JSON examples and security best practices. - Instructions for obtaining PKCS#11 values and setting up SoftHSM. - Checklist for IT handover and environment setup. - Steps for running cryptographic tests with PowerShell and Linux examples. - Common failure diagnostics and their meanings. - Clarification of signing semantics and validation requirements. - FAQ addressing common questions about SoftHSM and PKCS#11 usage. This update ensures clear guidance for developers and IT teams to configure and integrate the cryptographic layer effectively.
This commit is contained in:
399
EnvelopeGenerator.Infrastructure.Crypt/README.md
Normal file
399
EnvelopeGenerator.Infrastructure.Crypt/README.md
Normal file
@@ -0,0 +1,399 @@
|
|||||||
|
# EnvelopeGenerator.Infrastructure.Crypt
|
||||||
|
|
||||||
|
This project provides 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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1) What this project is (and what it is not)
|
||||||
|
|
||||||
|
This project is the cryptography 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.
|
||||||
|
|
||||||
|
It is **not**:
|
||||||
|
|
||||||
|
- a REST API by itself,
|
||||||
|
- a UI component,
|
||||||
|
- a full document workflow orchestrator.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2) SoftHSM and PKCS#11 in one minute
|
||||||
|
|
||||||
|
- `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.
|
||||||
|
|
||||||
|
Two deployment patterns are possible:
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
Both are valid for this project.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3) How this maps to the FES diagram (Ablauf SignFlow Unternehmenszertifikat)
|
||||||
|
|
||||||
|
From the shared draw.io/PDF process:
|
||||||
|
|
||||||
|
- 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.
|
||||||
|
|
||||||
|
So this project is the cryptographic core for diagram steps 6-8.
|
||||||
|
|
||||||
|
Actor mapping from the diagram:
|
||||||
|
|
||||||
|
- `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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4) Service surface
|
||||||
|
|
||||||
|
Main interfaces:
|
||||||
|
|
||||||
|
- `ISignatureProvider`
|
||||||
|
- `ICertificateProvider`
|
||||||
|
- `ISignatureVerifier`
|
||||||
|
- `ICryptographicHealthCheck`
|
||||||
|
|
||||||
|
DI entry point:
|
||||||
|
|
||||||
|
- `CryptDependencyInjection.AddCryptInfrastructure(...)`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5) Required configuration
|
||||||
|
|
||||||
|
Configuration section: `Crypt:Pkcs11`
|
||||||
|
|
||||||
|
Typical keys:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Crypt": {
|
||||||
|
"Pkcs11": {
|
||||||
|
"LibraryPath": "/usr/lib/softhsm/libsofthsm2.so",
|
||||||
|
"SlotId": 0,
|
||||||
|
"TokenLabel": null,
|
||||||
|
"UserPin": "***",
|
||||||
|
"PrivateKeyLabel": "sign-key",
|
||||||
|
"PrivateKeyIdHex": null,
|
||||||
|
"CertificateLabel": "sign-cert",
|
||||||
|
"CertificateIdHex": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Security rule:
|
||||||
|
|
||||||
|
- Do not commit real PINs to source control.
|
||||||
|
- Use environment variables / secret vault for production.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6) The 5 test values you must provide
|
||||||
|
|
||||||
|
Integration tests need these environment variables:
|
||||||
|
|
||||||
|
- `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`
|
||||||
|
|
||||||
|
Without these values, integration tests are skipped by design.
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7) How to obtain these values (IT-friendly)
|
||||||
|
|
||||||
|
## 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:
|
||||||
|
|
||||||
|
```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.
|
||||||
|
|
||||||
|
```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:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pkcs11-tool --module /path/to/libsofthsm2.so --slot <slot-id> --login --pin <user-pin> --list-objects
|
||||||
|
```
|
||||||
|
|
||||||
|
From output:
|
||||||
|
|
||||||
|
- private key label -> `FES_TEST_PKCS11_PRIVATE_KEY_LABEL`
|
||||||
|
- certificate label -> `FES_TEST_PKCS11_CERTIFICATE_LABEL`
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1) Initialize token in slot 0 (example)
|
||||||
|
softhsm2-util --init-token --slot 0 --label "CompanySignToken"
|
||||||
|
|
||||||
|
# 2) Verify slot/token
|
||||||
|
softhsm2-util --show-slots
|
||||||
|
|
||||||
|
# 3) Generate RSA key pair inside token (example)
|
||||||
|
pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --slot 0 --login --pin <USER_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 <USER_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 <USER_PIN> --list-objects
|
||||||
|
```
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
- Use this only in non-production unless approved.
|
||||||
|
- In production, key generation/import should follow company security policy.
|
||||||
|
|
||||||
|
## 7.2 If you use PKCS#11 proxy module
|
||||||
|
|
||||||
|
What it is:
|
||||||
|
|
||||||
|
- A local PKCS#11 bridge library that forwards calls to remote HSM/SoftHSM service.
|
||||||
|
|
||||||
|
Why needed:
|
||||||
|
|
||||||
|
- App still loads a local module path, but crypto operations happen remotely.
|
||||||
|
|
||||||
|
Ask IT for:
|
||||||
|
|
||||||
|
- proxy module path (`libpkcs11-proxy.*`)
|
||||||
|
- slot id or token label
|
||||||
|
- user pin
|
||||||
|
- private key label
|
||||||
|
- certificate label
|
||||||
|
|
||||||
|
In proxy mode, values come from proxy-backed token, not local SoftHSM token files.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7.3 Linux handover checklist for IT (copy/paste friendly)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8) Test execution checklist (single command flow)
|
||||||
|
|
||||||
|
## 8.1 Set environment variables
|
||||||
|
|
||||||
|
PowerShell example:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$env:FES_TEST_PKCS11_LIBRARY_PATH = "<module-path>"
|
||||||
|
$env:FES_TEST_PKCS11_SLOT_ID = "<slot-id>"
|
||||||
|
$env:FES_TEST_PKCS11_USER_PIN = "<user-pin>"
|
||||||
|
$env:FES_TEST_PKCS11_PRIVATE_KEY_LABEL = "<private-key-label>"
|
||||||
|
$env:FES_TEST_PKCS11_CERTIFICATE_LABEL = "<certificate-label>"
|
||||||
|
```
|
||||||
|
|
||||||
|
Linux (bash) example:
|
||||||
|
|
||||||
|
```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="<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.
|
||||||
|
|
||||||
|
If all five values are correct:
|
||||||
|
|
||||||
|
- integration tests run automatically,
|
||||||
|
- no code change is required,
|
||||||
|
- only environment setup is required.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9) Common failure meanings
|
||||||
|
|
||||||
|
- `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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10) Integration in the full stack architecture
|
||||||
|
|
||||||
|
Current role by layer:
|
||||||
|
|
||||||
|
- `Infrastructure.Crypt` (this project): PKCS#11 crypto operations
|
||||||
|
- `Application`: orchestration use-cases and business process steps
|
||||||
|
- `Server`: API endpoints and presentation concerns
|
||||||
|
|
||||||
|
Recommended integration path:
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11) Important note about signing semantics
|
||||||
|
|
||||||
|
PKCS#11 mechanisms differ in whether they expect raw data or a precomputed digest.
|
||||||
|
|
||||||
|
Current implementation signs with `CKM_SHA256_RSA_PKCS` and receives hash bytes from caller.
|
||||||
|
This must be validated in your real provider environment.
|
||||||
|
|
||||||
|
If provider expects raw data for this mechanism, integration may require adjustment.
|
||||||
|
This is why integration tests are critical.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12) Quick FAQ
|
||||||
|
|
||||||
|
**Q: Do I need REST calls to SoftHSM?**
|
||||||
|
|
||||||
|
No. SoftHSM is not a REST server. Use PKCS#11 library calls.
|
||||||
|
|
||||||
|
**Q: Can I use proxy and still call it SoftHSM setup?**
|
||||||
|
|
||||||
|
Yes. Proxy can forward to SoftHSM-backed token infrastructure.
|
||||||
|
|
||||||
|
**Q: Once I provide the 5 values, can tests run directly?**
|
||||||
|
|
||||||
|
Yes. Set env vars and run the single `dotnet test` command above.
|
||||||
|
|
||||||
|
**Q: Will one company cert/key be enough for this phase?**
|
||||||
|
|
||||||
|
Yes, for the diagram-aligned company-signing model, one company key/certificate is enough for initial implementation and validation.
|
||||||
Reference in New Issue
Block a user