Why host authentication has to check who the certificate belongs to

January 22, 2007

When using host SSL certificate to authenticate a host's identity, you can't just check that your CA signed the host's certificate; you also have to check that the certificate belongs to the host (usually by checking that the certificate's CN is the hostname, or IP address, or etc). The reason you need to make this additional check of the certificate is that without it, you don't know if the certificate actually came from the host you're trying to authenticate.

Imagine that you have two client machines, A and B. A and B can talk to each other's SSL host authentication service (why not, after all). An attacker wants to impersonate B. If you do not check what host the certificate belongs to, the attack goes like this:

The attacker waits until the real B is down. They configure their impostor machine to have B's IP address, and sets it up to NAT-forward incoming connections on the SSL authentication service's port off to A. Then they make a request that starts an authentication attempt. Your server calls the fake B up to get its SSL certificate; B forwards the request off to A, and passes A's packets back. As far as the server sees, it is talking to B and B is presenting a valid, CA-signed certificate, so the authentication succeeds.

It follows as a corollary that you can't issue generic CA-signed certificates for host authentication; you must issue host-locked ones.

(You can use some additional verification on top of SSL like the host echoing back its hostname to the server, but this is equivalent to checking that the SSL certificate actually belongs to the host.)

I suspect that this is well-known to crypto people, but I didn't realize it until recently. (One moral I draw from this is that designing security protocols is hard and I should do as little of it as possible, just in case.)

Comments on this page:

By DanielMartin at 2007-01-23 09:09:20:

Note that the main reason you have this need is that you are trying to authenticate via the SSL host certificate some other service that won't be running over that same SSL connection. (The other reason you might be doing this is if you trusted some hosts that had been signed by this CA, but not others)

For example, suppose I were doing something that automatically uploaded a credit card transaction to one of two or three internal servers. (doesn't matter which one; let's say that's being done for load balancing) I do this upload over SSL, and I check that the target is one of the machines signed by my I-can-send-credit-cards-here CA.

Now, suppose an attacker tried the scneario you're positing. So what? It wouldn't matter. The attacker would get the encrypted stream only.

I think that the lesson here is that SSL is designed to do what it's designed to do, and not something else. I might even suggest that you need to investigate if there isn't a protocol that's actually designed for this kind of "callback" authentication.

By cks at 2007-01-25 14:40:57:

The reason I am using SSL in all of this is that SSL is a convenient underlying layer to build a 'does this host know a particular secret?' service on top of, where the host's SSL certificate fills in the role of the secret. On the client side it's easy to build a simple do-nothing SSL service on top of stunnel or the like; on the server side all you really need on top of the ability to make a SSL connection is a 'did this host give us certificate X?' function (or a 'what certificate did this host give us' one).

I can't think of anything else that would be as widely supported and as easy to build stuff on top of. (And which is widely maintained and supported by other people.)

Written on 22 January 2007.
« Sometimes system administration requires a hacksaw
How to stop DiskSuite resyncing a mirror on Solaris 8 »

Page tools: View Source, View Normal, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Mon Jan 22 23:08:20 2007
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.