5

I have a webserver which is asking for client certificate for mutual authentication. I have what I think is the right certificate loaded into my client browser. However, the browser is not able to find the certificate & is giving the error "This page can’t be displayed" when I visit the page from IE (it also fails in chromium and FF). Is there any tool which will help me figure out what exactly is certificate the server is asking my client browser for?

I tried through some network monitors - but there is some much data exchanged that I cannot find it.

user93353
  • 1,982
  • 3
  • 19
  • 33
  • Do you have access to the server? – Bruno Jun 30 '14 at 11:03
  • @Bruno - No - don't have access to the server. Is there no way to trouble shoot from the client side? Edit: Saw your answer now - thank you - let me try it out. – user93353 Jun 30 '14 at 11:33

3 Answers3

5
  • If the server requests the certificate during the initial handshake, simply use Wireshark and look for the Certificate Request TLS message (just before Server Hello Done). If you look into the details of this package, you should see a certificate_authorities list giving you the list of acceptable CAs. Your local chain will need to match one of these.

  • If there is no visible Certificate Request message, it may be in a re-negotiated handshake. In this case, this second handshake will be encrypted, so not immediately visible. Recent versions of Wireshark let you use a pre-master secret (see "Using the (Pre)-Master-Secret section on the Wireshark SSL wiki page, and this answer of course). This is generally more convoluted, but this can be done.

    More generally, to debug your problem, I would also look at other NSS environment variables, such as SSLDEBUG (and SSLDEBUGFILE), when using Firefox.

In addition, you could use openssl s_client -connect my.host.example:443 -servername my.host.example (with various levels of verbosity if required) to simulate a browser connection to your server. That should at least tell you which CAs are advertised in the Certificate Request message. If the server uses re-negotiation, you might need to write a minimal HTTP request looking more or less like this (adapted with what you need):

GET /my/protected/resource HTTP/1.1
Host: my.host.example

(In some complex settings, you might have to copy/paste the other headers you see from a browser request, using its developer tools.)

(You may also find the -prexit option useful in some cases, credit to this answer.)

Since it seems from comments that forging manually the HTTP request doesn't work for you, another possibility is to use curl --verbose https://my.host.example/my/protected/resource > /dev/null (you can also use finer debug levels such as --trace or --trace-ascii if required, see man page for curl). This should produce something like this, so hopefully you should see a Certificate Request somewhere:

* SSLv3, TLS handshake, Client hello (1):
} [data not shown]
* SSLv3, TLS handshake, Server hello (2):
{ [data not shown]
* SSLv3, TLS handshake, CERT (11):
{ [data not shown]
* SSLv3, TLS handshake, Server key exchange (12):
{ [data not shown]

Better, if you need the request to be more realistic, make your actual request from Chrome after opening the developer tools. Right-click on that and use "Copy as cURL", then paste it and use it with curl (add --verbose or other): this should copy the necessary headers. There's a video with an example here.

Bruno
  • 10,765
  • 1
  • 39
  • 59
  • It's a renegotiation case. i.e. www.myhost.com is 1 way ssl, but www.myhost.com/my/resource is 2 way ssl. When I give `GET /my/resource HTTP/1.1` and press enter twice, server sends back a 500 error - this doesn't happen with the browser where server asks for client certs. Any idea on why I get the 500 error? – user93353 Jun 30 '14 at 17:28
  • You need the `Host` header with HTTP/1.1 (try HTTP/1.0 just in case perhaps). – Bruno Jun 30 '14 at 18:24
  • tried both, no luck. Need to use some network sniffer to figure out what the browser passes. – user93353 Jul 01 '14 at 03:36
  • The developers tools in Chrome should let you see and save that. – Bruno Jul 01 '14 at 10:36
0

I faced an issue like this recently. The symptom if you use a more recent version of Firefox is PR_END_OF_FILE_ERROR what I suspected and eventually found was the Internet protection software on the desktop.

The specific one was the McAfee Online Threat Prevention my suspicion is it intercepts the original request somehow and recreates it, but it is not compatible with mutual authentication and thus the session gets terminated.

I suspect this may cause the same issue may occur with AiProtection or anything with Trend Micro on Asus routers if it is enabled. So something to look at if you do not have McAfee or any Internet protection software installed.

0

This isn't so much a "how to troubleshoot" as it is "the most likely problem based on your description", but have you installed the private key as well as the client certificates?

In your browser's key store (which, for IE or Chrom[e|ium] on Windows, is the Windows key store), make sure that both the client certificate and its corresponding private key are installed.

If you look at the certificate in the Certificate Manager GUI (use Start search and/or launch certmgr.msc; you probably want the "User Certificates" store, not the system one), there should be a little key icon in the upper left of the certificate icon (the cert icon by itself being a rectangle with a little ribbon in the lower right), and when you open the certificate, it should again have a little key icon in the bottom of the General tab, and say "You have a private key that corresponds to this certificate."

Screenshots of Windows' Certificate properties view, on the General and Details tabs, of a TLS client certificate. Left screenshot (General tab) shows the "Proves your identity to a remote computer" and "You have a private key that corresponds to this certificate" text. Right screenshot (Details tab) shows the Enhanced Key Usage property, which includes "Client Authentication (1.3.5.1.5.5.7.3.2)"

If it doesn't, the certificate is unusable as a client certificate. Just like the server needs the private key for its certificate when it presents it to the browser, the browser needs the private key for its certificate when it presents it to the server. Without the private key, the browser will not display the cert as an option for the TLS mutual authentication.

To fix this issue, go find the private key that the certificate was created with, and install it on your computer. It is likely to be bundled with the certificate in a .PFX or .P12 (or similar) file. If the certificate was exported from another machine, make sure it was exported with the private key (by default, Windows does not export the private key). If you cannot get the private key - if it's lost, or the passphrase for it is lost, or if it's marked non-exportable (and you don't want to do the rather hacky steps to export it anyhow) on the only machine where it's present - then you will need to create a new certificate signing request with a new key, and get the cert issued again.


Other possible reasons why the browser might not trust/present the certificate:

  • It's outside its validity period (either expired, or not yet valid).
    • To check, look at the "Valid from" box and also check the certificate Information box (it will say "This certificate has expired or is not yet valid.") Note that the cert in the screenshot has expired, but had not yet when the image was captured.
    • To fix: Wait until it is valid (if not yet), or get the cert re-issued.
  • It isn't marked as usable for client identification.
    • To check: In the certificate information box, it will probably say "Proves your identity to a remote computer" (see the blue box on the left side of the screenshot) and in the Details tab, under Enhanced Key Usage, it should say "Client Authentication" along with a long series of dots and numbers called an OID.
    • To fix: Get the cert re-issued with the right OID(s).
  • Its signature is invalid. The certificate was tampered with after it was issued, without being re-signed.
    • To check: Windows will say that the certificate's signature is invalid, probably both in the Certificate Information box (General tab) and the Certificate Status box (Certification Path tab).
    • To fix: Go back to the original certificate file as issued by the CA (or as originally self-signed, if it's a self-signed cert), or get it re-issued.
  • The certificate's signature cannot be validated. This happens if the certificate is issued by a CA (Certificate Authority) whose public key is not installed on your computer.
    • To check: The Certificate Information box will say "Windows cannot verify the certificate's signature" or anything like that, and look at the Certification Path tab to see which certificate in the chain Windows is looking for but not finding.
    • To fix: Download and install the CA's certificate (you do not need, and probably shouldn't have access to, the CA's private key). Note that if Windows doesn't recognize the CA automatically, there's a good chance that your HTTPS server won't, either.
  • Some certificate in the certification chain is revoked, expired, or otherwise invalid.
    • To check: The certificate information box will say "Windows cannot verify the authenticity of this certificate" or similar. Look at the certification path to see which cert in the chain is invalid; it'll have a little red (X) in the corner of its icon.
    • To fix: Download and install the CA's new or correct certificate. If the public key was changed, you will also need to replace any certificates which were issued using the old key, which may mean needing to get your cert re-issued.

Hope that helps!

CBHacking
  • 40,303
  • 3
  • 74
  • 98