PDF Signature - LTV - CRL alternative? - validation

I'm working on a .NET PDF signature application that allows signing with a SmartCard (Belgian ID). In addition, I'd like the signature to support LTV.
I've followed the instructions and examples from iText, and it seems to work well. Acrobat Reader DC indicates that the signature is valid, and offers LTV.
There is an practical issue however: the included CRL is too big. 14MB on my test ID. This means that, for every signature, 14MB needs to be downloaded which slows down operation and significantly increases the file size of each signed PDF.
I was wondering if there is an alternative to including the complete CRL while still supporting LTV? It seems a bit overkill to include the complete CRL while the only "thing" that seems needed is the inclusion of a verifyable proof that the certificates in the chain have not been revoked at time of signing. I thought that use of the OCSP might offer such functionality, however simply removing the CRL and including a OcspClientBouncyCastle instance didn't do the trick. Is the OCSP that is given to SignDetached used to check whether the certificate is revoked at time of signing instead?
A related question concerns the LTV "support" itself. As I mentioned, Acrobat Reader only indicates that the file supports LTV when the CRL is included. Checking at the online service http://dss.nowina.lu/validation (EU reference) seems to indicate something else however. There, even the file without the embedded CRL has a valid check behind the description "Is AdES-T validation conclusive?" (which is the only checkpoint under "Long Term Validation Data"). As such, I was wondering if it is even needed to include the CRL for LTV?
Suffice to say I'm confused :).
Btw, 2 more warnings from that same verification service that I can't seem to solve: "The 'issuer-serial' attribute is absent or does not match!" and "The signer's certificate is not supported by SSCD!". But maybe thats for another question.
Thanks in advance for any help.

I had a look at your sample document. It does not conform to any LTV profile, merely to T-Level, i.e. it is timestamped.
In detail
The PDF signature is implemented merely by embedding a single CMS container using subfilter ETSI.CAdES.detached which contains
the certificate chain of the signer certificate in the CMS container certificate set
C=BE,CN=Belgium Root CA2
C=BE,CN=Citizen CA,SERIALNUMBER=201103
C=BE,CN=Donny Tytgat (Signature),SURNAME=Tytgat,GIVENNAME=Donny Geert,SERIALNUMBER=81032305309);
a signed Adobe RevocationInfoArchival attribute containing a single good OCSP response for the signer certificate; the response is signed by
CN=Belgium OCSP Responder,C=BE
which has the id-pkix-ocsp-nocheck extension;
a signature time stamp signed by
C=BE,SERIALNUMBER=2014,O=Belgium Federal Government,CN=Time Stamping Authority
Thus, the signature conforms to Baseline T-Level as
A PAdES signature conformant to T-Level shall be a signature conformant to B-Level for which a Trust Service
Provider [i.4] has generated a trusted token (time-mark or time-stamp token) proving that the signature itself actually
existed at a certain date and time.
(section 7 - Requirements for T-Level Conformance - ETSI TS 103 172 V2.2.2)
where B-Level conformance is defined as
This clause defines requirements that PAdES signatures claiming conformance to the B-Level have to fulfil.
The current clause specifies compliance requirements for short-term electronic signatures.
This clause actually profiles
PAdES-BES (signatures that do not incorporate signature-policy-identifier) and PAdES-EPES (signatures
that do incorporate signature-policy-identifier) signatures.
(section 6 - Requirements for B-Level Conformance - ibidem)
(Additional requirements also are fulfilled.)
It does not conform to LT-Level which requires:
The generator shall include the full set of revocation data (CRL or OCSP responses) that have been used in the
validation of the signer, and CA certificates used in signature. This set includes all certificate status
information required for validating the signing certificate, for validating any attribute certificate present in the
signature, and for validating any time-stamp token's signing certificate (i.e. a TSA certificate) already
incorporated to the signature.
(section 8 - Requirements for LT-Level Conformance - ibidem)
as there is no revocation information concerning the CA certificate or the TSA certificate.
Thus, it can also not conform to LTA-Level as
A PAdES signature conformant to LTA-Level shall be a signature conformant to LT-Level to which one or more
document-time-stamp has been incorporated
Concerning other questions
I was wondering if there is an alternative to including the complete CRL while still supporting LTV? It seems a bit overkill to include the complete CRL while the only "thing" that seems needed is the inclusion of a verifyable proof that the certificates in the chain have not been revoked at time of signing. I thought that use of the OCSP might offer such functionality
Given an appropriate PKI infrastructure that is possible. Unfortunately, though, neither the CA not the TSA certificate contain information on a OCSP responder responsible for them. Thus, either the Belgium citizen PKI does not provide OCSP services for those certificates or it merely does not make that provision public.
BTW, this is what the Diagnostic Tree remarks
<Message Id="0">OSCP Uri not found in certificate meta-data !</Message>
are about which you get when verifying your signature using the http://dss.nowina.lu/validation service.
There, even the file without the embedded CRL has a valid check behind the description "Is AdES-T validation conclusive?" (which is the only checkpoint under "Long Term Validation Data").
This user interface layout has misled you, as mentioned above there are more requirements for LTV-related profiles.

Related

How to validate a PE file's digital signature in windows and find who signed it? (using c/c++)

Lets say you have a windows executable (driver or usermode app), and you want to :
Verify if the digital signature is OK and file is not corrupted (same as when you go to the digital signature tab and it says the certificate is OK)
Find which company signed the file. Therefore I am not talking about the root of the certificate chain (Which is the CA most of the times), I am talking about the bottom certificate in the chain, which is the company that signed the file, i want to get the name of that company.
I found two APIs, WinVerifyTrust And CertGetCertificateChain, But I'm not sure how to use them for this task, or if they can help me with this or not.
Lets say you already have the handle to the file that you want to check, and have read it in a buffer as well, how do you use these to check the certificate afterwards? The documentations are very vague.
Verify if the digital signature is OK and file is not corrupted
For more details about how to Verifying the Signature of a PE File, I suggest you could refer to the example: https://learn.microsoft.com/en-us/windows/win32/seccrypto/example-c-program--verifying-the-signature-of-a-pe-file
Find which company signed the file.
I suggest you could try to use CryptQueryObject function (wincrypt.h).
For more details I suggest you could refer to the Doc:https://learn.microsoft.com/en-us/troubleshoot/windows/win32/get-information-authenticode-signed-executables
And you could refer to the Thread:Read and validate certificate from executable

Signing ClickOnce application with code signing certificate, but publisher still unknown

I have 2 code signing certificates, for both CSR is created same way, also import and export is done same way. The only difference that I see is that one of certificates Common name contains Quotes, and the other doesn't.
e.g.
some cert and
some "cert"
CSR creation
Request format PKCS #10
disabled "Strong private key encryption"
Entered Common name, Organization, Locality, State, Country
2048 bytes for private key
set private key exportable
Import
place all certificates in Personal store
Export
Include all certificates if possible
Enable certificate privacy
encryption algorithm TripleDES-SHA1
Misleading thing is that this Common name value is NOT taken from the value I entered when I created CSR request
I am using those certificates to sign Winforms applications in Visual Studio. Certificate without Quotes in common name is working correctly (i.e. when I install application user is not getting security warning about unknown publisher), but when I install application which is signed with the other Code signing certificate (with Quotes in Common name) - it does not recognize Publisher. No error when published my application. When I take a look at setup.exe properties in Windows Explorer I see a Digital signatures tab which contains row for my certificate.
I tried to sign files with signtool and then verify - it said that certificate is valid.
I tried to get help from godaddy.com where I bought my certificate, they said that it should work with quotes, too, but didn't offer help to solve the issue. Rekey also didn't help.
I see that there are some suggestions to use Pre Publish, Post Build tasks, but I am not using those for my first certificate which is working.
So, is anyone here using code signing certificate for Winforms application with common name having quotes in it? Or maybe anyone knows about this problem and how to solve it?
Had to revoke (common name which is entered when creating CSR is not taken into account, so rekeying is not enough!) my code signing certificate and create from start without quotes/brackets in company name.
So this means, you will have to wait again for few days, because verification process is made from start again. When you will be contacted by issuer, they will verify / ask you about company name - make sure that they do not include quotes/brackets.
Revoking means that you will basically have to buy your certificate once more, because after you revoke it (at least in godaddy case) in your account you don't have options to create it again. So, you have to contact support (use call center and not chat ;)

Duplicating Digital Signatures?

From what I understand about digital signatures, when code-signing exe's it the "signer" modifies the PE itself. I noticed that it adds the certificate content to the end of the PE and also (obviously) adds some kind of reference to the headers.
My question is: How secure is this ? Wouldn't someone capable of reverse engineering the executable be able to forge that onto his own executable thereby forging a digital signature ?
Code signing is a public-private key operation. The signing operation calculates a hash of the .exe file (minus the bits where the signature is stored), then encrypts the hash with the signer's private key.
On client-side validation, the client will redo the hash calculation, and decrypt the stored signature using the public key. If the two hashes match, then the exe has not been tampered with.
The only bits of the file are are encrypted are the signature - everythign else is stored in the clear. Nothing stops you from ripping apart the exe and stuff it (or parts of it) into another .exe.
Signing is not there to prevent theft - it's there to detect tampering.

How do certificate avoid the man in the middle attack?

I have another question to security in the web.
If I understand it correctly certificates are for identify who you really are. So the man in the middle attack isn't possible.
But when I see this image:
http://upload.wikimedia.org/wikipedia/commons/thumb/2/2b/Digital_Signature_diagram.svg/800px-Digital_Signature_diagram.svg.png
I think a man in the middle attack is possible. You could split the Signature, the certificate from the data. Make your own signature with your fake data and send the fake data with the fake signature (but the right certificate) to the server/client.
What I also not understand in this picture is where the certificate gets checked, on the verification side.
thanks.
SCBoy
Make your own signature with your fake data and send the fake data with the fake signature (but the right certificate) to the server/client.
The problem is that the receiver will then look at the fake signature and see that it does not match the certificate of the real sender.
You can only create signatures that match a given certificate when you have the correct private key for that certificate (even though the certificate itself is public, that is the magic of asymmetric cryptography). This private key is being kept secret by the owner of the certificate (the original sender of the message).
The man-in-the-middle is prevented by distributing trusted certificates in advance.
You have to trust the authenticity of the certificates, either by trusting them directly (root certificates) or by trusting a chain of signatures on the certificate leading up to one that you trust.
If the man in the middle can make you believe that his fake certificate is the real deal, then the whole system fails.

Validate signature on EXE with CertGetCertificateChain

I would like to verify a signed executable. The requirement is to validate that the executable itself is valid and where it came from (probably from the subject of the cert). The cert type is PKCS.
I found a similar posting here,
Validate Authenticode signature on EXE - C++ without CAPICOM
The Microsoft documentation, among others, appears to point to CertGetCertificateChain, but the examples tend to work with certificates that are in a store. Does anyone know how to validate a signed executable using CertGetCertificateChain and related API's?
I asked this question some time ago. I had your exact requirements. There's sample code in there that will help you. Have fun!!
Can you elaborate? the question you linked to seems to provide all of the answers you should need.
You state that "the examples tend to work with certificates that are in a store", which I take to mean that the executable needs to be signed with a certificate that chains to a root certificate in the machine's trusted store.
This is true; there's no way around that, otherwise there is no way way to trust that the signer is who he says he is, and no way for the provider to revoke the certificate if it's being fraudulently used.
So, WinVerifyTrust is the right way to validate a signed executable. It's a terrible API so be careful. CryptQueryObject and related apis will give you more information such as the name of the person or company that the certificate was issued to.

Resources