Search code examples
c#pdfitextitext7sign

Howto sign a pdf using iText which contains an OCSP which is embedded


The first image is from a pdf signature which is LTV enabled. This document is not created by me. enter image description here

In the revocation information, it shows the following text:

The selected certificate is considered valid because it has not been revoked as verified using the Online Certificate Status Protocol (OCSP) response that was embedded in the signature.

I do sign a pdf document using iText and I also apply an OCSP.

OCSPVerifier ocspVerifier = new OCSPVerifier(null, null); // null,null >https://stackoverflow.com/questions/40765907/itextsharp-ocspclientbouncycastle-constructor-is-deprecated-whats-the-replacem
IOcspClient ocspClient = new OcspClientBouncyCastle(ocspVerifier);
var ocsp = ocspClient.GetEncoded(ocspCert,ocspRootCert, "http://www.myurl.com/aia/ocsp");

if (ocsp == null)
    Console.WriteLine("oscp is null");
else
    Console.WriteLine("ocsp is not null");

//Create the pkcs7 container
PdfPKCS7 sgn = new PdfPKCS7(null, c.ToArray(), HashAlgorithm, false);
Console.WriteLine("PdfPKCS7");
byte[] sh = sgn.GetAuthenticatedAttributeBytes(hash, ocsp, null, PdfSigner.CryptoStandard.CMS);
Console.WriteLine("GetAuthenticatedAttributeBytes");

//Load the signature via pkcs11 hardware
byte[] extSignature = GetSignatureFromHashViaPkcs11(sh, pin);
Console.WriteLine("GetSignatureFromHashViaPkcs11");
sgn.SetExternalDigest(extSignature, null, DigestEncryptionAlgorithm);
Console.WriteLine("SetExternalDigest");
var ret = sgn.GetEncodedPKCS7(hash, tsaClient, ocsp, null, PdfSigner.CryptoStandard.CMS);
Console.WriteLine("GetEncodedPKCS7");

Console.WriteLine($"IsTsp : {sgn.IsTsp()}");

In this case, the produced signature is shown as valid but LTV is not enabled: enter image description here

In the revocation information, it shows the following text:

The selected certificate is considered valid because it has not been revoked as verified in real-time using the Online Certificate Status Protocol (OCSP) obtained on-line.

My guess is that this difference is responsible for the LTV issue. How can i set the OCSP using iText so that it is embedded instead of obtained on-line?


Solution

  • You add one OCSP response, the one you retrieve here:

    var ocsp = ocspClient.GetEncoded(ocspCert,ocspRootCert, "http://www.myurl.com/aia/ocsp");
    

    But this does not retrieve an OCSP response for your signer certificate but instead for the OCSP certificate of your PKI.

    What you need are revocation information for all involved certificates and their chains up to but excluding the trust anchor.

    Thus,

    1. you should start with the signer certificate and its chain;

      e.g. if your c is sorted as a chain, retrieve OCSP responses for c[0], c[1], then c[1], c[2], c[2], c[3] etc. up to the trust anchor;

    2. if your signature contains a time stamp, execute step 1 also for the TSA certificate;

    3. then you have to inspect those OCSP responses, retrieve their signer certificates, build their chains, and execute step 1 for all of them except for certificates that have a id-pkix-ocsp-nocheck extension.

      Beware, an OCSP response for a certificate signed by that certificate itself obviously is not worth a dime...