According to RFC6066, constrained clients can send certificate URLs instead of full certificates for TLS client authentication:

After negotiation of the use of client certificate URLs has been
successfully completed (by exchanging hellos including
"client_certificate_url" extensions), clients MAY send a
"CertificateURL" message in place of a "Certificate" message as
follows (see also Section 2):

     enum {
      individual_certs(0), pkipath(1), (255)
  } CertChainType;

  struct {
      CertChainType type;
      URLAndHash url_and_hash_list<1..2^16-1>;
  } CertificateURL;

  struct {
      opaque url<1..2^16-1>;
      unint8 padding;
      opaque SHA1Hash[20];
  } URLAndHash;


The hash corresponding to each URL is the SHA-1 hash of the
certificate or certificate chain (in the case of X.509 certificates,
the DER-encoded certificate or the DER-encoded PkiPath).


The server MUST check that the SHA-1 hash of the contents of the
object retrieved from that URL (after decoding any MIME Content-
Transfer-Encoding) matches the given hash.  If any retrieved object
does not have the correct SHA-1 hash, the server MUST abort the
handshake with a bad_certificate_hash_value(114) alert. This alert
is always fatal.

An active attacker can easily modify the URL to point to a certificate (or certificate chain) of their choice & replace the 20 bytes of "SHA1Hash" with the corresponding computed SHA1 hash, and the server will realize the problem only when it tries to verify the "Certificate Verify" message from the client. Also, the server verifies the SHA1 hash only after fetching the contents pointed by the URL, so any generic attack like buffer overflow or SQL injection on the server hosting the URL is also not prevented. Then, why is 20-byte SHA1 hash of URL included with this message?

  • You are right. Here is my best guess why this makes sense: I think this is less about security but more about identifying the correct root at all. So you can be sure that the root the embedded device trusts is the same one that you just downloaded. The embedded device might be online for years and years and the cert behind the URL might change in the meantime. Commented May 13, 2016 at 4:54

1 Answer 1


From my understanding your problem is that an active man in the middle can make a server S access a URL at host U and this URL is specified by the attacker. And the problem with this is not that the attacker might get to the contents behind this URL (he can't) but that just accessing this URL might trigger a bug at the server U.

Thus to make this attack working the following conditions must apply:

  • There must be a bug in server U which can be triggered just by accessing the specific URL.
  • The attacker can do an active man in the middle attack.
  • The attacker is either not willing or not able to access server U directly so it needs to use server S to access this URL.
  • Server S does implement the feature to get the clients certificate from a URL.
  • Server S does no filtering which kind of URL's it can access or server U is allowed by this filter.

If all this applies it can be used to attack server U. But in most cases there are far easier ways to make somebody access URL, like accessing the URL directly, including it in some <img src... tag at some web site to be accessed by somebody else or similar.

Then, why is 20-byte SHA1 hash of URL included with this message?

While I do not find any explicit explanation in the RFC my guess is that it is only to make sure that the server U actually provided the expected content and not something else which makes a bit sense in cases where the client itself has no real control over changes done at server U. This is not to prohibit attacks against server U.

Of course if the content served by U does not contain the expected client certificate it will be noticed during the handshake anyway because the private key used by the client does not match the client certificate. Thus it is questionable if this hash is really helpful or if it is just another useless feature which nevertheless made in in the standard: Remember the TLS heartbeat extension where the server for no real reason had to send the contents of the clients request payload back?

You must log in to answer this question.

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