Make IIS require SSL client certificate during initial handshake
Asked Answered
L

2

25

I am trying to configure an IIS website to require SSL client certificates. The website is set up in both IIS 6 and 7, though I am more interested in making it work for 7. I set the require client certificates property in IIS and it works fine when accessing the site through a web browser, but a Java-based client is having trouble accessing it.

I believe the problem is that IIS does not request a client certificate during the initial SSL handshake. Instead it negotiates a normal SSL connection, checks to see if the resource requires client certificates, and if it does it then initiates a new SSL handshake that requests a client certificate. IIS does this so support sites that only require the client certificates for certain resources. Even when the requirement is specified for the entire website, IIS still initiates two SSL handshakes. I want to force IIS to request the client certificate on the first SSL handshake, which will hopefully get things working for the client. (The client is developed by an external partner and I have virtually no knowledge of how it is set up and no access to its source code)

Has anyone dealt with this problem in IIS before?

Liberalism answered 25/3, 2010 at 18:27 Comment(1)
You may want to try this question on serverfault.comSassafras
F
7

It took me a while to find this metabase setting. We were having this same problem with our client using the new certicom libraries. Since the discovery of the MITM attack arround SSL Renegotiation, the answer in alot of circles has been to hangup on renegotitation requests.

running the following cmd from \inetpub\adminscripts will force IIS to always request a client certificate.

For IIS 6: cscript adsutil.vbs set \w3svc\siteID\SSLAlwaysNegoClientCert True

(So for the default website, cscript adsutil.vbs set \w3svc\1\SSLAlwaysNegoClientCert True)

Keep in mind that some clients Internet Explorer prompt for client certificates when it recieves that packet wether the client certificate is needed or not.

For IIS 7:

Save the following text to a file called "Enable_SSL_Renegotiate_Workaround.js"

var vdirObj=GetObject("IIS://localhost/W3svc/1"); 
// replace 1 on this line with the number of the web site you wish to configure 

WScript.Echo("Value of SSLAlwaysNegoClientCert Before: " + vdirObj.SSLAlwaysNegoClientCert); 
vdirObj.Put("SSLAlwaysNegoClientCert", true); 
vdirObj.SetInfo(); 
WScript.Echo("Value of SSLAlwaysNegoClientCert After: " + vdirObj.SSLAlwaysNegoClientCert);

Run the following command from an elevated / administrator command prompt:

cscript.exe enable_ssl_renegotiate_workaround.js

(Jacked from the KB article for 977377)

Frow answered 9/7, 2010 at 12:19 Comment(3)
well, it didnt like the way I typed it... generic cscript adsutil.vbs \w3svc\siteID\SSLAlwaysNegoClientCert True for the default website (Example) cscript adsutil.vbs \w3svc\1\SSLAlwaysNegoClientCert TrueFrow
Does this work in IIS 7? I remember finding SSLAlwaysNegoClientCert but I was unable to figure out how to set it in IIS 7. I found this explanation recently: forums.iis.net/t/1158990.aspx. In the end, we decided to go a different route for our client authentication, so my interest is just from curiosity. Thanks for your answer.Liberalism
Yes, our setup doc already recomends the IIS 6 compatability components. So, I got off easy. Your question might have saved me a bum chewing on monday though. I didn't check if adsutil was a part of the IIS 6 combatibility components. I have had far too many too many to worry about that now.Frow
S
15

Here's how I did this, on IIS 7.5:

  1. Run the following in an admin command prompt: netsh http show sslcert
  2. Save the output in a text file. Will look something like this:

    IP:port                 : 0.0.0.0:443
    Certificate Hash        : [a hash value]
    Application ID          : {[a GUID]}
    Certificate Store Name  : MY
    Verify Client Certificate Revocation    : Enabled
    Verify Revocation Using Cached Client Certificate Only    : Disabled
    Usage Check    : Enabled
    Revocation Freshness Time : 0
    URL Retrieval Timeout   : 0
    Ctl Identifier          : (null)
    Ctl Store Name          : (null)
    DS Mapper Usage    : Disabled
    Negotiate Client Certificate    : Disabled
    
  3. Create a batch file using that info:

    netsh http show sslcert
    netsh http delete sslcert ipport=0.0.0.0:443
    netsh http add sslcert ipport=0.0.0.0:443 certhash=[your cert hash from above] appid={[your GUID from above]} certstorename=MY verifyclientcertrevocation=enable VerifyRevocationWithCachedClientCertOnly=disable UsageCheck=Enable clientcertnegotiation=enable
    netsh http show sslcert
    

    (Yes, you have to delete and re-add; you can't just alter clientcertnegotiation in-place. That's why it's important to save the hash and GUID, so it knows what to re-add.)

  4. Run that batch file, check for any errors, done.

Keep in mind that this setting is applied per-certificate, not per-server. So if you use multiple certs, or change/update your cert, you will have to do this again.

Scratches answered 15/8, 2013 at 10:41 Comment(2)
There should be newlines between each of those netsh commands. I can't remember where I got this from - KB? MSDN?Scratches
Second that, this works in IIS 7.5 on Windows 2008 R2.Uird
F
7

It took me a while to find this metabase setting. We were having this same problem with our client using the new certicom libraries. Since the discovery of the MITM attack arround SSL Renegotiation, the answer in alot of circles has been to hangup on renegotitation requests.

running the following cmd from \inetpub\adminscripts will force IIS to always request a client certificate.

For IIS 6: cscript adsutil.vbs set \w3svc\siteID\SSLAlwaysNegoClientCert True

(So for the default website, cscript adsutil.vbs set \w3svc\1\SSLAlwaysNegoClientCert True)

Keep in mind that some clients Internet Explorer prompt for client certificates when it recieves that packet wether the client certificate is needed or not.

For IIS 7:

Save the following text to a file called "Enable_SSL_Renegotiate_Workaround.js"

var vdirObj=GetObject("IIS://localhost/W3svc/1"); 
// replace 1 on this line with the number of the web site you wish to configure 

WScript.Echo("Value of SSLAlwaysNegoClientCert Before: " + vdirObj.SSLAlwaysNegoClientCert); 
vdirObj.Put("SSLAlwaysNegoClientCert", true); 
vdirObj.SetInfo(); 
WScript.Echo("Value of SSLAlwaysNegoClientCert After: " + vdirObj.SSLAlwaysNegoClientCert);

Run the following command from an elevated / administrator command prompt:

cscript.exe enable_ssl_renegotiate_workaround.js

(Jacked from the KB article for 977377)

Frow answered 9/7, 2010 at 12:19 Comment(3)
well, it didnt like the way I typed it... generic cscript adsutil.vbs \w3svc\siteID\SSLAlwaysNegoClientCert True for the default website (Example) cscript adsutil.vbs \w3svc\1\SSLAlwaysNegoClientCert TrueFrow
Does this work in IIS 7? I remember finding SSLAlwaysNegoClientCert but I was unable to figure out how to set it in IIS 7. I found this explanation recently: forums.iis.net/t/1158990.aspx. In the end, we decided to go a different route for our client authentication, so my interest is just from curiosity. Thanks for your answer.Liberalism
Yes, our setup doc already recomends the IIS 6 compatability components. So, I got off easy. Your question might have saved me a bum chewing on monday though. I didn't check if adsutil was a part of the IIS 6 combatibility components. I have had far too many too many to worry about that now.Frow

© 2022 - 2024 — McMap. All rights reserved.