Question

I'm trying to set up client certificate authentication. I was able to generate a CA-, server- and client-certificate. As long as I use Fiddler everything works as expected. However, as soon as I start using a browser it doesn't work anymore (HTTP Error 403.7 - Forbidden).

Of course I imported the client certificate in the Personal store and I made sure Client Certificate Negotiation is enabled.

I also tried openssl s_client -connect 127.0.0.1:443 -state -debug but I couldn't really make sense of the result... The only thing what's weird is that my CA doesn't show up in the Acceptable client certificate CA names section.

Anything else I could try?

Update: I think it doesn't matter but my server certificate is set up for 127.0.0.1. Therefore I'm using https://127.0.0.1/... in my browsers.

Update2: Using Wireshark I noticed that my servers' response depends on the client:

Fiddler (OK):

Client Hello 
Server Hello, Certificate, Server Hello Done

Browser (Not OK):

Client Hello
Server Hello, Change Cipher Spec, Encrypted Handshake Message

Update3: After enabling clientcertnegotiation the server response is different but still doesn't work:

Server Hello, Certificate
Certificate Request
Certificate, Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message

My self-signed CA doesn't seem to be in the Distinguished Names list...

Update4: SSL Settings: Checked Require SSL and Client certificates set as Required. Client cert shows up in Personal and the intended purpose is Client Authentication.

Was it helpful?

Solution

I finally found the issue and a workaround:

As mentioned in Update3, Distinguished Names doesn't contain my CA. This is because Distinguished Names has a limit of 2^14 bytes (16384 bytes). Because I do have a lot of CA installed on my machine my CA simply didn't make it in. The TLS standard would allow to send multiple messages but unfortunately Windows doesn't support this!

As mentioned here you have a few possibilities. The simplest one is this:

At your server add a DWORD (not QWORD!) value called SendTrustedIssuerList in your registry under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL and set it to 0. This will prevent your server from sending a list at all, letting the client choose from any installed client certificate.

Unfortunately I couldn't see any traces in the Event Viewer (as reported elsewhere). Therefore the issue wasn't easy to spot (I had to use Wireshark in order to check Distinguished Names).

OTHER TIPS

Use the Accept option instead of the Require option of the "Client certificates" feature.

  1. In IIS Manager, locate the Web application for which you want to change the SSL setting.

  2. In Features View, double-click SSL Settings.

  3. On the SSL Settings page, select the Accept option under Client certificates.

  4. In the Actions pane, click Apply.

More info here

Client certificate should be imported in CurrentUser\My store with private key (i.e. p12 or pfx file usually). CA certificate should be in LocalMachine\Root store so that IIS trusts all certificates issued by the CA and the CA is trusted for every user on the computer.

CRL issued by the CA should be either available through URL (specified in every end entity certificate that CA issued) or imported in LocalMachine\My store.

NOTE: openssl doesn't use windows certificate store so this will have no efect on openssl s_client -connect 127.0.0.1:443 -state

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top