VintaSoft Imaging .NET SDK 15.2: Documentation for .NET developer
In This Topic
PDF: How to verify digital signatures in PDF document
In This Topic
If digital signatures should be verified in PDF document, the following steps must be done:
Here is C#/VB.NET code that demonstrates how to check whether signatures in PDF document are authentic:
/// <summary>
/// Displays and verifies signatures of PDF document.
/// </summary>
/// <param name="pdfFilename">The filename of PDF document.</param>
public static void VerifyDocumentSignatures(string pdfFilename)
{
    // open PDF document
    using (Vintasoft.Imaging.Pdf.PdfDocument document = 
        new Vintasoft.Imaging.Pdf.PdfDocument(pdfFilename))
    {
        // if document does not have interactive form
        if (document.InteractiveForm == null)
        {
            System.Console.WriteLine("Signature fields are not found.");
            return;
        }

        // get an array of signature fields of document
        Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfInteractiveFormSignatureField[] signatureFields =
            document.InteractiveForm.GetSignatureFields();
        // if document does not have signature fields
        if (signatureFields.Length == 0)
        {
            System.Console.WriteLine("Signture fields are not found.");
            return;
        }

        // for each signature field
        for (int i = 0; i < signatureFields.Length; i++)
        {
            // get reference to the signature field
            Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfInteractiveFormSignatureField signatureField = signatureFields[i];
            // print signature field name
            System.Console.WriteLine(string.Format("[{0}]Signaure field: {1}", i + 1, signatureField.FullyQualifiedName));

            // get information about signature
            Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfSignatureInformation signatureInfo = signatureField.SignatureInfo;
            // if signature information is empty
            if (signatureInfo == null)
            {
                System.Console.WriteLine("Empty signature field.");
            }
            // if signature information is NOT empty
            else
            {
                // check is document timestamp signature
                if (signatureInfo.IsTimeStamp)
                    System.Console.WriteLine("Signature is a document timestamp signature");

                // print signature filter
                System.Console.WriteLine(string.Format("Filter      : {0} ({1})", signatureInfo.Filter, signatureInfo.SubFilter));
                // print the signer name
                if (signatureInfo.SignerName != null)
                    System.Console.WriteLine(string.Format("Signed by   : {0}", signatureInfo.SignerName));
                // print the signature reason
                if (signatureInfo.Reason != null)
                    System.Console.WriteLine(string.Format("Reason      : {0}", signatureInfo.Reason));
                // print the signature location
                if (signatureInfo.Location != null)
                    System.Console.WriteLine(string.Format("Location    : {0}", signatureInfo.Location));
                // print the signer contact info
                if (signatureInfo.ContactInfo != null)
                    System.Console.WriteLine(string.Format("Contact Info: {0}", signatureInfo.ContactInfo));
                // print the signing date
                if (signatureInfo.SigningTime != System.DateTime.MinValue)
                    System.Console.WriteLine(string.Format("Signig Date : {0}", signatureInfo.SigningTime.ToString("f")));

                // get PKCS signature
                bool error = false;
                Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignature signature = null;
                try
                {
                    signature = signatureInfo.GetSignature();
                }
                catch (System.Exception e)
                {
                    error = true;
                    System.Console.WriteLine("PKCS signature parsing error: {0}", e.Message);
                }
                if (error)
                    continue;

                // print name of signature algorithm
                System.Console.WriteLine(string.Format("Algorithm   : {0}", signature.SignatureAlgorithmName));

                // print information about signature certificate chain
                System.Console.WriteLine("Sign certificate chain:");
                System.Security.Cryptography.X509Certificates.X509Certificate2[] signCertChain = 
                    signature.SigningCertificateChain;
                string padding = "";
                foreach (System.Security.Cryptography.X509Certificates.X509Certificate2 cert in signCertChain)
                {
                    padding += "    ";
                    System.Console.WriteLine("{0}Serial number: {1}", padding, cert.SerialNumber);
                    System.Console.WriteLine("{0}Issuer       : {1}", padding, cert.GetNameInfo(
                        System.Security.Cryptography.X509Certificates.X509NameType.SimpleName, true));
                    System.Console.WriteLine("{0}Subject      : {1}", padding, cert.GetNameInfo(
                        System.Security.Cryptography.X509Certificates.X509NameType.SimpleName, false));
                }


                // verify digital signature
                VerifyDigitalSignature(signatureInfo, signature);
            }
            System.Console.WriteLine();
        }
    }
}

/// <summary>
/// Verifies the digital signature.
/// </summary>
/// <param name="signature">The signature.</param>
/// <param name="signatureInfo">The signature information.</param>
/// <returns><b>true</b> if signature is valid; otherwise, <b>false</b>.</returns>
public static bool VerifyDigitalSignature(
    Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfSignatureInformation signatureInfo,
    Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignature signature)
{
    System.Console.WriteLine("Verifying signature...");

    bool signatureVerifyResult = false;
    bool embeddedTimestampVerifyResult = false;
    bool certificateVerifyResult = false;
    bool embeddedTimestampCertificateVerifyResult = false;
    bool signatureCoversWholeDocument = false;
    System.Security.Cryptography.X509Certificates.X509Chain certificateChain = null;
    System.Security.Cryptography.X509Certificates.X509Chain timestampCertificateChain = null;


    // verify signature

    try
    {
        // check that signature covers the whole document
        signatureCoversWholeDocument = signatureInfo.SignatureCoversWholeDocument();

        // verify PKCS signature
        signatureVerifyResult = signature.VerifySignature();

        // if signature has embedded timestamp
        if (signature.HasEmbeddedTimeStamp)
        {
            // verify embedded timestamp
            embeddedTimestampVerifyResult = signature.VerifyTimestamp();
        }

        // build and verify certificate chain
        certificateChain = new System.Security.Cryptography.X509Certificates.X509Chain();
        certificateVerifyResult = certificateChain.Build(signature.SigningCertificate);

        // if signature has embedded timestamp
        if (signature.HasEmbeddedTimeStamp)
        {
            // build and verify timestamp certificate chain
            timestampCertificateChain = new System.Security.Cryptography.X509Certificates.X509Chain();
            embeddedTimestampCertificateVerifyResult = certificateChain.Build(signature.TimestampCertificate);
        }

    }
    catch (System.Exception verificationException)
    {
        System.Console.WriteLine("Verification failed: {0}", verificationException.Message);
        return false;
    }

    bool pageContentModified = false;
    string subsequentChangesMessage = "";
    // if PKCS signature verification is passed AND signature does not cover the whole document
    if (signatureVerifyResult && !signatureCoversWholeDocument)
    {
        try
        {
            // if signature has revision info
            if (signatureInfo.SignedRevision != null)
            {
                // check subsequent changes
                using (Vintasoft.Imaging.Pdf.PdfDocumentRevisionComparer documentChanges = signatureInfo.GetDocumentChanges())
                {
                    // check subsequent changes in pages content
                    pageContentModified = documentChanges.HasModifiedPages;

                    // build subsequent changes message
                    if (documentChanges.ChangedPageContents.Count > 0)
                        subsequentChangesMessage += string.Format("{0} page(s) modified; ", documentChanges.ChangedPageContents.Count);
                    if (documentChanges.AddedPages.Count > 0)
                        subsequentChangesMessage += string.Format("{0} page(s) added; ", documentChanges.AddedPages.Count);
                    if (documentChanges.RemovedPages.Count > 0)
                        subsequentChangesMessage += string.Format("{0} page(s) removed; ", documentChanges.RemovedPages.Count);
                    if (documentChanges.RemovedAnnotations.Count > 0)
                        subsequentChangesMessage += string.Format("annotations(s) on {0} page(s) removed; ", documentChanges.RemovedAnnotations.Count);
                    if (documentChanges.RemovedAnnotations.Count > 0)
                        subsequentChangesMessage += string.Format("removed annotation(s) on {0} page(s); ", documentChanges.RemovedAnnotations.Count);
                    if (documentChanges.AddedAnnotations.Count > 0)
                        subsequentChangesMessage += string.Format("added annotation(s) on {0} page(s); ", documentChanges.AddedAnnotations.Count);
                    if (documentChanges.ChangedAnnotations.Count > 0)
                        subsequentChangesMessage += string.Format("changed annotation(s) on {0} page(s); ", documentChanges.ChangedAnnotations.Count);
                    if (documentChanges.MiscellaneousChanges.Count > 0)
                        subsequentChangesMessage += string.Format("miscellaneous changes: {0}; ", documentChanges.MiscellaneousChanges.Count);
                }
            }
        }
        catch (System.Exception verificationException)
        {
            System.Console.WriteLine("Verification failed: {0}", verificationException.Message);
            return false;
        }
    }

    // print signature verification result

    // if PKCS signature verification is failed OR
    // signature does not cover the whole document AND page(s) content is modified
    if (!signatureVerifyResult || (!signatureCoversWholeDocument && pageContentModified))
        System.Console.WriteLine("Signature is INVALID.");
    // if certificate verification is failed
    else if (!certificateVerifyResult || (signature.HasEmbeddedTimeStamp && (!embeddedTimestampCertificateVerifyResult || !embeddedTimestampVerifyResult)))
        System.Console.WriteLine("Signature validity is UNKNOWN.");
    else
        System.Console.WriteLine("Signature is VALID.");


    // print signature verification details

    // if signature verification is successful
    if (signatureVerifyResult)
    {
        // if signature covers the whole document
        if (signatureCoversWholeDocument)
        {
            System.Console.WriteLine("    Signature verification: Document has not been modified since this signature was applied.");
        }
        // if signature does NOT cover the whole document
        else
        {
            if (pageContentModified)
            {
                System.Console.WriteLine("    Signature verification: Document has been modified or corrupted since it was signed.");
                System.Console.WriteLine(string.Format("    Subsequent changes: {0}.", subsequentChangesMessage));
            }
            else if (subsequentChangesMessage != "")
            {
                System.Console.WriteLine("    Signature verification: The revision of the document that was covered by this signature has not been altered; however, there have been subsequent changes to the document.");
                System.Console.WriteLine(string.Format("    Subsequent changes: {0}.", subsequentChangesMessage));
            }
            else
            {
                System.Console.WriteLine("    Signature verification: Document has not been modified since this signature was applied.");
            }
        }
    }
    // if signature verification is NOT successful
    else
    {
        System.Console.WriteLine("    Signature verification: Document has been modified or corrupted since it was signed.");
    }

    // if signature has embedded timestamp
    if (signature.HasEmbeddedTimeStamp)
    {
        if (embeddedTimestampVerifyResult)
            System.Console.WriteLine("    Timestamp verification: Timestamp is valid.");
        else
            System.Console.WriteLine("    Timestamp verification: Timestamp is valid.");
    }


    // print certificate verification details

    // if certificate chain is present
    if (certificateChain != null)
    {
        // if certificate verification is successful
        if (certificateVerifyResult)
        {
            System.Console.WriteLine("    Certificate verification: Signer's certificate is valid.");
        }
        // if certificate verification is NOT successful
        else
        {
            // print certificate verification status
            System.Console.WriteLine("    Certificate verification: Signer's certificate is invalid:");
            foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in certificateChain.ChainStatus)
                System.Console.Write(string.Format("        {0}: {1}", status.Status, status.StatusInformation));
        }
    }

    // if timestamp certificate chain is present
    if (timestampCertificateChain != null)
    {
        // if timestamp certificate verification is successful
        if (embeddedTimestampCertificateVerifyResult)
        {
            System.Console.WriteLine("    Timestamp certificate verification: Signer's certificate is valid.");
        }
        // if timestamp certificate verification is NOT successful
        else
        {
            // print certificate verification status
            System.Console.WriteLine("    Timestamp certificate verification: Signer's certificate is invalid:");
            foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in timestampCertificateChain.ChainStatus)
                System.Console.Write(string.Format("        {0}: {1}", status.Status, status.StatusInformation));
        }
    }

    // if signature is not verified
    if (!signatureVerifyResult)
        return false;

    // if signature does NOT cover the whole document and page content was modified
    if (!signatureCoversWholeDocument && pageContentModified)
        return false;

    // if signature certificate is NOT verified
    if (!certificateVerifyResult)
        return false;
    
    if (signature.HasEmbeddedTimeStamp)
    {
        // if timestamp is NOT verified
        if (!embeddedTimestampVerifyResult)
            return false;

        // if timestamp certifiacet is NOT verified
        if (!embeddedTimestampCertificateVerifyResult)
            return false;
    }

    // sigature is VALID
    return true;
}
''' <summary>
''' Displays and verifies signatures of PDF document.
''' </summary>
''' <param name="pdfFilename">The filename of PDF document.</param>
Public Shared Sub VerifyDocumentSignatures(pdfFilename As String)
    ' open PDF document
    Using document As New Vintasoft.Imaging.Pdf.PdfDocument(pdfFilename)
        ' if document does not have interactive form
        If document.InteractiveForm Is Nothing Then
            System.Console.WriteLine("Signature fields are not found.")
            Return
        End If

        ' get an array of signature fields of document
        Dim signatureFields As Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfInteractiveFormSignatureField() = _
            document.InteractiveForm.GetSignatureFields()
        ' if document does not have signature fields
        If signatureFields.Length = 0 Then
            System.Console.WriteLine("Signture fields are not found.")
            Return
        End If

        ' for each signature field
        For i As Integer = 0 To signatureFields.Length - 1
            ' get reference to the signature field
            Dim signatureField As Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfInteractiveFormSignatureField = signatureFields(i)
            ' print signature field name
            System.Console.WriteLine(String.Format("[{0}]Signaure field: {1}", i + 1, signatureField.FullyQualifiedName))

            ' get information about signature
            Dim signatureInfo As Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfSignatureInformation = signatureField.SignatureInfo
            ' if signature information is empty
            If signatureInfo Is Nothing Then
                System.Console.WriteLine("Empty signature field.")
            Else
                ' if signature information is NOT empty
                ' check is document timestamp signature
                If signatureInfo.IsTimeStamp Then
                    System.Console.WriteLine("Signature is a document timestamp signature")
                End If

                ' print signature filter
                System.Console.WriteLine(String.Format("Filter      : {0} ({1})", signatureInfo.Filter, signatureInfo.SubFilter))
                ' print the signer name
                If signatureInfo.SignerName IsNot Nothing Then
                    System.Console.WriteLine(String.Format("Signed by   : {0}", signatureInfo.SignerName))
                End If
                ' print the signature reason
                If signatureInfo.Reason IsNot Nothing Then
                    System.Console.WriteLine(String.Format("Reason      : {0}", signatureInfo.Reason))
                End If
                ' print the signature location
                If signatureInfo.Location IsNot Nothing Then
                    System.Console.WriteLine(String.Format("Location    : {0}", signatureInfo.Location))
                End If
                ' print the signer contact info
                If signatureInfo.ContactInfo IsNot Nothing Then
                    System.Console.WriteLine(String.Format("Contact Info: {0}", signatureInfo.ContactInfo))
                End If
                ' print the signing date
                If signatureInfo.SigningTime <> System.DateTime.MinValue Then
                    System.Console.WriteLine(String.Format("Signig Date : {0}", signatureInfo.SigningTime.ToString("f")))
                End If

                ' get PKCS signature
                Dim [error] As Boolean = False
                Dim signature As Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignature = Nothing
                Try
                    signature = signatureInfo.GetSignature()
                Catch e As System.Exception
                    [error] = True
                    System.Console.WriteLine("PKCS signature parsing error: {0}", e.Message)
                End Try
                If [error] Then
                    Continue For
                End If

                ' print name of signature algorithm
                System.Console.WriteLine(String.Format("Algorithm   : {0}", signature.SignatureAlgorithmName))

                ' print information about signature certificate chain
                System.Console.WriteLine("Sign certificate chain:")
                Dim signCertChain As System.Security.Cryptography.X509Certificates.X509Certificate2() = _
                    signature.SigningCertificateChain
                Dim padding As String = ""
                For Each cert As System.Security.Cryptography.X509Certificates.X509Certificate2 In signCertChain
                    padding += "    "
                    System.Console.WriteLine("{0}Serial number: {1}", padding, cert.SerialNumber)
                    System.Console.WriteLine("{0}Issuer       : {1}", padding, cert.GetNameInfo(System.Security.Cryptography.X509Certificates.X509NameType.SimpleName, True))
                    System.Console.WriteLine("{0}Subject      : {1}", padding, cert.GetNameInfo(System.Security.Cryptography.X509Certificates.X509NameType.SimpleName, False))
                Next


                ' verify digital signature
                VerifyDigitalSignature(signatureInfo, signature)
            End If
            System.Console.WriteLine()
        Next
    End Using
End Sub

''' <summary>
''' Verifies the digital signature.
''' </summary>
''' <param name="signature">The signature.</param>
''' <param name="signatureInfo">The signature information.</param>
''' <returns><b>true</b> if signature is valid; otherwise, <b>false</b>.</returns>
Public Shared Function VerifyDigitalSignature( _
    signatureInfo As Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfSignatureInformation, _
    signature As Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignature) As Boolean

    System.Console.WriteLine("Verifying signature...")

    Dim signatureVerifyResult As Boolean = False
    Dim embeddedTimestampVerifyResult As Boolean = False
    Dim certificateVerifyResult As Boolean = False
    Dim embeddedTimestampCertificateVerifyResult As Boolean = False
    Dim signatureCoversWholeDocument As Boolean = False
    Dim certificateChain As System.Security.Cryptography.X509Certificates.X509Chain = Nothing
    Dim timestampCertificateChain As System.Security.Cryptography.X509Certificates.X509Chain = Nothing


    ' verify signature

    Try
        ' check that signature covers the whole document
        signatureCoversWholeDocument = signatureInfo.SignatureCoversWholeDocument()

        ' verify PKCS signature
        signatureVerifyResult = signature.VerifySignature()

        ' if signature has embedded timestamp
        If signature.HasEmbeddedTimeStamp Then
            ' verify embedded timestamp
            embeddedTimestampVerifyResult = signature.VerifyTimestamp()
        End If

        ' build and verify certificate chain
        certificateChain = New System.Security.Cryptography.X509Certificates.X509Chain()
        certificateVerifyResult = certificateChain.Build(signature.SigningCertificate)

        ' if signature has embedded timestamp
        If signature.HasEmbeddedTimeStamp Then
            ' build and verify timestamp certificate chain
            timestampCertificateChain = New System.Security.Cryptography.X509Certificates.X509Chain()
            embeddedTimestampCertificateVerifyResult = certificateChain.Build(signature.TimestampCertificate)

        End If
    Catch verificationException As System.Exception
        System.Console.WriteLine("Verification failed: {0}", verificationException.Message)
        Return False
    End Try

    Dim pageContentModified As Boolean = False
    Dim subsequentChangesMessage As String = ""
    ' if PKCS signature verification is passed AND signature does not cover the whole document
    If signatureVerifyResult AndAlso Not signatureCoversWholeDocument Then
        Try
            ' if signature has revision info
            If signatureInfo.SignedRevision IsNot Nothing Then
                ' check subsequent changes
                Using documentChanges As Vintasoft.Imaging.Pdf.PdfDocumentRevisionComparer = signatureInfo.GetDocumentChanges()
                    ' check subsequent changes in pages content
                    pageContentModified = documentChanges.HasModifiedPages

                    ' build subsequent changes message
                    If documentChanges.ChangedPageContents.Count > 0 Then
                        subsequentChangesMessage += String.Format("{0} page(s) modified; ", _
                            documentChanges.ChangedPageContents.Count)
                    End If
                    If documentChanges.AddedPages.Count > 0 Then
                        subsequentChangesMessage += String.Format("{0} page(s) added; ", documentChanges.AddedPages.Count)
                    End If
                    If documentChanges.RemovedPages.Count > 0 Then
                        subsequentChangesMessage += String.Format("{0} page(s) removed; ", documentChanges.RemovedPages.Count)
                    End If
                    If documentChanges.RemovedAnnotations.Count > 0 Then
                        subsequentChangesMessage += String.Format("annotations(s) on {0} page(s) removed; ", _
                            documentChanges.RemovedAnnotations.Count)
                    End If
                    If documentChanges.RemovedAnnotations.Count > 0 Then
                        subsequentChangesMessage += String.Format("removed annotation(s) on {0} page(s); ", _
                            documentChanges.RemovedAnnotations.Count)
                    End If
                    If documentChanges.AddedAnnotations.Count > 0 Then
                        subsequentChangesMessage += String.Format("added annotation(s) on {0} page(s); ", _
                            documentChanges.AddedAnnotations.Count)
                    End If
                    If documentChanges.ChangedAnnotations.Count > 0 Then
                        subsequentChangesMessage += String.Format("changed annotation(s) on {0} page(s); ", _
                            documentChanges.ChangedAnnotations.Count)
                    End If
                    If documentChanges.MiscellaneousChanges.Count > 0 Then
                        subsequentChangesMessage += String.Format("miscellaneous changes: {0}; ", _
                            documentChanges.MiscellaneousChanges.Count)
                    End If
                End Using
            End If
        Catch verificationException As System.Exception
            System.Console.WriteLine("Verification failed: {0}", verificationException.Message)
            Return False
        End Try
    End If

    ' print signature verification result

    ' if PKCS signature verification is failed OR
    ' signature does not cover the whole document AND page(s) content is modified
    If Not signatureVerifyResult OrElse (Not signatureCoversWholeDocument AndAlso pageContentModified) Then
        System.Console.WriteLine("Signature is INVALID.")
    ' if certificate verification is failed
    ElseIf Not certificateVerifyResult OrElse (signature.HasEmbeddedTimeStamp AndAlso _
           (Not embeddedTimestampCertificateVerifyResult OrElse Not embeddedTimestampVerifyResult)) Then
        System.Console.WriteLine("Signature validity is UNKNOWN.")
    Else
        System.Console.WriteLine("Signature is VALID.")
    End If


    ' print signature verification details

    ' if signature verification is successful
    If signatureVerifyResult Then
        ' if signature covers the whole document
        If signatureCoversWholeDocument Then
            System.Console.WriteLine("    Signature verification: Document has not been modified since this signature was applied.")
        Else
            ' if signature does NOT cover the whole document
            If pageContentModified Then
                System.Console.WriteLine("    Signature verification: Document has been modified or corrupted since it was signed.")
                System.Console.WriteLine(String.Format("    Subsequent changes: {0}.", subsequentChangesMessage))
            ElseIf subsequentChangesMessage <> "" Then
                System.Console.WriteLine("    Signature verification: The revision of the document that was covered by this signature has not been altered; however, there have been subsequent changes to the document.")
                System.Console.WriteLine(String.Format("    Subsequent changes: {0}.", subsequentChangesMessage))
            Else
                System.Console.WriteLine("    Signature verification: Document has not been modified since this signature was applied.")
            End If
        End If
    Else
        ' if signature verification is NOT successful
        System.Console.WriteLine("    Signature verification: Document has been modified or corrupted since it was signed.")
    End If

    ' if signature has embedded timestamp
    If signature.HasEmbeddedTimeStamp Then
        If embeddedTimestampVerifyResult Then
            System.Console.WriteLine("    Timestamp verification: Timestamp is valid.")
        Else
            System.Console.WriteLine("    Timestamp verification: Timestamp is valid.")
        End If
    End If


    ' print certificate verification details

    ' if certificate chain is present
    If certificateChain IsNot Nothing Then
        ' if certificate verification is successful
        If certificateVerifyResult Then
            System.Console.WriteLine("    Certificate verification: Signer's certificate is valid.")
        Else
            ' if certificate verification is NOT successful
            ' print certificate verification status
            System.Console.WriteLine("    Certificate verification: Signer's certificate is invalid:")
            For Each status As System.Security.Cryptography.X509Certificates.X509ChainStatus In certificateChain.ChainStatus
                System.Console.Write(String.Format("        {0}: {1}", status.Status, status.StatusInformation))
            Next
        End If
    End If

    ' if timestamp certificate chain is present
    If timestampCertificateChain IsNot Nothing Then
        ' if timestamp certificate verification is successful
        If embeddedTimestampCertificateVerifyResult Then
            System.Console.WriteLine("    Timestamp certificate verification: Signer's certificate is valid.")
        Else
            ' if timestamp certificate verification is NOT successful
            ' print certificate verification status
            System.Console.WriteLine("    Timestamp certificate verification: Signer's certificate is invalid:")
            For Each status As System.Security.Cryptography.X509Certificates.X509ChainStatus In timestampCertificateChain.ChainStatus
                System.Console.Write(String.Format("        {0}: {1}", status.Status, status.StatusInformation))
            Next
        End If
    End If

    ' if signature is not verified
    If Not signatureVerifyResult Then
        Return False
    End If

    ' if signature does NOT cover the whole document and page content was modified
    If Not signatureCoversWholeDocument AndAlso pageContentModified Then
        Return False
    End If

    ' if signature certificate is NOT verified
    If Not certificateVerifyResult Then
        Return False
    End If

    If signature.HasEmbeddedTimeStamp Then
        ' if timestamp is NOT verified
        If Not embeddedTimestampVerifyResult Then
            Return False
        End If

        ' if timestamp certifiacet is NOT verified
        If Not embeddedTimestampCertificateVerifyResult Then
            Return False
        End If
    End If

    ' sigature is VALID
    Return True
End Function


IMPORTANT! The certificate verification will be performed successfully only if certificate has root certificare that is stored in the list of trusted root certificates of current Windows user. You can read more on how to manage trusted root certificates here: https://technet.microsoft.com/en-us/library/cc754841.aspx.


Please read how to add digital signature to a PDF document here.
Please read how to remove digital signature from PDF document here.