Embedded certificates in digitally signed PDFs

Dear tech people, good day!

I'm having an issue when signing PDF files with PdfCertificate and PdfSignature as follows:

1) When creating a PdfCertificate for signing with this constructor: PdfCertificate(Stream certificate, String password), the resulting PDF contains the complete certificate chain that is in the PFX used to build the Stream parameter (a sample PDF is attached, and a snapshot of what Adobe shows).

2) When creating a PdfCertificate for signing with this constructor: PdfCertificate(X509Certificate2 x509Certificate2), the resulting PDF contains only the signing certificate, and not the complete chain (a sample PDF is attached, and a snapshot of what Adobe shows).

The X509Certificate2 object passed to the constructor in example 2) was built like this:
var cert = new X509Certificate2(pathToPfxFile, passwordOfPfxFile)

The same PFX file was used in both cases, only that the first example passes a filestream of that file, and the second case passes an X509Certificate2 object built on it.

It's important to keep the complete certificate chain inside the PDF files. This is because when parsing the files, I extract the certificates to build a certificate chain and pass it to PdfLoadedSignatureField.ValidateSignature(rootCertificates X509Certificate2Collection).

I would gladly use only the first PdfCertificate example in our software, but since signing with smartcards is also a must, and that can be achieved only by passing an X509Certificate2 to PdfCertificate, I guess there must be something we can do in order to have the full chain embedded in the resulting PDF using the second method.

As a side note, this misbehavior happens with PFX files that were NOT imported previously in the Windows Certificates Store, otherwise the resulting PDF contains the full chain, I think because the signing process looks for the root cert there.

We cannot depend on the Windows Certificates Store to sign files because it's a server software, running under an IIS Application Pool account with low privileges.

I'm using ASP.NET MVC components, version 18.1.0.59.

Any suggestions are very welcome.
Thank you!
Alex






Attachment: Signed_PDF_samples_732b0e5a.zip

4 Replies 1 reply marked as answer

CM Chinnu Muniyappan Syncfusion Team June 26, 2020 11:51 AM UTC

Hi Alex, 
 
Thank you for contacting Syncfusion support. 
 
We are excluding the root certificate when signing a PDF document using the X509Certificate2 API, because of the root certificate fetched from the windows store in the viewer automatically (like Adobe Reader). This is our current behavior for signing store certificates. We can include the store certificate chain by using the following code. 
 
First Approach: 
 
Load the X509Certificate2 as exportable and sign with different digest algorithm like. 
 
 
//Load existing PDF document 
PdfLoadedDocument document = new PdfLoadedDocument("PDF_Succinctly.pdf"); 
 
//Get the existing page. 
PdfLoadedPage page = document.Pages[0] as PdfLoadedPage; 
 
//Load the certificate with exportable. 
X509Certificate2 x509 = new X509Certificate2("certchain.pfx", "password@123", X509KeyStorageFlags.Exportable); 
             
//Create PdfCertificate instance. 
PdfCertificate certificate = new PdfCertificate(x509); 
 
//Create the signature. 
PdfSignature signature = new PdfSignature(document, page, certificate, "Signature1"); 
 
//Set the digest algorithm. 
signature.Settings.DigestAlgorithm = DigestAlgorithm.SHA256; 
 
//Save the PDF document 
document.Save("Output.pdf"); 
 
//Close the document. 
document.Close(true); 
 
 
Second Approach: 
 
Or else we can sign the store certificate using SignedCms externally like below. 
 
 
//Load existing PDF document 
PdfLoadedDocument document = new PdfLoadedDocument("PDF_Succinctly.pdf"); 
 
//Get the existing page. 
PdfLoadedPage page = document.Pages[0] as PdfLoadedPage; 
 
//Create the signature with empty certificate. 
PdfSignature signature = new PdfSignature(document, page, null, "Signature1"); 
signature.Bounds = new RectangleF(0, 0, 100, 50); 
 
//Initialize the ComputeHash event. 
signature.ComputeHash += Signature_ComputeHash; 
 
//Save the PDF document 
document.Save("ExternalSignature.pdf"); 
 
//Close the document. 
document.Close(true); 
 
 
And the ComputeHash event add the below code. 
 
private void Signature_ComputeHash(object sender, PdfSignatureEventArgs ars) 
{ 
    //Get the document bytes. 
    byte[] documentBytes = ars.Data; 
 
    SignedCms signedCms = new SignedCms(new ContentInfo(documentBytes), detached: true); 
 
    //Compute the signature using the specified digital ID file and the password. 
    X509Certificate2 certificate = new X509Certificate2("certchain.pfx", "password@123"); 
    var cmsSigner = new CmsSigner(certificate); 
 
    cmsSigner.IncludeOption = X509IncludeOption.WholeChain; 
 
    //Set the digest algorithm SHA256 
    cmsSigner.DigestAlgorithm = new Oid("2.16.840.1.101.3.4.2.1"); 
 
    signedCms.ComputeSignature(cmsSigner);       
 
    //Embed the encoded digital signature to the PDF document. 
    ars.SignedData = signedCms.Encode(); 
} 
 
For more details, refer the following KB article. 

Please try the above in your side and let us know if you have any further assistance. 
 
Regards, 
Chinnu M 


Marked as answer

AL Alejandro June 26, 2020 06:47 PM UTC

Hello Chinnu, 

Thanks for your response. I understand the behavior you mention about excluding the root certificate when using X509Certificate2.

But what I don't understand is this:

How can other people validate PDFs signed this way, which don't include the root certificate?

In my case, I'm using external tools to parse the files (like BouncyCastle), which help me build X509Certificate2 objects from the signature certificates in the files.
Then I use .net's X509Chain to build a certificate chain with all that info, and -finally- I use them to pass it to PdfLoadedSignatureField.ValidateSignature

X509Chain complains if the chain cannot be built, and that's the case when the root certificate is missing.

I don't see how can I validate a PDF which does not containt the whole certificate chain embedded.

Am I missing something regarding validation?

Thank you
Alex



SL Sowmiya Loganathan Syncfusion Team June 29, 2020 12:39 PM UTC

Hi Alejandro,  

We have validated the reported issue and logged a bug report for this. We will update the patch for the reported issue on July 13, 2020.  

Regards, 
Sowmiya Loganathan 




SL Sowmiya Loganathan Syncfusion Team July 13, 2020 11:38 AM UTC

Hi Alejandro,

The reported issue has been fixed and the patch for this fix can be downloaded from the following location.

 
The status of this feedback can be tracked through the following feedback link,   

Recommended approach - exe will perform automatic configuration
Please find the patch setup from below location:

http://syncfusion.com/Installs/support/patch/18.2.0.44/1177194/F155522/SyncfusionPatch_18.2.0.44_1177194_7132020061305583_F155522.exe  

Advanced approach – use only if you have specific needs and can directly replace existing assemblies for your build environment
Please find the patch assemblies alone from below location:

http://syncfusion.com/Installs/support/patch/18.2.0.44/1177194/F155522/SyncfusionPatch_18.2.0.44_1177194_7132020061305583_F155522.zip  
 

Assembly Version:  18.2.0.44
Installation Directions :
This patch should replace the files “Syncfusion.Pdf.Base.dll” under the following folder.
$system drive:\ Files\Syncfusion\Essential Studio\18.2.0.44\precompiledassemblies\18.2.0.44\4.5.1
Eg : $system drive:\Program Files\Syncfusion\Essential Studio\9.3.0.61\precompiledassemblies\9.3.0.61\4.0

To automatically run the Assembly Manager, please check the Run assembly manager checkbox option while installing the patch. If this option is unchecked, the patch will replace the assemblies in precompiled assemblies’ folder only. Then, you will have to manually copy and paste them to the preferred location or you will have to run the Syncfusion Assembly Manager application (available from the Syncfusion Dashboard, installed as a shortcut in the Application menu) to re-install assemblies.

Note :
To change how you receive bug fixes, ask your license management portal admin to change your project’s patch delivery mode.
https://www.syncfusion.com/account/license

Disclaimer :
Please note that we have created this patch for version 18.2.0.44 specifically to resolve the following issue(s) reported in this/the incident(s). 155522

If you have received other patches for the same version for other products, please apply all patches in the order received.
This fix will be included in our Volume 2 SP1 release which will be available in end of August, 2020.
 

Regards,
 
Sowmiya Loganathan 
 


Loader.
Up arrow icon