PadesLevels.cs
- //
- // This code is part of Document Solutions for PDF demos.
- // Copyright (c) MESCIUS inc. All rights reserved.
- //
- using System;
- using System.IO;
- using System.Drawing;
- using System.Text;
- using System.Linq;
- using System.Collections.Generic;
- using System.Security.Cryptography;
- using System.Security.Cryptography.X509Certificates;
-
- using GrapeCity.Documents.Pdf;
- using GrapeCity.Documents.Pdf.Security;
- using GrapeCity.Documents.Pdf.AcroForms;
- using GrapeCity.Documents.Text;
-
-
- namespace DsPdfWeb.Demos
- {
- // This sample shows how to sign an existing PDF file containing
- // an empty signature field with a signature that complies with
- // the various PAdES (PDF Advanced Electronic Signatures) levels.
- // Note that when run online, this sample simply returns an unsigned
- // PDF with an empty signature field. To actually sign the PDF
- // you will need to provide a valid .pfx file (see "JohnDoe.pfx").
- // The sample contains 5 methods that can be used to sign a PDF
- // with the various PAdES levels, the last 3 methods can be
- // used in a chain to incrementally increase the signature strength.
- // To check the signature compliance, open the signed PDF in Acrobat
- // Reader and inspect the signature properties.
- //
- // IMPORTANT! The code in this sample WILL NOT work correctly
- // unless DsPdf is licensed with a valid license key.
- // Email us.sales@mescius.com to obtain a trial key.
- public class PadesLevels
- {
- // Certificate issued by CA Cert Signing Authority, used for verification:
- static X509Certificate2 s_caCertRoot = new X509Certificate2(Path.Combine("Resources", "Misc", "CACertRoot.crt"));
- // TODO: replace with a real certificate:
- static X509Certificate2 s_cert = new X509Certificate2(Path.Combine("Resources", "Misc", "JohnDoe.pfx"), "secret");
-
- static PadesLevels()
- {
- // TODO: GcPdfDocument MUST BE LICENSED for the signatures to remain valid,
- // as otherwise the license nag text added when saving the PDF invalidates
- // incremental updates. Email us.sales@mescius.com to obtain a trial key.
- // GcPdfDocument.SetLicenseKey("my key");
- }
-
- public void CreatePDF(Stream stream, int paramsIdx = 0)
- {
- CreatePDF(stream, GetSampleParamsList()[paramsIdx]);
- }
-
- // While this sample includes code that does the actual signing and time stamping,
- // that code is NOT executed by the online demo. So the online sample driver
- // simply returns the PDF that includes info about the selected PAdES level,
- // and can be signed or time stamped using a valid certificate.
- // You can copy the corresponding code and use it in your applications.
- public void CreatePDF(Stream stream, string[] sampleParams)
- {
- // TODO: change to true to actually run the signing/time stamping code:
- bool doSigning = false;
-
- // The unsigned PDF with a signature field to sign:
- var fn = Path.Combine("Resources", "PDFs", sampleParams[3]);
-
- if (doSigning)
- {
- // Running this code will produce 5 PDFs with increasing PAdES levels:
-
- // PAdES B-B:
- Do_B_B(fn);
- // PAdES B-T:
- Do_B_T(fn);
- // Note that the next 3 steps use PDFs produced by the previous step,
- // incrementally adding verification info:
- // PAdES B-LT:
- Do_B_LT("B-T.pdf");
- // PAdES B-LTA:
- Do_B_LTA("B-LT.pdf");
- // LTV Enabled:
- Do_B_LTA_LTV("B-LTA.pdf");
- }
-
- // Copy the source PDF to output stream
- // to provide the demo result:
- using var fs = File.OpenRead(fn);
- fs.CopyTo(stream);
- }
-
- // Signs a PDF with a PAdES B-B Level signature:
- void Do_B_B(string fn)
- {
- using FileStream fs = File.OpenRead(fn);
- var doc = new GcPdfDocument();
- doc.Load(fs);
-
- var signField = doc.AcroForm.Fields.FirstOrDefault(f_ => f_ is SignatureField);
- if (signField == null)
- throw new Exception("Could not find a signature field.");
-
- var sp = new SignatureProperties()
- {
- SignatureField = signField,
- SignatureBuilder = new Pkcs7SignatureBuilder(s_cert)
- {
- Format = Pkcs7SignatureBuilder.SignatureFormat.ETSI_CAdES_detached,
- },
- };
- // Sign and save the PDF to a file:
- doc.Sign(sp, "B-B.pdf");
- }
-
- // Signs a PDF with a PAdES B-T Level signature:
- void Do_B_T(string fn)
- {
- using FileStream fs = File.OpenRead(fn);
- var doc = new GcPdfDocument();
- doc.Load(fs);
-
- var signField = doc.AcroForm.Fields.FirstOrDefault(f_ => f_ is SignatureField);
- if (signField == null)
- throw new Exception("Could not find a signature field.");
-
- var sp = new SignatureProperties()
- {
- SignatureField = signField,
- SignatureBuilder = new Pkcs7SignatureBuilder(s_cert)
- {
- Format = Pkcs7SignatureBuilder.SignatureFormat.ETSI_CAdES_detached,
- },
- TimeStamp = new TimeStamp(@"http://ts.ssl.com"),
- };
- // Sign and save the PDF to a file:
- doc.Sign(sp, "B-T.pdf");
- }
-
- // Adds LTV information to a B-T level signature (e.g. as created by the do_B_T method above),
- // which makes the signature compliant with PAdES B-LT:
- void Do_B_LT(string fn)
- {
- using FileStream fs = File.OpenRead(fn);
- var doc = new GcPdfDocument();
- doc.Load(fs);
-
- var signField = doc.AcroForm.Fields.FirstOrDefault(f_ => f_ is SignatureField);
- if (signField == null)
- throw new Exception("Could not find a signature field.");
-
- // Get the signature and add verification information for it:
- var sig = (Signature)signField.Value;
- var vp = new DocumentSecurityStore.VerificationParams();
- vp.Certificates = new X509Certificate2[] { s_caCertRoot };
- if (!doc.SecurityStore.AddVerification(sig, vp))
- throw new Exception($"Could not add verification for {sig.Name}.");
-
- // Save the PDF to a file using incremental update so that the signature remains valid:
- doc.Save("B-LT.pdf", SaveMode.IncrementalUpdate);
- }
-
- // Adds time stamp to a signed PDF (e.g. as created by the do_B_LT method above),
- // which makes the document compliant with B-LTA level:
- void Do_B_LTA(string fn)
- {
- using FileStream fs = File.OpenRead(fn);
- var doc = new GcPdfDocument();
- doc.Load(fs);
-
- var ts = new TimeStampProperties()
- {
- TimeStamp = new TimeStamp(@"http://ts.ssl.com"),
- };
- // Save the PDF to a file adding a time stamp to it:
- doc.TimeStamp(ts, "B-LTA.pdf");
- }
-
- // Adds verification information for a PDF time-stamp (e.g. as created by the do_B_LTA method above)
- // which makes the signature LTV enabled:
- void Do_B_LTA_LTV(string fn)
- {
- using FileStream fs = File.OpenRead(fn);
- var doc = new GcPdfDocument();
- doc.Load(fs);
-
- var signField = doc.AcroForm.Fields.FirstOrDefault(f_ => f_ is SignatureField);
- if (signField == null)
- throw new Exception("Could not find a signature field.");
-
- // Get the signature and add verification information for it:
- var sig = (Signature)signField.Value;
- if (!doc.SecurityStore.AddVerification(sig))
- throw new Exception($"Could not add verification for {sig.Name}.");
-
- // Save the PDF to a file using incremental update so that the signature remains valid:
- doc.Save("B-LTA_LTV.pdf", SaveMode.IncrementalUpdate);
- }
-
- public static List<string[]> GetSampleParamsList()
- {
- // Strings are name, description, info, rest are arbitrary strings:
- return new List<string[]>()
- {
- new string[] { "@b-sign/PAdES B-B Level", "How to sign a PDF complying with PAdES B-B level", "",
- "PAdES-B-B.pdf" },
- new string[] { "@b-sign/PAdES B-T Level", "How to sign a PDF complying with PAdES B-T level", "",
- "PAdES-B-T.pdf" },
- new string[] { "@b-sign/PAdES B-LT Level", "How to add LTV information to a signature", "",
- "PAdES-B-LT.pdf" },
- new string[] { "@b-sign/PAdES B-LTA Level", "How to time stamp a signed PDF", "",
- "PAdES-B-LTA.pdf" },
- new string[] { "@b-sign/LTV Enabled Signature", "How to make a signature LTV enabled", "",
- "PAdES-B-LTA-LTV.pdf" },
- };
- }
- }
- }
-