feat(infrastructure): add PKCS#11 PDF signing infrastructure
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
using DocumentOperator.Application.Common.Configurations;
|
||||
using DevExpress.Office.DigitalSignatures;
|
||||
using DevExpress.Pdf;
|
||||
|
||||
namespace DocumentService.Infrastructure.Crypt.Services;
|
||||
|
||||
internal sealed class Pkcs11ExternalSigner(Pkcs11Options options) : Pkcs7SignerBase
|
||||
{
|
||||
private readonly Pkcs11PdfSigningRsa rsa = new(options);
|
||||
private readonly DigestCalculator digestCalculator = new(HashAlgorithmType.SHA256);
|
||||
private readonly IReadOnlyList<byte[]> certificates = [ReadCertificateBytesWithFallback(options)];
|
||||
|
||||
protected override IDigestCalculator DigestCalculator => digestCalculator;
|
||||
|
||||
protected override string SigningAlgorithmOID => "1.2.840.113549.1.1.1";
|
||||
|
||||
protected override IEnumerable<byte[]> GetCertificates() => certificates;
|
||||
|
||||
protected override byte[] SignDigest(byte[] digest)
|
||||
{
|
||||
return rsa.SignHash(digest, System.Security.Cryptography.HashAlgorithmName.SHA256, System.Security.Cryptography.RSASignaturePadding.Pkcs1);
|
||||
}
|
||||
|
||||
private static byte[] ReadCertificateBytesWithFallback(Pkcs11Options options)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Pkcs11SessionRunner.Run(options, session =>
|
||||
{
|
||||
var attrs = new List<Net.Pkcs11Interop.HighLevelAPI.IObjectAttribute>
|
||||
{
|
||||
session.Factories.ObjectAttributeFactory.Create(Net.Pkcs11Interop.Common.CKA.CKA_CLASS, Net.Pkcs11Interop.Common.CKO.CKO_CERTIFICATE),
|
||||
session.Factories.ObjectAttributeFactory.Create(Net.Pkcs11Interop.Common.CKA.CKA_LABEL, options.CertificateLabel)
|
||||
};
|
||||
|
||||
var handles = session.FindAllObjects(attrs);
|
||||
if (handles.Count == 0)
|
||||
throw new InvalidOperationException($"Certificate '{options.CertificateLabel}' not found in token.");
|
||||
|
||||
var values = session.GetAttributeValue(handles[0], new List<Net.Pkcs11Interop.Common.CKA> { Net.Pkcs11Interop.Common.CKA.CKA_VALUE });
|
||||
return values[0].GetValueAsByteArray();
|
||||
});
|
||||
}
|
||||
catch when (Pkcs11ToolBridge.IsAvailable(options))
|
||||
{
|
||||
return Pkcs11ToolBridge.ReadCertificateBytes(options);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user