Um das PDF offline zu validieren, konfiguriere ich SignatureValidator, um den Online-Abruf von OCSP/CRL-Daten zu deaktivieren. Die Validierung schlägt jedoch fehl, es sei denn, der Online-Abruf ist aktiviert. Das Debuggen des iText-Codes legt nahe, dass die im DSS eingebetteten OCSP/CRL-Daten nicht von SignatureValidator verwendet werden.
Schritte zum Reproduzieren (mit iText 9.0)
Code: Select all
// 1) Sign the pdf
var inputPdfReader = new PdfReader("not_signed.pdf");
var outputStream = new FileStream("signed.pdf", FileMode.Create);
var tsaClient = new TSAClientBouncyCastle("https://freetsa.org/tsr", null, null, 8192, "SHA-256");
var stampingProperties = new StampingProperties();
PdfSigner pdfSigner = new PdfSigner(inputPdfReader, outputStream, stampingProperties);
pdfSigner.Timestamp(tsaClient, null);
outputStream.Close();
// 2) Add LTV information:
var signedReader = new PdfReader("signed.pdf");
var ltvWriter = new PdfWriter("signed_ltv.pdf");
var ltvDocument = new PdfDocument(signedReader, ltvWriter, new StampingProperties().UseAppendMode());
LtvVerification v = new LtvVerification(ltvDocument);
SignatureUtil signatureUtil = new SignatureUtil(ltvDocument);
var names = signatureUtil.GetSignatureNames();
var pkcs7 = signatureUtil.ReadSignatureData(names.Single());
Debug.Assert(pkcs7.IsTsp());
v.AddVerification(names[0], (IOcspClient)new OcspClientBouncyCastle(), new CrlClientOnline(), LtvVerification.CertificateOption.WHOLE_CHAIN,
LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.NO);
v.Merge();
ltvDocument.Close();
// 3) Verify the LTV information:
var validationProperties = new SignatureValidationProperties();
// It works if I comment the next line and allow online fetching. But I think it should work without...
validationProperties.SetRevocationOnlineFetching(ValidatorContexts.All(), CertificateSources.All(), TimeBasedContexts.All(), SignatureValidationProperties.OnlineFetching.NEVER_FETCH);
// bugfix for iText 9.0 https://kb.itextpdf.com/itext/workaround-for-required-extension-missing-or-incor
List certIssuerRequiredExtensions = new();
certIssuerRequiredExtensions.Add(new KeyUsageExtension(KeyUsage.KEY_CERT_SIGN));
certIssuerRequiredExtensions.Add(new DynamicBasicConstraintsExtension());
validationProperties.SetRequiredExtensions(CertificateSources.Of(CertificateSource.CERT_ISSUER),
[new KeyUsageExtension(KeyUsage.KEY_CERT_SIGN), new MyDynamicBasicConstraintsExtension()]);
var ks = new List();
using (var stream = new FileStream("freetsa_root.cer", FileMode.Open))
{
ks.Add(new X509CertificateBC(new X509CertificateParser().ReadCertificate(stream)));
}
using (var stream = new FileStream("freetsa_root2.cer", FileMode.Open))
{
ks.Add(new X509CertificateBC(new X509CertificateParser().ReadCertificate(stream)));
}
var validatorChainBuilder = new ValidatorChainBuilder()
.WithSignatureValidationProperties(validationProperties)
.WithTrustedCertificates(ks);
ltvDocument = new PdfDocument(new PdfReader("signed_ltv.pdf"));
var validator = validatorChainBuilder.BuildSignatureValidator(ltvDocument);
var validationReport = validator.ValidateSignatures();
var validationFailures = validationReport.GetFailures();
Die Validierung schlägt fehl, wenn der Offline-Abruf deaktiviert ist. Basierend auf meinem Debugging scheint es, dass die im DSS eingebetteten OCSP/CRL-Daten von SignatureValidator ignoriert werden.
Der Workflow funktioniert, wenn ich Online-Abruf zulasse (kommentieren Sie die Zeile). im Code erwähnt). Ich möchte jedoch, dass der Workflow für die Offline-Validierung vollständig auf den eingebetteten DSS-Daten basiert.
Um dies zu reproduzieren, benötigen Sie die Stammzertifikate von freetsa.org (eines zum Signieren, das ein anderes für OCSP). Ich habe sie mit der Funktion „Zertifikat exportieren“ von Adobe Readers extrahiert.
Jede Einsicht oder Problemumgehung wäre sehr dankbar.