/// <summary>
/// Signs a PDF or PDF/A document using specified certificate.
/// </summary>
/// <param name="inputFilename">The filename of input PDF document.</param>
/// <param name="outputFilename">The filename of output PDF document.</param>
/// <param name="certificate">The certificate that should be used
/// for signing the input PDF document.</param>
/// <param name="conformance">The conformance of PDF document.</param>
public static void SignDocument(
string inputFilename,
string outputFilename,
Vintasoft.Imaging.Pdf.PdfDocumentConformance conformance,
System.Security.Cryptography.X509Certificates.X509Certificate2 certificate)
{
SignDocument(inputFilename, outputFilename, conformance, certificate, false, null);
}
/// <summary>
/// Signs with timestamp a PDF or PDF/A document using specified certificate.
/// </summary>
/// <param name="inputFilename">The filename of input PDF document.</param>
/// <param name="outputFilename">The filename of output PDF document.</param>
/// <param name="certificate">The certificate that should be used
/// for signing the input PDF document.</param>
/// <param name="addCertificateChain">A value indicating whether signing certificate chain must be added to signature.</param>
/// <param name="conformance">The conformance of PDF document.</param>
/// <param name="timestampServerUrl">Timestamp server URL.</param>
public static void SignDocument(
string inputFilename,
string outputFilename,
Vintasoft.Imaging.Pdf.PdfDocumentConformance conformance,
System.Security.Cryptography.X509Certificates.X509Certificate2 certificate,
bool addCertificateChain,
string timestampServerUrl)
{
Vintasoft.Imaging.Pdf.Processing.PdfDocumentConverter converter = null;
// if PDF document conformance is specified
if (conformance != Vintasoft.Imaging.Pdf.PdfDocumentConformance.Undefined)
{
// create PDF document converter
converter = Vintasoft.Imaging.Pdf.Processing.PdfDocumentConverter.Create(conformance);
// if is PDF/A converter
Vintasoft.Imaging.Pdf.Processing.PdfA.PdfAConverter pdfAConverter = converter as Vintasoft.Imaging.Pdf.Processing.PdfA.PdfAConverter;
if (pdfAConverter != null)
{
// set ICC profiles
//pdfAConverter.DefaultCmykIccProfileFilename = "DefaultCMYK.icc";
//pdfAConverter.DefaultRgbIccProfileFilename = "DefaultRGB.icc";
}
// if PDF document converter is not found
if (converter == null)
{
string message = string.Format("Unsupported {0} conformance.", conformance);
throw new System.ArgumentOutOfRangeException(message);
}
}
// open PDF document
using (Vintasoft.Imaging.Pdf.PdfDocument document = new Vintasoft.Imaging.Pdf.PdfDocument(inputFilename))
{
// add signature
AddSignature(document, certificate, addCertificateChain, timestampServerUrl, 1);
// if PDF document cannot be converted
if (converter == null)
{
if (inputFilename == outputFilename)
{
// sign PDF document and save changes in PDF document
document.SaveChanges();
}
else
{
// sign PDF document and save PDF document to the output file
document.SaveChanges(outputFilename);
}
}
else
{
if (inputFilename != outputFilename)
{
Vintasoft.Imaging.Pdf.Processing.PdfA.PdfAConverter pdfAConverter =
(Vintasoft.Imaging.Pdf.Processing.PdfA.PdfAConverter)converter;
pdfAConverter.OutputFilename = outputFilename;
}
// sign and convert PDF document
Vintasoft.Imaging.Processing.ConversionProfileResult conversionResult =
converter.Convert(document, new Vintasoft.Imaging.Processing.ProcessingState());
// if conversion falied
if (!conversionResult.IsSuccessful)
{
// throw conversion exception
throw conversionResult.CreateConversionException();
}
}
}
}
/// <summary>
/// Adds a digital signature to specified PDF document.
/// </summary>
/// <param name="document">The PDF document.</param>
/// <param name="certificate">The certificate that should be added.</param>
/// <param name="timestampServerUrl">Timestamp server URL.</param>
/// <param name="addCertificateChain">A value indicating whether signing certificate chain must be added to signature.</param>
/// <param name="sigNumber">The number of signature field.</param>
private static void AddSignature(
Vintasoft.Imaging.Pdf.PdfDocument document,
System.Security.Cryptography.X509Certificates.X509Certificate2 certificate,
bool addCertificateChain,
string timestampServerUrl,
int sigNumber)
{
// if PDF document does not have interactive form
if (document.InteractiveForm == null)
{
// create the interactive form in document
document.InteractiveForm = new Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfDocumentInteractiveForm(document);
}
// specify that document contains signatures
document.InteractiveForm.SignatureFlags =
Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfDocumentSignatureFlags.SignaturesExist |
Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfDocumentSignatureFlags.AppendOnly;
// specify that the viewer application must NOT construct appearance streams and
// appearance properties for widget annotations in the document
document.InteractiveForm.NeedAppearances = false;
// get PDF page on which signature will be placed
Vintasoft.Imaging.Pdf.Tree.PdfPage page = document.Pages[0];
// calculate the signature field rectangle (field will be placed in the bottom-center of page)
System.Drawing.RectangleF signatureRect = new System.Drawing.RectangleF();
signatureRect.Width = page.MediaBox.Width / 5;
signatureRect.Height = signatureRect.Width / 3;
signatureRect.X = page.MediaBox.X + (page.MediaBox.Width - signatureRect.Width) / 2;
signatureRect.Y = page.MediaBox.Y + signatureRect.Height * sigNumber;
// create parameters for creation of PKCS#7 signature
Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignatureCreationParams creationParams =
new Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignatureCreationParams(certificate, addCertificateChain);
// if timestamp server is specified
if (!string.IsNullOrEmpty(timestampServerUrl))
{
// specify the timestamp authority client
creationParams.TimestampAuthorityClient = new Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.TimestampAuthorityWebClient(timestampServerUrl);
}
// create PKCS#7 signature
Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignature signature = Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignature.CreatePkcs7Signature(
document.Format, creationParams);
// create signature info
Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfSignatureInformation signatureInfo =
new Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfSignatureInformation(document, signature);
signatureInfo.SignerName = certificate.GetNameInfo(
System.Security.Cryptography.X509Certificates.X509NameType.SimpleName, false);
signatureInfo.Reason = "Test signing";
signatureInfo.Location = System.Globalization.CultureInfo.CurrentCulture.EnglishName;
signatureInfo.SigningTime = System.DateTime.Now;
// create the signature field
Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfInteractiveFormSignatureField signatureField =
new Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfInteractiveFormSignatureField(document, string.Format("MySignature{0}", sigNumber), signatureRect);
// set the signature information
signatureField.SignatureInfo = signatureInfo;
// create the signature appearance
using (Vintasoft.Imaging.Pdf.Drawing.PdfGraphics g = signatureField.CreateAppearanceGraphics())
{
// signature text
string signatureText = string.Format("Digitally signed by\n{0}",
signatureInfo.SignerName);
// signature appearance rect
System.Drawing.RectangleF rect = new System.Drawing.RectangleF(
System.Drawing.PointF.Empty,
signatureField.Annotation.Rectangle.Size);
// draw background
g.FillRectangle(new Vintasoft.Imaging.Pdf.Drawing.PdfBrush(
System.Drawing.Color.FromArgb(255, System.Drawing.Color.Lime)), rect);
// padding
rect.Inflate(-rect.Height / 10, -rect.Height / 10);
// create TimesRoman font
Vintasoft.Imaging.Pdf.Tree.Fonts.PdfFont font = document.FontManager.GetStandardFont(
Vintasoft.Imaging.Pdf.Tree.Fonts.PdfStandardFontType.TimesRoman);
// measure font size
float fontSize = g.MeasureFontSize(signatureText, font, rect.Width, rect.Height);
// draw signture text
g.DrawString(
signatureText,
font, fontSize, new Vintasoft.Imaging.Pdf.Drawing.PdfBrush(System.Drawing.Color.Black),
rect, Vintasoft.Imaging.Pdf.Drawing.PdfContentAlignment.Center, false);
}
// add signature field to the interactive form of document
document.InteractiveForm.Fields.Add(signatureField);
// if PDF page does not have annotations
if (page.Annotations == null)
// create an empty annotation collection for page
page.Annotations = new Vintasoft.Imaging.Pdf.Tree.Annotations.PdfAnnotationList(document);
// add widget annotation of signature field to the annotation collection of page
page.Annotations.Add(signatureField.Annotation);
}
''' <summary>
''' Signs a PDF or PDF/A document using specified certificate.
''' </summary>
''' <param name="inputFilename">The filename of input PDF document.</param>
''' <param name="outputFilename">The filename of output PDF document.</param>
''' <param name="certificate">The certificate that should be used
''' for signing the input PDF document.</param>
''' <param name="conformance">The conformance of PDF document.</param>
Public Shared Sub SignDocument(inputFilename As String, outputFilename As String, conformance As Vintasoft.Imaging.Pdf.PdfDocumentConformance, certificate As System.Security.Cryptography.X509Certificates.X509Certificate2)
SignDocument(inputFilename, outputFilename, conformance, certificate, False, Nothing)
End Sub
''' <summary>
''' Signs with timestamp a PDF or PDF/A document using specified certificate.
''' </summary>
''' <param name="inputFilename">The filename of input PDF document.</param>
''' <param name="outputFilename">The filename of output PDF document.</param>
''' <param name="certificate">The certificate that should be used
''' for signing the input PDF document.</param>
''' <param name="addCertificateChain">A value indicating whether signing certificate chain must be added to signature.</param>
''' <param name="conformance">The conformance of PDF document.</param>
''' <param name="timestampServerUrl">Timestamp server URL.</param>
Public Shared Sub SignDocument(inputFilename As String, outputFilename As String, conformance As Vintasoft.Imaging.Pdf.PdfDocumentConformance, certificate As System.Security.Cryptography.X509Certificates.X509Certificate2, addCertificateChain As Boolean, timestampServerUrl As String)
Dim converter As Vintasoft.Imaging.Pdf.Processing.PdfDocumentConverter = Nothing
' if PDF document conformance is specified
If conformance <> Vintasoft.Imaging.Pdf.PdfDocumentConformance.Undefined Then
' create PDF document converter
converter = Vintasoft.Imaging.Pdf.Processing.PdfDocumentConverter.Create(conformance)
' if is PDF/A converter
Dim pdfAConverter As Vintasoft.Imaging.Pdf.Processing.PdfA.PdfAConverter = TryCast(converter, Vintasoft.Imaging.Pdf.Processing.PdfA.PdfAConverter)
' set ICC profiles
'pdfAConverter.DefaultCmykIccProfileFilename = "DefaultCMYK.icc";
'pdfAConverter.DefaultRgbIccProfileFilename = "DefaultRGB.icc";
If pdfAConverter IsNot Nothing Then
End If
' if PDF document converter is not found
If converter Is Nothing Then
Dim message As String = String.Format("Unsupported {0} conformance.", conformance)
Throw New System.ArgumentOutOfRangeException(message)
End If
End If
' open PDF document
Using document As New Vintasoft.Imaging.Pdf.PdfDocument(inputFilename)
' add signature
AddSignature(document, certificate, addCertificateChain, timestampServerUrl, 1)
' if PDF document cannot be converted
If converter Is Nothing Then
If inputFilename = outputFilename Then
' sign PDF document and save changes in PDF document
document.SaveChanges()
Else
' sign PDF document and save PDF document to the output file
document.SaveChanges(outputFilename)
End If
Else
If inputFilename <> outputFilename Then
Dim pdfAConverter As Vintasoft.Imaging.Pdf.Processing.PdfA.PdfAConverter = DirectCast(converter, Vintasoft.Imaging.Pdf.Processing.PdfA.PdfAConverter)
pdfAConverter.OutputFilename = outputFilename
End If
' sign and convert PDF document
Dim conversionResult As Vintasoft.Imaging.Processing.ConversionProfileResult = converter.Convert(document, New Vintasoft.Imaging.Processing.ProcessingState())
' if conversion falied
If Not conversionResult.IsSuccessful Then
' throw conversion exception
Throw conversionResult.CreateConversionException()
End If
End If
End Using
End Sub
''' <summary>
''' Adds a digital signature to specified PDF document.
''' </summary>
''' <param name="document">The PDF document.</param>
''' <param name="certificate">The certificate that should be added.</param>
''' <param name="timestampServerUrl">Timestamp server URL.</param>
''' <param name="addCertificateChain">A value indicating whether signing certificate chain must be added to signature.</param>
''' <param name="sigNumber">The number of signature field.</param>
Private Shared Sub AddSignature(document As Vintasoft.Imaging.Pdf.PdfDocument, certificate As System.Security.Cryptography.X509Certificates.X509Certificate2, addCertificateChain As Boolean, timestampServerUrl As String, sigNumber As Integer)
' if PDF document does not have interactive form
If document.InteractiveForm Is Nothing Then
' create the interactive form in document
document.InteractiveForm = New Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfDocumentInteractiveForm(document)
End If
' specify that document contains signatures
document.InteractiveForm.SignatureFlags = Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfDocumentSignatureFlags.SignaturesExist Or Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfDocumentSignatureFlags.AppendOnly
' specify that the viewer application must NOT construct appearance streams and
' appearance properties for widget annotations in the document
document.InteractiveForm.NeedAppearances = False
' get PDF page on which signature will be placed
Dim page As Vintasoft.Imaging.Pdf.Tree.PdfPage = document.Pages(0)
' calculate the signature field rectangle (field will be placed in the bottom-center of page)
Dim signatureRect As New System.Drawing.RectangleF()
signatureRect.Width = page.MediaBox.Width / 5
signatureRect.Height = signatureRect.Width / 3
signatureRect.X = page.MediaBox.X + (page.MediaBox.Width - signatureRect.Width) / 2
signatureRect.Y = page.MediaBox.Y + signatureRect.Height * sigNumber
' create parameters for creation of PKCS#7 signature
Dim creationParams As New Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignatureCreationParams(certificate, addCertificateChain)
' if timestamp server is specified
If Not String.IsNullOrEmpty(timestampServerUrl) Then
' specify the timestamp authority client
creationParams.TimestampAuthorityClient = New Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.TimestampAuthorityWebClient(timestampServerUrl)
End If
' create PKCS#7 signature
Dim signature As Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignature = Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignature.CreatePkcs7Signature(document.Format, creationParams)
' create signature info
Dim signatureInfo As New Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfSignatureInformation(document, signature)
signatureInfo.SignerName = certificate.GetNameInfo(System.Security.Cryptography.X509Certificates.X509NameType.SimpleName, False)
signatureInfo.Reason = "Test signing"
signatureInfo.Location = System.Globalization.CultureInfo.CurrentCulture.EnglishName
signatureInfo.SigningTime = System.DateTime.Now
' create the signature field
Dim signatureField As New Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfInteractiveFormSignatureField(document, String.Format("MySignature{0}", sigNumber), signatureRect)
' set the signature information
signatureField.SignatureInfo = signatureInfo
' create the signature appearance
Using g As Vintasoft.Imaging.Pdf.Drawing.PdfGraphics = signatureField.CreateAppearanceGraphics()
' signature text
Dim signatureText As String = String.Format("Digitally signed by" & vbLf & "{0}", signatureInfo.SignerName)
' signature appearance rect
Dim rect As New System.Drawing.RectangleF(System.Drawing.PointF.Empty, signatureField.Annotation.Rectangle.Size)
' draw background
g.FillRectangle(New Vintasoft.Imaging.Pdf.Drawing.PdfBrush(System.Drawing.Color.FromArgb(255, System.Drawing.Color.Lime)), rect)
' padding
rect.Inflate(-rect.Height / 10, -rect.Height / 10)
' create TimesRoman font
Dim font As Vintasoft.Imaging.Pdf.Tree.Fonts.PdfFont = document.FontManager.GetStandardFont(Vintasoft.Imaging.Pdf.Tree.Fonts.PdfStandardFontType.TimesRoman)
' measure font size
Dim fontSize As Single = g.MeasureFontSize(signatureText, font, rect.Width, rect.Height)
' draw signture text
g.DrawString(signatureText, font, fontSize, New Vintasoft.Imaging.Pdf.Drawing.PdfBrush(System.Drawing.Color.Black), rect, Vintasoft.Imaging.Pdf.Drawing.PdfContentAlignment.Center, _
False)
End Using
' add signature field to the interactive form of document
document.InteractiveForm.Fields.Add(signatureField)
' if PDF page does not have annotations
If page.Annotations Is Nothing Then
' create an empty annotation collection for page
page.Annotations = New Vintasoft.Imaging.Pdf.Tree.Annotations.PdfAnnotationList(document)
End If
' add widget annotation of signature field to the annotation collection of page
page.Annotations.Add(signatureField.Annotation)
End Sub