Imagine this scenario:

  1. 1st December 2014 - a certificate is stolen and used to sign malware with 2014-12-01 timestamp.

  2. 15th December 2014 - the certificate is revoked. Malware will be prevented from running by systems that check CRLs.

  3. 31st December 2014 - certificate expires and is removed from CRLs as suggested by this answer - "certificates which are expired are removed from the CRL".

  4. 1st January 2015 - malware can now be run again, as the signing timestamp indicates that the certificate was valid at the time of signing, and this is what systems use when determining whether to trust a signature.

Is this possible, or am I misunderstanding something about the way code signing works? Am I making an assumption in step 4? Sources such as the Java documentation seem to imply that this is how it works - "Because signing certificates typically expire annually, this caused customers significant problems by forcing them to re-sign deployed JAR files annually. Starting in J2SE 5.0, jarsigner can generate signatures that include a timestamp, thus enabling systems/deployer (including Java Plug-in) to check whether the JAR file was signed while the signing certificate was still valid."


2 Answers 2


This is why Microsoft recommends to never remove expired code signing certs from CRLs. An alternative scenario: attacker signs their malware before cert expiry. If they can remain undiscovered past cert expiry, then the cert won't get added to the CRL even on discovery, and their malware will never get blocked. Thus the revocation status of code signing certs must be tracked forever.

From Microsoft's Code Signing Best Practices document:

In most PKI deployments, only certificates that have not yet expired are placed on the CRL. This means that when a revoked certificate expires, it is eventually removed from the CRL. However, timestamping allows Authenticode signatures to remain valid indefinitely. As a result, revoked code-signing certificates should not be removed from the CRL. This paper recommends always revoking compromised certificates that were used to sign publicly released software and maintaining these entries in the CRL indefinitely.

Microsoft Certificate Server enables administrators to configure the CA to keep all revoked certificates in the CRL. However, the CA does not distinguish between code-signing certificates and other certificates. For this reason, administrators should dedicate a CA for the sole purpose of handling code-signing production certificates.

So to answer your question - yes, the malware can run again if the CRL for code signing certs isn't managed properly.


Dealing with digital signatures is more complex than we can suppose at first sight.

Your scenario is correct: if you do not have a proof of the date/time of the signature you cannot be sure it has not been done after the revocation and expiration of the certificate. You can also note that, even if the certificate has not been revoked, a signature done after the certificate expiration should not be considered valid.

First solution

Adding a time-stamp to the software signature. This time-stamp is called signature time-stamp. This time-stamp provides a proof that the signature existed at a given date. It prooves that the signature has been computed before the expiration of the certificate. But it does not solve the second problem: what if the certificate has been revoked?

Second solution

Along with the signature time-stamp you can also attach a copy of the CRL (or an OCSP response) to the signature. It will prove that the certificate was not revoked when the signature was produced.

But time-stamp tokens and CRL are also signed objects. They also need to be validated. So, should we also get the CRL which proves that the signature time-stamp has been signed by a valid certificate? Short answer: Yes, things seems to get more complicated.

Third solution

Some signature standards (like CAdES) have proposed a better solution: along with the signature time-stamp, you should collect every items required to validate the signature off-line (i.e. being able to validate the certificate without having to download any additional object). It includes all intermediate CA certificates and CRLs. This is not an endless process since you are going to eventually reach one or several trustfully root CA but it may be quite complex (Note that a good X.509 validation algorithm should output all these items along with the certificate validity status). And after having fetched all these objects, you must put a time-stamp on it. This time-stamp is called archive time-stamp

Now the signature validation process is the following:

  1. You validate the global time-stamp on-line. It means you download all necessary element in order to ensure that the time-stamp signature is valid. Now you have a proof that all the enclosed object (CRL...) existed at the archive time-stamp date.
  2. You validate the signature off-line only with the elements which was covered by the archive time-stamp as if the current date was the date of the archive time-stamp.

With this solution the scenario you was presenting is not possible since the signature verifier has a proof of the expiration and validity status of the certificate at the date of the signature.

This solution is currently implementing for validation of long-term document signature but unfortunately, as far as I known, not for code signature validation. Today vendors are using other mechanisms like stolen certificate blacklists, which are easier to implement.

UPDATE Sept, 25 2014 (after reading @maureen comment)

First, your understanding of the process is correct: since every certificate is removed from the CRL after the expiration date, you cannot assess whether a certificate has been revoked or not in the past. Hence it is not possible to validate a signature after the expiration of a certificate.

But even if a certificate has been compromise (or simply revoked because, for instance the customer lost his USB crypto-token), all signatures created before should be considered valid. The process I described in my answer tries to explain how it is possible to answer today (i.e. even after the expiration of the certificate) that question: "Was the signature valid was it was created".

  • Thank you for your reply, but you have explained how a system can trust that the certificate was valid at the time of signing. My question is different. My understanding is this: if a certificate is compromised, a system can use a CRL to prevent code from running even though the certificate was valid when the code was signed. But after the certificate expires, it is removed from the CRL, and now code signed with that compromised certificate can be run. Is my understanding correct? Commented Sep 19, 2014 at 16:26
  • 1
    I realized that may be a bit unclear in my answer. I updated my answer trying to give a little bit more details.
    – Jcs
    Commented Sep 25, 2014 at 10:01
  • 1
    Dealing with revocation of a code signing cert is such a fascinating topic. (see recent news: krebsonsecurity.com/2014/10/…). For example, what is the mitigation strategy for signed device drivers or kernel modules? Do servers fail on reboot after running for months or years? Commented Oct 18, 2014 at 1:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .