Warm tip: This article is reproduced from stackoverflow.com, please click
.net c# itext7 pdf

Add revocation information to signature using iText7

发布于 2020-05-06 09:06:47

I am producing Long Term signature. I am trying to add revocation information (Crls, OCSP Responses, Certificate Chain) to the signature as an unsigned attributes but the revocation information is not been embedded in the final signature. Following is the code snippet:

        Stream outputStream = new MemoryStream();

        List<byte[]> ocspCollection = new List<byte[]>();
        List<byte[]> crlCollection = new List<byte[]>();
        List<byte[]> certsCollection = new List<byte[]>();

        Stream readerStream = new MemoryStream(signedDocument);
        PdfReader pdfReader = new PdfReader(readerStream);
        PdfSigner pdfSigner = new PdfSigner(pdfReader, outputStream, new StampingProperties().UseAppendMode());

        LtvVerification ltvVerification = new LtvVerification(pdfSigner.GetDocument());

        X509Chain chain = new X509Chain();
        chain.Build(signerCertificate);

        foreach (X509ChainElement item in chain.ChainElements)
        {
            byte[] certBytes = item.Certificate.Export(X509ContentType.Cert);
            certsCollection.Add(certBytes);
        }

        foreach (byte[] ocsp in revocationInfo.OCSPResponses)
        {
            ocspCollection.Add(ocsp);
        }

        foreach (byte[] crlBytes in revocationInfo.CRLs)
        {
            crlCollection.Add(crlBytes);
        }

        bool revocationInfoAdded = ltvVerification.AddVerification(signingRequest.FieldName, ocspCollection, crlCollection, certsCollection);

ltvVerification.AddVerification() method returns true in response.

Please find the signed document from below link: https://1drv.ms/b/s!AvIgyv7xAxxoihGn9aFbe9TQSps4?e=eKPdn8

Any help in this regard is highly appreciated. Regards

Questioner
Muddassir Awan
Viewed
45
mkl 2020-02-20 21:24

Some working code

You used a PdfSigner (which only makes sense when also applying a signature or document time stamp but you provided only the already signed file) and have some variables I do not have here. Thus, I essentially wrote an example based on a mere PdfDocument and your shared files without those extra variables:

using (PdfReader pdfReader = new PdfReader("LTV Doc-Revocation Info Issue.pdf"))
using (PdfWriter pdfWriter = new PdfWriter("LTV Doc-Revocation Info Issue-WithRevocation.pdf"))
using (PdfDocument pdfDocument = new PdfDocument(pdfReader, pdfWriter, new StampingProperties().UseAppendMode()))
{
    List<byte[]> ocspCollection = new List<byte[]>();
    List<byte[]> crlCollection = new List<byte[]>();
    List<byte[]> certsCollection = new List<byte[]>();
    ocspCollection.Add(File.ReadAllBytes(@"Ocsp"));
    crlCollection.Add(File.ReadAllBytes(@"Crl.crl"));

    LtvVerification ltvVerification = new LtvVerification(pdfDocument);
    ltvVerification.AddVerification("SH_SIGNATURE_532546", ocspCollection, crlCollection, certsCollection);
    ltvVerification.Merge();
}

Inspecting the result one sees:

Screen shot of PDF structure

In particular the provided OCSP response and the provided CRL are embedded in the PDF, so the iText LtvVerification class does its job.

Possible issues in your project

First of all your say:

I am trying to add revocation information (Crls, OCSP Responses, Certificate Chain) to the signature as an unsigned attributes

This already indicates a mismatch: You use the LtvVerification class, and so do I in the working code above. This class does not change the embedded CMS containers. It does not add the revocation information to the unsigned attributes of the embedded CMS container but instead to the DSS (Document Security Store) structure of the PDF.

Embedding revocation data as unsigned attributes of the embedded CMS signature container actually is not possible in an interoperable way: You either use the signed adbe-revocationInfoArchival attribute in the CMS container or the DSS outside of the CMS container.

(Some validators accept revocation data embedded CAdES-style in the unsigned attributes but strictly speaking that is forbidden in PAdES and not interoperable in PDF 2.0.)

So if you actually want to embed the revocation data in the CMS container, provide them to the PdfSigner signing method of your choice, they all explicitly or implicitly accept revocation data to embed,

public virtual void SignDetached(IExternalSignature externalSignature, X509Certificate[] chain,
    ICollection<ICrlClient> crlList, IOcspClient ocspClient, ITSAClient tsaClient,
    int estimatedSize, PdfSigner.CryptoStandard sigtype)

public virtual void SignDetached(IExternalSignature externalSignature, X509Certificate[] chain,
    ICollection<ICrlClient> crlList, IOcspClient ocspClient, ITSAClient tsaClient,
    int estimatedSize, PdfSigner.CryptoStandard sigtype, SignaturePolicyInfo signaturePolicy)

public virtual void SignDetached(IExternalSignature externalSignature, X509Certificate[] chain,
    ICollection<ICrlClient> crlList, IOcspClient ocspClient, ITSAClient tsaClient,
    int estimatedSize, PdfSigner.CryptoStandard sigtype, SignaturePolicyIdentifier signaturePolicy)

or

public virtual void SignExternalContainer(IExternalSignatureContainer externalSignatureContainer,
    int estimatedSize)

The former three explicitly accept CRL and OCSP clients (which can be implemented to provide pre-existing CRLs and OCSPs) while the latter gets the full CMS container from the given IExternalSignatureContainer implementation, so in that implementation you can add any information to it you want.