Why I want direct certificate checking instead of having to rely on CAs

January 18, 2007

The common SSL model is that you verify someone's good nature by checking to see that their certificate is signed by an approved CA. For example, if you are verifying that hosts you are connecting to are approved you would make up a CA certificate, then make up a bunch of host certificates and sign them with the CA certificate. When you connect to a machine, you verify that its certificate is signed by your CA certificate.

(Except that that's a simplification; you actually need to verify that the certificate is signed and that some identifying information in it is correct, such as the machine's hostname being the CN.)

The alternate approach is to directly check that each host's server certificate is in your list of approved certificates (and perhaps that it comes from the host that you expect it to). I maintain that this is the better approach for situations such as host verification.

The problem with the CA approach is dealing with bad certificates. First, you need to use not just a CA check but CA plus CRL, because if you just check for your CA signature the only thing you can do when a host certificate is compromised is to change to a new CA certificate, which invalidates all current host certificates. Unfortunately, CRLs are not widely used in the wild, so they are not necessarily well supported in tools.

Even with CA plus CRL you still have the risk that an attacker has managed to get some signed host certificates of his own (whether by quietly compromising your keys or by surreptitiously inserting things into your processing pipeline). Since you do not have copies of these certificates yourself (unless you catch one live during a host verification attempt), you cannot generate CRL entries for them; if you think this may have happened, your only recourse is to change your entire CA certificate.

By contrast, directly checking that you know each host's server certificate is much easier and more direct. You have a complete list of what certificates you accept and who you accept them from. If a certificate is not there, you know it will not be accepted; invalidating a bad certificate is as simple and precise as rm.

(Plus, you do not have to maintain and keep secure a CA signing setup.)

What this boils down to is that the CA approach is 'everything that is not explicitly forbidden is permitted' (if it is signed by your CA certificate it is allowed unless it is in your CRL), whereas direct certificate checking is 'everything that is not explicitly permitted is forbidden' (it is only accepted if it is in your list of good certificates). The latter is a much stronger security model, plus is easier to manage until you grow quite large.


Comments on this page:

By Dan.Astoorian at 2007-01-19 12:02:14:

Even with CA plus CRL you still have the risk that an attacker has managed to get some signed host certificates of his own (whether by quietly compromising your keys or by surreptitiously inserting things into your processing pipeline)

This is a practical risk if and only if it is substantially easier to create a new signed host certificate than to break or steal the private key for an existing one; I can't think of any reason that would be the case, unless you are doing something very, very wrong (such as failing to protect your CA private key at least as well as your host certificate private keys).

What this boils down to is that the CA approach is 'everything that is not explicitly forbidden is permitted' (if it is signed by your CA certificate it is allowed unless it is in your CRL),

That logic is tangled: issuing a host certificate with your CA certificate is a (cryptographically-strong) form of explicitly granting permission to the possessor of the certificate's private key, so it really boils down to "everything that is explicitly permitted [through issuing a certificate] that is not explicitly forbidden [via a CRL] is permitted (and everything else is forbidden)." From that statement follows this one: "everything that is not explicitly permitted is forbidden."

--Dan

By cks at 2007-01-19 17:14:56:

Let me rephrase my CA+CRL versus direct checking thing slightly: CA+CRL is fundamentally 'everything not explicitly listed is allowed (provided that it is signed by the CA cert etc)', whereas direct checking is 'everything that is not explicitly listed is forbidden'.

I disagree with:

[...] issuing a host certificate with your CA certificate is a (cryptographically-strong) form of explicitly granting permission to the possessor of the certificate's private key, [...]

If you actually knowingly issued the key, that is true. But a signature by the CA certificate is not proof of that any more than my digital signature on a piece of email is proof that I wrote it, and for the same reason. Both are merely reasonably strong indications.

Of course, neither is the presence of a digital signature in a directory. But the presence of the digital signature is much more direct and visible, so it is much more amenable to me checking to make sure that intentions and reality actually match up.

From 128.100.26.136 at 2007-01-20 15:57:57:

If you actually knowingly issued the key, that is true.

My point is that it is probably very safe, from a practical perspective, to assume that I did knowingly issue the key.

For this not to be the case, one must assume that an attacker had the ability to compromise my CA private key (which would certainly have been passphrase-protected, and is only ever used when signing new host certificates), but would not have been able to compromise a trusted host private key (which is used orders of magnitude more frequently, and thus is far more likely to be stored somewhere on the host in an unencrypted form).

(Strictly speaking, there is another possibility: there could be a flaw in the design or implementation of the cryptographic infrastructure itself; i.e., a weakness in the software or algorithms which make it possible for host keys to be signed without possessing the CA's private key. The fact that the entire e-commerce industry has already bet very, very heavily against this possibility makes it difficult to lend much credibility to this idea.)

But the presence of the digital signature is much more direct and visible, so it is much more amenable to me checking to make sure that intentions and reality actually match up.

In other words, it's easier for you to believe in because you can see it?

I don't dispute that direct certificate checking is a simpler approach (or would be, if the software you were using provided support for it). I only maintain that it is nevertheless not (by the mere fact of its comparative simplicity) significantly more secure than the approach already designed into the system.

--Dan

By cks at 2007-01-20 18:13:27:

In other words, it's easier for you to believe in because you can see it?

It's easier for me to trust because I can see it. (It is also easier to manipulate, because I can do so directly instead of indirectly.)

As a side effect, it also removes the need to crack the certificate open and check that the CN matches and so on. (Doing so is necessary in a CA situation.)

By cks at 2007-01-20 18:34:33:

To simplify my argument, let's look at what you need to do to authenticate a host in each case:

  • for CA checking: check CA signature, that the certificate is not in the CRL, and that the certificate's CN (or other attribute that you have specified) matches the host.

    (You do not have to check that the host is authorized; you would not have signed a certificate with a CN for an unauthorized host, and if a host becomes unauthorized you add its signature to your CRL.)

  • for direct checking: check that the certificate is authorized for that host, either directly or by having a global list of authorized certificates and then checking that the certificate CN matches the host.

(Note that in both cases you need to keep a complete list of authorized certificates yourself; it is just that in the CA case, the only thing you use the list for is putting things in the CRL.)

I believe that the second case is simpler, has fewer moving parts, and is more direct. As a result I like it better and trust it more.

By Dan.Astoorian at 2007-01-22 11:07:28:

(You do not have to check that the host is authorized; you would not have signed a certificate with a CN for an unauthorized host, and if a host becomes unauthorized you add its signature to your CRL.)

With all due respect, that's a really poor way to manage authorization.

Authorization is a separate problem from identification and authentication; you are attempting to combine everything into a single process by declaring "any host I can authenticate is authorized."

A far better model is to use SSL for identification and authentication ("I am host A, and I can prove that I hold A's private key"), then use other means to manage authorizations for authenticated hosts ("host A is allowed to use this service, but host B is not).

The CRL is used when the authentication loses its trustworthiness (e.g., because there's evidence that someone might have had access to A's private key, not merely because A is no longer authorized to access the service).

--Dan

By cks at 2007-01-22 11:37:34:

You're right; I should not have talked about authorization at all. Indeed in the situation I'm thinking about, the authorization is entirely separate; we would not be making the SSL call to verify the host's identity if the machine wasn't authorized.

I still prefer 'check if certificate is X' to 'check if certificate is signed, has not been revoked, and has a CN of X' as a way of verifying the host's identity, though.

Written on 18 January 2007.
« A grump about the socket module's SSL support
Link: Peter Gutmann on PKI »

Page tools: View Source, View Normal.
Search:
Login: Password:

Last modified: Thu Jan 18 23:44:19 2007
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.