Click here to Skip to main content
15,891,033 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I want to return an ltv enabled pdf after signing a document. I made some modifications to my code yet I can't get the desired result. I've been trying for more than a week and I'm very fustrated. Please, if anyone is kind enough to edit the code or offer suggestions that might help me, I will be very grateful. Thanks very much in advance.

All the methods are located in a static class "SignMyPDF" Here is the method I have use to sign my pdf

Here is a link to my certificate and the document I want to sign and make ltv enabled.

My certificate

Document

Document


This is a helper method to get crls from certificate

C#
public static string[] GetCrlDistributionPoints(this X509Certificate2 certificate)
    {
        X509Extension ext = certificate.Extensions.Cast<X509Extension>().FirstOrDefault(
            e => e.Oid.Value == "2.5.29.31");

        if (ext == null || ext.RawData == null || ext.RawData.Length < 11)
            return EmptyStrings;

        int prev = -2;
        List<string> items = new List<string>();
        while (prev != -1 && ext.RawData.Length > prev + 1)
        {
            int next = IndexOf(ext.RawData, 0x86, prev == -2 ? 8 : prev + 1);
            if (next == -1)
            {
                if (prev >= 0)
                {
                    string item = Encoding.UTF8.GetString(ext.RawData, prev + 2, ext.RawData.Length - (prev + 2));
                    items.Add(item);
                }

                break;
            }

            if (prev >= 0 && next > prev)
            {
                string item = Encoding.UTF8.GetString(ext.RawData, prev + 2, next - (prev + 2));
                items.Add(item);
            }

            prev = next;
        }

        return items.ToArray();
    }

    static int IndexOf(byte[] instance, byte item, int start)
    {
        for (int i = start, l = instance.Length; i < l; i++)
            if (instance[i] == item)
                return i;

        return -1;
    }

    static string[] EmptyStrings = new string[0];



This is the method that tries to make the document ltv enabled

C#
public static void AddLtv(byte[] doc, string dest, IOcspClient ocsp, ICrlClient crl, ITSAClient tsa)
        {
            PdfReader r = new PdfReader(doc);
            FileStream fos = new FileStream(dest, FileMode.Create);
            PdfStamper stp = PdfStamper.CreateSignature(r, fos, '\0', null, true);
            LtvVerification v = stp.LtvVerification;
            AcroFields fields = stp.AcroFields;
            List<string> names = fields.GetSignatureNames();
            string sigName = names[names.Count - 1];
            PdfPKCS7 pkcs7 = fields.VerifySignature(sigName);
            if (pkcs7.IsTsp)
            {
                v.AddVerification(sigName, ocsp, crl,
                    LtvVerification.CertificateOption.SIGNING_CERTIFICATE,
                    LtvVerification.Level.OCSP_CRL,
                    LtvVerification.CertificateInclusion.NO);
            }
            else
            {
                foreach (string name in names)
                {
                    v.AddVerification(name, ocsp, crl,
                        LtvVerification.CertificateOption.WHOLE_CHAIN,
                        LtvVerification.Level.OCSP_CRL,
                        LtvVerification.CertificateInclusion.NO);
                }
            }
            PdfSignatureAppearance sap = stp.SignatureAppearance;
            LtvTimestamp.Timestamp(sap, tsa, null);
        }


What I have tried:

public static byte[] Sign(byte[] document, X509Certificate2 certificate, ITSAClient tsaClient)
        {
            byte[] signedDocument = null;

            IExternalSignature signature = new X509Certificate2Signature(certificate, "SHA-1");
            Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser();
            Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { cp.ReadCertificate(certificate.RawData) };

            PdfReader reader = new PdfReader(document);
            MemoryStream ms = new MemoryStream();
            PdfStamper st = PdfStamper.CreateSignature(reader, ms, '\0');

            PdfSignatureAppearance sap = st.SignatureAppearance;
            sap.CertificationLevel = PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED;
            sap.SignatureCreator = "NAME";
            sap.Reason = "REASON";
            sap.Contact = "CONTACT";
            sap.Location = "LOCATION";
            sap.SignDate = DateTime.Now;

            RectangleF rectangle = new RectangleF(400.98139f, 54.88828f, 530, 84.88828f);
            sap.Layer2Font = iTextSharp.text.FontFactory.GetFont(BaseFont.TIMES_ROMAN, BaseFont.CP1257, 7f);
            sap.Layer2Font.Color = iTextSharp.text.BaseColor.RED;            
            sap.Layer2Text = string.Format("Signed for testing: {0}", DateTime.Now.ToString("dd.MM.yyyy."));            
            sap.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.DESCRIPTION;
            sap.SetVisibleSignature(new iTextSharp.text.Rectangle(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height), 1, null);

            IOcspClient ocspClient = new OcspClientBouncyCastle();

            ICrlClient crlClient = new CrlClientOnline();
            List<ICrlClient> crlList = new List<ICrlClient>();

            string[] crls = GetCrlDistributionPoints(certificate);

            crlClient = new CrlClientOnline(crls);
            crlList.Add(crlClient);

            MakeSignature.SignDetached(sap, signature, chain, crlList, ocspClient, tsaClient, 0, CryptoStandard.CMS);

            // ADD ltv to document
            AddLtv(signedDocument, @"d:\test.pdf", ocspClient, crlClient, tsaClient);

            st.Close();
            ms.Flush();
            signedDocument = ms.ToArray();
            ms.Close();

            reader.Close();

            return signedDocument;
        }
Posted
Updated 20-Sep-18 0:29am
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900