Add PKCS#11-based PDF signing infrastructure

Introduced a cryptographic infrastructure for PDF signing and validation using PKCS#11-based hardware security modules (HSMs) or software tokens. Key changes include:

- Added `PdfDigitalSignatureService` for signing PDFs, multi-signature support, and signature validation.
- Implemented `Pkcs11ExternalSigner` and `Pkcs11PdfSigningRsa` for PKCS#11-based signing with DevExpress PDF infrastructure.
- Added utilities like `Pkcs11SessionRunner`, `Pkcs11InteropBootstrap`, and `Pkcs11ToolBridge` for session management, library initialization, and fallback mechanisms.
- Introduced `Pkcs11Options` for managing PKCS#11 configurations.
- Updated project dependencies to include `DevExpress.Document.Processor`, `System.Security.Cryptography.Pkcs`, and `Pkcs11Interop`.
- Enhanced error handling and fallback support for PKCS#11 operations.

These changes enable robust and extensible PDF signing capabilities with detailed signature metadata extraction and validation.
This commit is contained in:
2026-10-13 14:45:47 +02:00
parent 7766e2ea25
commit f361898ba4
9 changed files with 897 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
using System.Security.Cryptography;
namespace EnvelopeGenerator.Infrastructure.Crypt.Services;
internal static class Pkcs11DigestInfoBuilder
{
public static byte[] Build(byte[] hash, HashAlgorithmName hashAlgorithm)
{
byte[] prefix = hashAlgorithm.Name switch
{
"SHA256" =>
[
0x30, 0x31,
0x30, 0x0d,
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
0x05, 0x00,
0x04, 0x20
],
"SHA384" =>
[
0x30, 0x41,
0x30, 0x0d,
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
0x05, 0x00,
0x04, 0x30
],
"SHA512" =>
[
0x30, 0x51,
0x30, 0x0d,
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
0x05, 0x00,
0x04, 0x40
],
_ => throw new NotSupportedException($"Hash algorithm '{hashAlgorithm.Name}' is not supported.")
};
var digestInfo = new byte[prefix.Length + hash.Length];
Buffer.BlockCopy(prefix, 0, digestInfo, 0, prefix.Length);
Buffer.BlockCopy(hash, 0, digestInfo, prefix.Length, hash.Length);
return digestInfo;
}
}