Автоподбор размера 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, резервирующие меньше запрошенного