Certificate chain from PDF digital signature back to trusted root certificate not verified?
Submitted by Sebastian Rasmussen
Assigned to poppler-bugs
Description
I believe that the full certificate chain back to a trusted root certificate is not verified when attempting to verify digital signatures in PDFs.
SignatureHandler::init_nss() initializes NSS to point to my root certficate database in my firefox profile or if not available (it is available) /etc/pki/nssdb (which is unpopoulated on my machine).
I believe that the idea is that this database of root certificates will be used when verifying the chain of certificates in digital signatures.
I downloaded http://blogs.adobe.com/security/SampleSignedPDFDocument.pdf and then ran pdfsig (compiled from git HEAD currently at c301f6c6) like so:
./pdfsig-original ./SampleSignedPDFDocument.pdf Digital Signature Info of:./SampleSignedPDFDocument.pdf Signature #1:
- Signer Certificate Common Name: John B Harris
- Signing Time: Jul 16 2009 16:47:47
- Signature Validation: Signature is Valid.
- Certificate Validation: Certificate has Expired
The mesage "Signature is Valid" implies that the chain of certificates has all been checked. However if I replace the call to NSS_Init() with a call that explicitlydisables any preinitialized database like so:
diff --git a/poppler/SignatureHandler.cc b/poppler/SignatureHandler.cc index 15c9321c..4be4a140 100644 --- a/poppler/SignatureHandler.cc +++ b/poppler/SignatureHandler.cc @@ -91,16 +91,9 @@ GooString *SignatureHandler::getDefaultFirefoxCertDB_Linux() */ void SignatureHandler::init_nss() {
- GooString *certDBPath = getDefaultFirefoxCertDB_Linux();
- if (certDBPath == NULL) {
- NSS_Init("sql:/etc/pki/nssdb");
- } else {
- NSS_Init(certDBPath->getCString());
- }
- NSS_NoDB_Init(""); //Make sure NSS root certificates module is loaded SECMOD_AddNewModule("Root Certs", "libnssckbi.so", 0, 0);
- delete certDBPath; }
And then recompile and rerun pdfsig I get the same message as above:
./pdfsig-changed ./SampleSignedPDFDocument.pdf Digital Signature Info of: ./SampleSignedPDFDocument.pdf Signature #1:
- Signer Certificate Common Name: John B Harris
- Signing Time: Jul 16 2009 16:47:47
- Signature Validation: Signature is Valid.
- Certificate Validation: Certificate has Expired
Which again seems to claim that the chain of certificates is valid. How can that be when there are no trusted root certificates in the database?
This appears to be corroborated by the comment preceeding the function NSS_CMSSignerInfo_Verify() which SignatureHandler later calls to do the verification:
"Just verifies the signature. The assumption is that verification of the certificate is done already", see https://hg.mozilla.org/projects/nss/file/tip/lib/smime/cmssiginfo.c#l310
I believe that the intent with the poppler code is to verify the entire certificate chain (why else bother to add the firefox root certificate database?), but I don't think that is what is happening.
Unfortunately I'm not yet well versed in this code to figure out how to fix this, hence there is no patch attached fixing this issue. Maybe the decision is to be happy that the certificate is self-consistent and that the digest is matching, etc. but to ignore that the chain of certificates is never checked, however in that case I'd suggest mentioning this clearly, e.g. "Signature is Valid (chain back to root certificate not checked)".
Oh, and of course any UI that uses SignatureHandler is equally affected as pdfsig, but I find reporting issued using command-line tools easier. :)