Автоподбор размера CMS placeholder
HotPDF может оценить отсоединённый CMS-контейнер без вызова операции с приватным ключом, timestamp authority или контрподписанта, а затем пересобрать слишком маленький unsigned PDF до необратимой границы подписывания
Оценка без побочных эффектов
HPDFCMSEstimatePlaceholder берёт длину подписи из EstimatedSignatureBytes, затем из провайдера, заявляющего spcEstimateSignatureSize, затем из RSA modulus в сертификате подписи — именно в этом порядке
Оценщик строит точную статическую форму CMS с синтетической подписью такой длины, сохраняет настроенные сертификаты и статические контрподписи, а динамические callback заменяет настраиваемыми вызывающим кодом резервами payload
THPDFCMSPlaceholderEstimateOptions.Default применяет запас в 50 процентов, минимум 1,024 байта, выравнивание по 256 байтам и максимум 16 MiB; оценки timestamp и контрподписей остаются явными, потому что размеры их ответов зависят от внешних сервисов
THPDFCMSPlaceholderEstimateInfo сообщает выбранный источник, длину подписи, статическую длину CMS, динамический резерв, оценённую длину CMS и рекомендованную выровненную ёмкость /Contents
Пересборка до подписывания
Функции автоподбора размера проверяют текущую ёмкость /Contents после подготовки /ByteRange
Если ёмкость ниже рекомендации, THPDFCMSRebuildUnsignedPDFCallback получает требуемое число байтов и пишет свежий unsigned PDF в переданный destination stream; пересобранный placeholder валидируется до запуска любого signing callback
EstimateOptions := THPDFCMSPlaceholderEstimateOptions.Default;
AutoOptions := THPDFCMSAutoSizeOptions.Default;
AutoOptions.Estimate := EstimateOptions;
HPDFCMSSignPDFStreamWithProviderAutoSize(
InputStream, OutputStream, CertificateDER, Provider, KeyIdentifier,
SignOptions, AutoOptions,
procedure(ContentsBytes: Integer; Destination: TStream)
begin
BuildUnsignedPDF(ContentsBytes, Destination);
end,
AutoSizeInfo);
Контракт безопасности повторов
HPDFCMSSignPDFStreamWithExternalSignerAutoSize никогда не вызывает внешний signer повторно после того, как тот вернул подпись; неожиданное переполнение восстанавливает unsigned placeholder и поднимает ошибку с фактическим и доступным размерами
HPDFCMSSignPDFStreamWithProviderAutoSize может повторять только когда провайдер заявляет spcSafeSignRetry, доступен rebuild callback и MaximumSigningRetries не исчерпан
Если включены content timestamp, signature timestamp или динамические контрподписи, повтор дополнительно требует DynamicCallbacksSafeToRetry=True
Callback-провайдер открывает ConfigureSizeEstimation, удалённые провайдеры принимают опциональный оценщик и объявление safe-retry, а провайдеры хранилища ключей PKCS#11 или Windows выводят длину выхода RSA из сертификата, не трогая приватный ключ
Диагностика и лимиты
THPDFCMSAutoSizeInfo сообщает начальную и итоговую ёмкости, фактическую длину CMS, число пересборок, попытки подписывания и то, был ли повтор после подписи
Рекомендованные и повторные размеры проверяются широкой арифметикой, выравниваются в пределах настроенного максимума и отвергают невалидные проценты, счётчики повторов, нулевые длины, битые сертификаты, неподдерживаемые ключи и rebuild callback, резервирующие меньше запрошенного