Enhanced PDF signing with UUID and metadata handling: - Added `UUID` and `OriginalDocumentSha256` to `PdfSignOptionsDto` and `PdfSignatureCheckItemDto`. - Introduced `BusinessReason` to separate metadata from signature reasons. - Updated `PdfDigitalSignatureService` to embed and parse metadata in signature reasons. - Improved error handling to include metadata in validation results. - Updated `PdfSignatureController` to handle `UUID` in signing requests. Refactored PKCS#11 configuration: - Replaced `LibraryPath` with `AssetsRootPath` for asset resolution. - Added `ProxySocket` and `DefaultApplicationName` options. - Clarified runtime behavior for asset resolution in `README.md`. Updated documentation and examples to reflect these changes.
302 lines
7.7 KiB
Markdown
302 lines
7.7 KiB
Markdown
# 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:AssetsRootPath` (base path that contains bundled `pkcs11` assets)
|
|
- `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:
|
|
|
|
- resolved module path must exist under configured/default assets root,
|
|
- 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.
|