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.
7.7 KiB
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
Applicationlayer use-cases, - support future extensions (timestamping, certificate chain validation, multiple key algorithms).
2. Context and Constraints
- SoftHSMv2 is not a REST service. It is a PKCS#11 module loaded as a native library.
EnvelopeGenerator.Serveris presentation only; cryptographic implementation belongs to infrastructure.- Clean Architecture boundaries must be respected:
Applicationdepends on abstractions.Infrastructure.Cryptimplements abstractions.
- Initial target framework is
net8.0. - 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)Pkcs11ProviderOptionsKeyLocator(label/id/slot/token selectors)SignHashRequestSignHashResultVerifySignatureRequestVerifySignatureResultCertificateDescriptorSignatureEvidence(technical evidence payload)
Interfaces:
ISignatureProviderICertificateProviderISignatureVerifierICryptographicHealthCheck
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:
Pkcs11LibraryLoaderPkcs11SessionFactoryPkcs11ObjectFinderPkcs11SignatureProviderPkcs11CertificateProvider
Capabilities:
- load module path from options (
libsofthsm2.soor proxy module when required), - enumerate slots/tokens,
- open read-write session,
- login with user pin,
- find private key by label/id,
- sign digest with selected mechanism,
- 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:
DefaultSignatureVerifierX509CertificateParser- optional
CertificateChainValidator(toggleable)
Capabilities:
- verify signature using returned certificate/public key,
- expose certificate metadata (
thumbprint,subject,issuer,notBefore,notAfter), - 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:
CryptInfrastructureDependencyInjectionextension 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:
Unit:- request validation,
- algorithm mapping,
- evidence building,
- error mapping.
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
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 = PKCS11Crypt:Pkcs11:AssetsRootPath(base path that contains bundledpkcs11assets)Crypt:Pkcs11:SlotIdor token selectorsCrypt:Pkcs11:UserPin(from secret store/env, not plain committed value)Crypt:Pkcs11:PrivateKeyLabelCrypt:Pkcs11:CertificateLabelCrypt: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_UNAVAILABLECRYPT_SLOT_NOT_FOUNDCRYPT_LOGIN_FAILEDCRYPT_KEY_NOT_FOUNDCRYPT_CERT_NOT_FOUNDCRYPT_SIGN_FAILEDCRYPT_VERIFY_FAILED
Map low-level exceptions to these codes with safe diagnostics.
8. Non-Functional Requirements
- Security: never log pins or raw private key handles.
- Reliability: deterministic cleanup (
IDisposable/IAsyncDisposable). - Observability: structured logs with correlation id.
- Performance: avoid repeated login per operation when a safe session strategy is available.
- Extensibility: algorithm/provider mapping must be open for extension.
9. Implementation Order (Small Tasks)
- Add models + interfaces.
- Add options + validators.
- Add PKCS#11 low-level loader/session wrappers.
- Implement
Pkcs11SignatureProviderfor hash signing. - Implement certificate retrieval.
- Implement verifier.
- Implement evidence builder.
- Add DI registration extension.
- Add unit tests.
- Add optional integration tests (SoftHSM profile).
10. Definition of Done
Done means:
Infrastructure.Cryptexposes generic cryptographic services usable by Application use-cases.- SoftHSM-backed PKCS#11 sign/verify path works in integration tests.
- All sensitive configuration is externalized.
- Structured error codes are returned for expected failure scenarios.
- Documentation exists for host registration and required settings.