Reputation: 517
I have created a website that I want to be able to access using a smart card so I have enabled SSL on the site. When I am logged in remotely to the server and access the site on the https port using the smart card everything works fine. I receive my prompt and the site loads. However, if I try to access the same site, using the same card from a client pc then I receive the 403 Forbidden error.
Settings on the server(IIS 7.5) I have implemented or verified:
1) Site is bound to specific port (not 443) with a type of https and a certificate that has a friendly name.
2) SSL settings: Require SSL is checked, Require client certificates is selected (note: if I set it to accept, the site will load for the client but it never prompts for credentials)
3) I have verified that when Require client certificates is set to accept, that the certificate it recognizes in the browser is the correct one (e.g. myserver.com) but as I said then I don't receive the prompt for credentials
4) Anonymous Authentication is enabled, all others disabled
5) applicationhost.config file set the following in location -> system.webserver -> security:
a) sslFlags = "Ssl, SslNegotiateCert, SslRequireCert"
b) under authentication set iisClientCertificateMappingAuthentication to true
6) I have confirmed the necessary certificates exist in the Trusted Root and Personal folders for the Local Computer account.
Settings for the client:
1) I have confirmed the necessary certificates exist and match what the server has in the Trusted Root and Personal folders for the Local Computer account.
2) I have checked that the certificate chain in the browser does not show any errors going down the chain in both IE and Chrome
I created a self-signed certificate and added it to all the certificate stores on the server and the client and received the same behavior.
Using OpenSSL I have achieved the following results:
openssl s_client -connect myserver.com -CAfile c:\certs\godaddy.pem -servername myserver.com
Loading 'screen' into random state - done
CONNECTED(00000160)
depth=2 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go D
addy Root Certificate Authority - G2
verify return:1
depth=1 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", OU = http
://certs.godaddy.com/repository/, CN = Go Daddy Secure Certificate Authority - G
2
verify return:1
depth=0 OU = Domain Control Validated, CN = *.myserver.com
verify return:1
---
Certificate chain
0 s:/OU=Domain Control Validated/CN=*.myserver.com
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.c
om/repository//CN=Go Daddy Secure Certificate Authority - G2
1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.c
om/repository//CN=Go Daddy Secure Certificate Authority - G2
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certific
ate Authority - G2
---
Server certificate
-----BEGIN CERTIFICATE-----
...29u1FZGXZnMUZCW5rlmZrkCAiBwDAB0/2t6BhyGh0JxydLWrRzJAZhW33KIem7IC...
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/CN=*.myserver.com
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy
.com/repository//CN=Go Daddy Secure Certificate Authority - G2
---
No client certificate CA names sent
---
SSL handshake has read 2713 bytes and written 673 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1
Cipher : AES128-SHA
Session-ID: *** edited ***
Session-ID-ctx:
Master-Key: *** edited ***
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1439825381
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
read:errno=10054
The OpenSSL results has one section that says 'No client certificate CA names sent' and before I added the -CAfile option I was getting the Verify 20 error unable to get local issuer certificate.
UPDATE to OpenSSL results:
Figured out how to use the debug feature and from what I can see here, it seems to negotiate SSL correctly and with the correct certificate as long as I pass in the CAfile path.
openssl s_client -connect myserver.com:10168 -state -debug -CAfile c:\certs\godaddy.pem -servername myserver
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=2 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go Daddy Root Certificate Authority - G2
verify return:1
depth=1 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", OU = http://certs.godaddy.com/repository/, CN = Go Daddy Secure Certificate
Authority - G2
verify return:1
depth=0 OU = Domain Control Validated, CN = *.myserver.com
verify return:1
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL_connect:SSLv3 read finished A
---
Certificate chain
0 s:/OU=Domain Control Validated/CN=*.myserver.com
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.c
om/repository//CN=Go Daddy Secure Certificate Authority - G2
1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.c
om/repository//CN=Go Daddy Secure Certificate Authority - G2
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certific
ate Authority - G2
---
Server certificate
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/CN=*.myserver.com
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy
.com/repository//CN=Go Daddy Secure Certificate Authority - G2
---
No client certificate CA names sent
---
SSL handshake has read 2713 bytes and written 643 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1
Cipher : AES128-SHA
Session-ID: ***
Session-ID-ctx:
Master-Key: ***
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1439919398
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
read from 0x2dd5b0 [0x2f06d3] (5 bytes => -1 (0xFFFFFFFF))
read:errno=10054
write to 0x2dd5b0 [0x2f4c23] (37 bytes => -1 (0xFFFFFFFF))
Additional openssl command:
openssl s_client -connect yourip:443 -prexit
...found on this SO site here did prove that in the list of acceptable certificates names was the Go Daddy Class 2 Certification Authority CA; however, I did not see *.myserver.com. Since *.myserver.com is chained to the Go Daddy Class 2 Certification Authority CA it seems that might be a normal process as indicated by this site here. On my local pc and the server the Go Daddy certificate exists in both the Trusted Root and Intermediate CA folders.
UPDATE - netsh:
I also tried the netsh http add sslcert certhash= appid= clientcertnegotiation=enable
which executed sucessfully but did not result in any success.
UPDATE TO WIRESHARK INFO:
If I use Wireshark on my local pc to look at the traffic specifically to the server (display filter is set to search for ip.addr or ssl) I don't see any traffic at all generated by SSL. There's no Client or Server Hello or Certificate entry. I did verify in the first three SYN, SYN/ACK, and ACK packets that the IP addresses and ports were the correct values.
When I run Wireshark on the server I don't see any SSL traffic either specifically coming from my IP address. However, if I run Wireshark and my SSL website directly on the server, the site does resolve, works and prompts for credentials like it should but I discovered that the Certificate id-at-commonName equals a certificate different than I assigned to the site (*.myserver.com) which is *.vo.msecnd.net and belongs according to my research to the Baltimore CyberTrust Root certificate from Microsoft.
UPDATE - Repaired Certificate
Followed the instructions on this site to repair the certificate and rule out it being faulty. I don't have an Entrust cert but the instructions at the bottom work the same.
Why am I not seeing a Client Hello? How can I troubleshoot lack of SSL handshake?
Some SO sites that I have used to try and resolve the issue include:
OpenSSL errno 10054,connection refused
OpenSSL: unable to get local issuer certificate
IIS 7.5 site with SSL fails, site without SSL works
RESOLUTION:
It appears the combination of certificate repair and setting the clientcertnegotiation did the trick but only after I rebooted the server.
Upvotes: 2
Views: 2300
Reputation: 3553
The correct steps are:
netsh http show sslcert and copy the values
Remove server SSL certificate binding with netsh http delete sslcert
Added server SSL certificate binding with netsh http add sslcert ipport=0.0.0.0:443 certhash=.... appid=.... sslctlstorename=ClientAuthIssuer clientcertnegotiation=enable
Verified that settings were applied with netsh http show sslcert
(Windows 2012 R2 only) Set HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\SendTrustedIssuerList
to 1
Upvotes: 1