Files
TekH f7af3776c2 Switch to DocumentService API, remove PKCS#11 support
Replaced PKCS#11-based cryptographic operations with a new DocumentService API integration. Removed all PKCS#11-related code, configurations, and dependencies, including options, self-test status, and signing logic. Updated `FinalizeEnvelopeCommand` to include a notification service and added base64 conversion for documents. Updated `ServiceCollectionExtensions` to register the new DocumentService client. Removed outdated documentation and diagrams related to PKCS#11. Updated project files and configurations to reflect these changes and incremented the version number. Added a comment in `EnvelopeFinalizationWorker` for future RabbitMQ integration.
2026-10-25 18:52:12 +01:00

78 lines
3.5 KiB
C#

using DocumentService.Client.Interfaces;
using DocumentService.Client.Models.Requests;
using EnvelopeGenerator.Application.Common.Dto;
using EnvelopeGenerator.Application.Common.Interfaces.Services;
using ClientCertLevel = DocumentService.Client.Models.Requests.PdfSignatureCertificationLevel;
using ClientCoordUnit = DocumentService.Client.Models.Requests.PdfSignatureCoordinateUnit;
using ClientCoordOrigin = DocumentService.Client.Models.Requests.PdfSignatureCoordinateOrigin;
namespace EnvelopeGenerator.Infrastructure.Crypt.Services;
/// <summary>
/// Proxy that forwards PDF signing to the remote DocumentService API via <see cref="IPdfSignatureClient"/>.
/// </summary>
public sealed class PdfDigitalSignatureService(IPdfSignatureClient signatureClient) : IPdfDigitalSignatureService
{
public async Task SignPdfAsync(Stream inputPdf, Stream outputPdf, PdfSignOptionsDto? options = null, Stream? image = null, CancellationToken cancellationToken = default)
{
var pdfBytes = await ReadAllBytesAsync(inputPdf, cancellationToken);
var imageBytes = image is null ? null : await ReadAllBytesAsync(image, cancellationToken);
using var signed = await signatureClient.SignAsync(pdfBytes, Map(options), imageBytes, cancellationToken);
await signed.CopyToAsync(outputPdf, cancellationToken);
}
public Task<PdfSignatureCheckResultDto> CheckPdfSignatureAsync(Stream inputPdf, CancellationToken cancellationToken = default)
=> throw new NotSupportedException("Signature checking is handled by DocumentService and is not available through this proxy.");
private static SignPdfOptions Map(PdfSignOptionsDto? o) => new()
{
DocumentElementId = o?.DocumentElementId ?? 0,
Name = o?.Name ?? string.Empty,
Reason = o?.Reason,
Location = o?.Location,
Email = o?.Email,
Phone = o?.Phone,
ApplicationName = o?.ApplicationName,
CertificationLevel = (ClientCertLevel)(o?.CertificationLevel ?? EnvelopeGenerator.Application.Common.Enums.PdfSignatureCertificationLevel.NoCertification),
Appearance = o?.Appearance is null ? null : MapAppearance(o.Appearance)
};
private static PdfSignatureAppearance MapAppearance(PdfSignatureAppearanceDto a) => new()
{
PageNumber = a.PageNumber,
Left = a.Left,
Bottom = a.Bottom,
Width = a.Width,
Height = a.Height,
ShowLabels = a.ShowLabels,
ShowName = a.ShowName,
ShowDate = a.ShowDate,
ShowReason = a.ShowReason,
ShowLocation = a.ShowLocation,
ShowDistinguishedName = a.ShowDistinguishedName,
DateTimeFormat = a.DateTimeFormat,
CoordinateUnit = (ClientCoordUnit)a.CoordinateUnit,
CoordinateOrigin = (ClientCoordOrigin)a.CoordinateOrigin,
Font = new PdfSignatureFont
{
FamilyName = a.Font.FamilyName,
Size = a.Font.Size,
IsBold = a.Font.IsBold,
IsItalic = a.Font.IsItalic,
IsUnderline = a.Font.IsUnderline,
Color = new PdfSignatureColor { R = a.Font.Color.R, G = a.Font.Color.G, B = a.Font.Color.B }
}
};
private static async Task<byte[]> ReadAllBytesAsync(Stream stream, CancellationToken cancellationToken)
{
if (stream is MemoryStream memory && memory.TryGetBuffer(out var buffer))
return buffer.AsSpan(0, (int)memory.Length).ToArray();
using var copy = new MemoryStream();
await stream.CopyToAsync(copy, cancellationToken);
return copy.ToArray();
}
}