1

So I've been working on signing of PDF documents lately, and today I came across a new and wonderful problem. So when I sign the document(The document is signed on a server actually) and open that document up in my machine, the signature shows valid and that it is LTV enabled, so pretty much works as expected. But when I open the same document on my boss's computer it shows that the identity of the signing could not be verified even after the certificate was trusted, but if I open the certificate properties it says that the certificate is valid and revocation was performed successfully. What could be the cause of this?

On my boss's computer, it shows that signer identity could not be verified, but the revocation tab when I view the certificate properties states that the signature certificate is valid

Figure 1: The certificate itself is trusted.

On my boss's computer, it shows that signer identity could not be verified, but the revocation tab when I view the certificate properties states that the signature certificate is valid

Figure 2: Intermediary certificate is trusted.

On my boss's computer, it shows that signer identity could not be verified, but the revocation tab when I view the certificate properties states that the signature certificate is valid

Figure 3: Root certificate trusted

Signed Document: https://drive.google.com/file/d/0B9RyqgJoa6W8WlBLemVETXJRU0U/view?usp=sharing

Another weird thing, for the timestamping signature, when I add the Root certificate as a trusted root certificate to adobe, it says that LTV is not enabled, but if I add the GlobalTrustFinder certificate itself as a trusted certificate it says that LTV is enabled. Any reason that it would do that?

Any help would really be appreciated

Code for adding LTV to the existing signature blocks as well as add the timestamping signature:

private void SignDocumentSigningBlockAddLTVVerification(PdfStamper stamper, Certificate certificate)
    {
        LtvVerification ltvVerification = stamper.LtvVerification;
        List<string> signatureFieldNames = stamper.AcroFields.GetSignatureNames();
        ITSAClient tsaClient = new TSAClientBouncyCastle(_settingManager["DocumentSigningTimestampingServiceAddress"], String.Empty, String.Empty, Int32.Parse(_settingManager["DocumentSigningEstimatedTimestampSize"]), _settingManager["DocumentSigningEncryptionHashAlgorithm"]);
        IOcspClient ocspClient = new OcspClientBouncyCastle();
        ICrlClient crlClient = new CrlClientOnline(SignDocumentSigningBlockBuildChain(new X509Certificate2(certificate.Bytes, certificate.Password, X509KeyStorageFlags.Exportable)).ToList());

        PdfPKCS7 pkcs7 = stamper.AcroFields.VerifySignature(signatureFieldNames.Last());
        if (pkcs7.IsTsp)
        {
            ltvVerification.AddVerification(signatureFieldNames.Last(), ocspClient, crlClient, LtvVerification.CertificateOption.SIGNING_CERTIFICATE, LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.NO);
        }
        else
        {
            foreach (string name in stamper.AcroFields.GetSignatureNames())
            {
                ltvVerification.AddVerification(name, ocspClient, crlClient, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.NO);
            }
        }
        ltvVerification.Merge();

        PdfSignatureAppearance appearance = stamper.SignatureAppearance;
        LtvTimestamp.Timestamp(appearance, tsaClient, null);
    }

Kind regards

Johandre
  • 95
  • 2
  • 13

1 Answers1

2

Revocation could not be checked

But when I open the same document on my boss's computer it shows that the identity of the signing could not be verified even after the certificate was trusted, but if I open the certificate properties it says that the certificate is valid and revocation was performed successfully. What could be the cause of this?

As I cannot check the computer of your boss, this is bound to be guesswork. So...

Giving it a shot

You say the certificate was trusted but there are many certificates involved. Thus, which one have you trusted? According to your screenshot

On my boss's computer, it shows that signer identity could not be verified, but the revocation tab when I view the certificate properties states that the signature certificate is valid

you have not trusted the user certificate (if you had, that certificate would not have been checked against a CRL but instead it would have been trusted without further tests).

Probably you have trusted the Root CA certificate on the computer of your boss. If you have, not only the end user certificate has to be checked for revocation but also the intermediary CA certificate (SAPO Class 4 CA)! Probably that is where your problem arises

Thus, when you are on the revocation tab, please select the intermediary certificate and see whether revocation checks for it could be performed. If not, that's the problem you ran into.

PS: It's not so

The OP tested the idea mentioned above but

So I went back and checked all the certificates, and it seems that the CRL check is performed as expected.

Thus, it is not as easy as I thought above

the difference in setup was that i trusted the certificate that I signed with as the root certificate hence was showing up as successfully signed on my machine, I've now set up my security settings so that I have the same results as on my boss's computer.

Ok, so the difference between the results on those two computers is explained.

To determine whether the problem is in determining the revocation status of the CA certificate or your user certificate, could you please re-configure your settings yet again and trust the CA certificate?

If after this change the problem remains, the issue most likely is linked to your user certificate and checking its revocation status. If it vanishes, the issue most likely is linked with checking the revocation status of the CA certificate.

I trusted the CA now, it still has the same problem, but if I trust the user cert marking the "Use this certificate as a trusted root" and Certified Documents" checkbox, the signature is shown as valid as well as LTV enabled, but only if I mark it as the root. In all other cases the signature has the warning stating that the revocation checks were not performed.

If you immediately trust your user certificate, the signature is verified positively without further ado. After all, you do trust that certificate...

Putting that aside, there already is a problem when checking the user certificate. I'll try and investigate some more.

PPS: So that is why...

If all else fails, start inspecting the signature or so I thought after I could not find anything really bad in the certificate. I opened the signature in an ASN.1 Dump utility and...

...
    <30 42>
2174   66:             SEQUENCE {
    <06 09>
2176    9:               OBJECT IDENTIFIER '1 2 840 113583 1 1 8'
    <31 35>
2187   53:               SET {
    <30 33>
2189   51:                 SEQUENCE {
    <A0 31>
2191   49:                   [0] {
    <30 2F>
2193   47:                     SEQUENCE {
    <2D 2D>
2195   45:                       Unknown (Reserved) {
    <2D 2D>
2197   45:                         Unknown (Reserved) {
    <2D 42>
2199   66:                           Unknown (Reserved) {
    <45 47>
2201   71:                             [APPLICATION 5]
         :                   'IN X509 CRL-----.MIIfZzCCHU8CAQEwDQYJKo0...*.H..'
         :                   '............0...Ix<..N+'
         :                   Error: IA5String contains illegal character(s).
Error: Inconsistent object length, 7 bytes difference.
         :                             }
Error: Inconsistent object length, 30 bytes difference.
         :                           }
Error: Inconsistent object length, 32 bytes difference.
         :                         }
Error: Inconsistent object length, 32 bytes difference.
         :                       }
Error: Inconsistent object length, 32 bytes difference.
         :                     }
Error: Inconsistent object length, 32 bytes difference.
         :                   }
Error: Inconsistent object length, 32 bytes difference.
         :                 }
Error: Inconsistent object length, 32 bytes difference.
         :               }
Error: Inconsistent object length, 32 bytes difference.
         :             }
...

So there are syntactical errors in the signature itself, more exactly inside the PDF signature certificate revocation information attribute (OID 1 2 840 113583 1 1 8).

(Looking at that region with a different viewer, one sees that there is a text(!) "-----BEGIN X509 CRL-----" - There seems to be a textual CRL representation which is invalid here.)

Adobe Reader, therefore, when trying to check for certificate revocation during signature verification, inspects the signature attribute which can be used to add revocation information already during signing, finds a broken attribute value and seems to stop the verification check with a failure...

The code used for filling the certificate details window seem to be separately coded.

Why that?

One might wonder how a textual CRL representation happens to be included in the PDF signature certificate revocation information attribute of your signature.

I looked into that embedded "CRL". It is in PEM format and cut off after 47 bytes. So I accessed the CRL at the URL given in the certificate (https://pki.trustcentre.co.za/crl/sapo_c4ca.crl) and I indeed retrieved a (complete) CRL in PEM format which is textual. The signature creation code seems to have tried to include it as is but it got cur off.

Is the PKI wrong in supplying that CRL in PEM format instead of in DER format? Or is the signature creation code wrong in assuming to find a DER encoded CRL at the position pointed to?

The current specification for the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile (RFC 5280) specifies:

When the HTTP or FTP URI scheme is used, the URI MUST point to a single DER encoded CRL as specified in [RFC2585].

(Section 4.2.1.13. CRL Distribution Points)

But it does not say anything equivalent about the HTTPS URI scheme!

Because the PKI employs the HTTPS scheme, therefore, the PKI might be considered to be conform to the letter of the RFC.

Even though the HTTPS scheme essentially merely is the secured variant of the HTTP scheme and so the PKI definitively and unnecessarily violates the spirit of the RFC, it seemingly does not violate the letter of it.

Thus, CRL retrieving classes (like iText's CrlClientOnline) had better check the format of the retrieved CRL and transform it if necessary.

LTV-enabled or not LTV-enabled

An explanation

Another weird thing, for the timestamping signature, when I add the Root certificate as a trusted root certificate to adobe, it says that LTV is not enabled, but if I add the GlobalTrustFinder certificate itself as a trusted certificate it says that LTV is enabled. Any reason that it would do that?

This is pretty obvious:

If you trust the root certificate, revocation has to be checked for the intermediary CA and the end entity certificates. As there are no CRLs or OCSP responses for them embedded in your document, your time stamp is not LTV-enabled.

If on the other hand you explicitly trust the end entity certificate, the very certificate that created the timestamp, the Adobe validator immediately trusts the time stamp. No need to check for revocation of a certificate explicitly trusted... Thus, in this case the time stamp is LTV enabled.

(The term "LTV enabled" is an Adobe term with a very variable value. For backgrounds on this term and other LTV related terminology, cf. the section Background in this answer and the other answers referenced from there,)

Follow-up questions

For the timestamping I'm a bit confused, I followed the code examples in the post you recomended, and the code I've used was a variation of that but in principle the same, why would the CRL and the OCSP responses not be embedded?

The big difference is that the code in my referenced answer does not apply a document time stamp, it merely adds validation related information (certificates, CRLs, OCSP responses).

Adobe's proprietary term "LTV-enabled" refers to a document signature or document time stamp for which "all information required for verification of all relevant signatures (including those signing the CRLs, OCSP responses and time stamps used in the verification process) in the context of the security settings of the validating Adobe Reader are contained in the PDF". Your code, after adding the validation related information, adds a document time stamp, so the information required for validating that time stamp are in general not yet available in the PDF.

ETSI's standardized term "PDF document with LTV" refers to a signed PDF with validation related information (e.g. an "LTV-enabled" PDF) plus a final document time stamp.

The iText sample code you used attempts to create an ETSI "PDF document with LTV" and, therefore, has to be tweaked to instead attempt to create a PDF where all document signature and time stamps are Adobe "LTV-enabled".

As for adding the crls and ocsps, as far as I understood that for adding LTV, you have to add the validation to all signatures in the document and the final document time stamp, as I did in the code I provided, is this not the case?

There are different use cases in the context of LTV, and depending on one's very use case, different information may have to be added.

Community
  • 1
  • 1
mkl
  • 90,588
  • 15
  • 125
  • 265
  • Thank you for the very detailed answer. So I went back and checked all the certificates, and it seems that the CRL check is performed as expected. I did trust all the certificates in the chain. Do I need to trust the user certificate as a root certificate, because then the revocation checks are not performed? For the timestamping I'm a bit confused, I followed the code examples in the post you recomended, and the code I've used was a variation of that but in principle the same, why would the CRL and the OCSP responses not be embedded? Kind regards – Johandre Nov 13 '15 at 05:05
  • I've updated the original question with images from the revocation tab as well as the code used to add the LTV verification to the signature blocks – Johandre Nov 13 '15 at 05:08
  • So checking again, in the signature panel it says that the revocation could not be checked, but if I view the properties it says that it is valid...Am I misunderstanding something here, because it does seem that the revocation checking is at fault here, but I don't fully understand why? – Johandre Nov 13 '15 at 05:23
  • As mentioned in my answer we can only guess. For a more well-founded answer knowing the actual differences (concerning the security settings of Adobe reader and the OS) between your computer and the computer of your boss might be helpful. – mkl Nov 13 '15 at 07:13
  • so at first the difference in setup was that i trusted the certificate that I signed with as the root certificate hence was showing up as successfully signed on my machine, I've now set up my security settings so that I have the same results as on my boss's computer. I have a feeling there might be something wrong with the certificate CRL, because even if i dont use LTV the certificate still comes up that the CRL could not be verified. I am at a bit of a loss with this. Thanks for the input mkl :P – Johandre Nov 13 '15 at 09:37
  • To determine whether the problem is in determining the revocation status of the CA certificate or your user certificate, could you please re-configure your settings yet again and trust the CA certificate? If after this change the problem remains, the issue most likely is linked to your user certificate and checking its revocation status. If it vanishes, the issue most likely is linked with checking the revocation status of the CA certificate. – mkl Nov 13 '15 at 11:03
  • I trusted the CA now, it still has the same problem, but if I trust the user cert marking the "Use this certificate as a trusted root" and Certified Documents" checkbox, the signature is shown as valid as well as LTV enabled, but only if I mark it as the root. In all other cases the signature has the warning stating that the revocation checks were not performed. As for adding the crls and ocsps, as far as I understood that for adding LTV, you have to add the validation to all signatures in the document and the final document time stamp, as I did in the code I provided, is this not the case? – Johandre Nov 13 '15 at 11:41
  • See my most recent edit, the signature (or more exactly, a signature attribute which can be used to put revocation information into the signature itself) is broken. – mkl Nov 13 '15 at 14:04
  • @user2699460 Have you meanwhile signed the PDF using a correct CRL encoding? – mkl Nov 16 '15 at 13:56
  • sorry for the delayed response, unfortunately i do not have control over the CRL or certificate for that matter, its provided by a third party. So if I understand the reply correctly the problem is not with the code, but with the third party CRL? And again thanks for the detailed response. Kind regards – Johandre Nov 17 '15 at 15:18
  • *So if I understand the reply correctly the problem is not with the code, but with the third party CRL?* - The embedded "CRL" at least partially looks textual. Thus, it is not a CRLin the expected binary format. I obviously do not know whether this textual representation is what the third party delivers or a side effect of your code. – mkl Nov 17 '15 at 15:38
  • I just looked into the "CRL" embedded into the signature. It is in PEM format and cut off after 47 bytes. So I accessed the CRL at the URL given in the certificate, *https://pki.trustcentre.co.za/crl/sapo_c4ca.crl* and I indeed retrieved a (complete) CRL in PEM format But according to the *current* specification (RFC 5280) the CRL referenced via http-scheme from the certificate MUST be provided in DER format. I assume, though, that that PKI will not be easily be persuaded to change their infrastructure. Thus, you'll have to fix the format somewhere in your code... – mkl Nov 17 '15 at 17:09
  • that makes sooo much sense. Thank you for looking into that mkl. I will have a chat with the company on friday since we were assured that they are following standards, I am new to the CRL part of things so still getting to grips with it. Again thank you for the detailed response. Kind regards – Johandre Nov 18 '15 at 16:08
  • *they are following standards* - they are, but not the current ones but the former versions. I think rfc 3280 does not explicitly require der format but rfc 5280 does. – mkl Nov 18 '15 at 18:14
  • @user2699460 I looked into it some more; Because they use HTTPS instead of HTTP, they might indeed be conform to the *letter* of the RFC, (but definitively not the spirit!). For more details see my recent edit. – mkl Nov 19 '15 at 10:40
  • Awesome thanks for that!Ill talk to the company and check if they have a DER url available otherwise ill try to do the checks in code. Thanks again for looking into it far futher than expected :) Kind regards – Johandre Nov 20 '15 at 04:25