Forum Discussion

Andy_4962's avatar
Andy_4962
Icon for Nimbostratus rankNimbostratus
Feb 02, 2010

Client Certificate Request on demand

Hello group!

 

 

I can not seem to get a client cert request to appear to the end user a second time in a single session.

 

 

For authentication purposes, I want to allow the end user to Login with their client cert by clicking a "Cert Login" button. The problem I'm having is, I prompt them for their cert when they first visit the site. If they choose cancel and enter the site without the cert, then when they press the Login button, the prompt never appears again for the cert. If I do not request the cert initially, then the login button works - the prompt appears and the user can login. I have tried the code below, which appears to be the solution based on articles and posts I've read here at DevCentral. It works once, but will not work twice.

 

 

when CLIENTSSL_CLIENTCERT {

 

HTTP::release

 

}

 

when HTTP_REQUEST {

 

if { [HTTP::uri] contains "login" } {

 

HTTP::collect

 

SSL::session invalidate

 

SSL::authenticate always

 

SSL::authenticate depth 9

 

SSL::cert mode request

 

SSL::renegotiate

 

}

 

 

I added the invalidate line to resolve issues identified with IE.

 

I'm running BigIP LTM V9.4.6 HF2.

 

 

Any ideas would be appreciated. I've been pouring over this for days!

 

 

Thanks!

 

Andy
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    Hi Andy,

     

     

    You would want to check to see if a cert has been provided using SSL::cert count and possibly validate it against a trusted CA root cert configured in the client SSL profile using SSL::verify. You could then add the cert or cert details to the session table with the SSL session ID as a lookup key. On each HTTP request for "restricted" URIs you'd check whether the client has already provided a valid cert stored in the session table.

     

     

    For more examples, you can search for the forums for 'client cert request'. This process is a bit simpler in v10.1.0 as LTM saves the SSL cert details for the duration of the SSL session. I think there is a new access control module with v10.1 that you could possibly use for this as well once the product coalesces:

     

     

    BIG-IP APM:

     

    https://support.f5.com/kb/en-us/products/big-ip_apm/releasenotes/product/relnote_apm_10_1_0.html

     

     

    Aaron
  • Thanks for the reply Aaron.

     

     

    I think my issue is slightly different though. The main cause of the problem is session timeout after 42 minutes. We want to allow the user to login again, using their client certificate, without having to close the browser and open a new connection to the site. Note that my client certs are configured in Request mode. Users can access the site without providing a cert, but when they do provide a cert, the system will log them into the application without the need for an additional user/pass. I could test the secondary login after 42 minutes, but that is very time consuming. Instead, I'm choosing not to login the first time the site prompts me, and press a button to initiate Login once on the site. This should cause the BigIP to prompt the user again for a client certificate, which was not previously provided. The same code, however, does not deliver a cert prompt to the end user the second time. It simply reloads the site.

     

     

    Should the SSL::renegotiate be enough to cause another client cert request? As I'm reading it, it seems that it is, but it's just not performing that way.

     

     

    I also recognize that this may be a browser config or limitation, and am researching that as well.

     

     

    Thanks,

     

    Andy
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    Hi Andy,

     

     

    Thanks for the clarifying. So you're testing to a VIP with a client SSL profile set to request a client cert. You access a link containing "login", click cancel on the cert prompt, then click on a login link again and don't get a cert prompt?

     

     

    IE (and most other browsers) will "remember" by default the user's selection (or non-selection) of a cert for the duration of the SSL session. I thought using SSL::session invalidate and SSL::renegotiate would force a new SSL session to be negotiated. And I thought in the process, the browser would prompt the user the next time a cert was requested by LTM.

     

     

    To test, can you change your browser to prompt you on each request for a client cert? It might also help to log the SSL::sessionid value to see if a new SSL session is negotiated. You could also capture a tcpdump and use ssldump to decrypt/analyze the SSL handshakes:

     

     

    ssldump -AedHr /var/tmp/encrypted.dmp -Nk /config/ssl/ssl.key/ssl.key > /var/tmp/decrypted.dmp.txt

     

     

    Aaron
  • Aaron,

     

     

    Your on the right track now, sorry it was hard to explain.

     

     

    I logged the SSL::sessionid and with or without SSL::session invalidate the session ID is changed, but no, still no additional prompt from IE7. I suspected the browser was causing that, but I can't find a setting to force it to prompt at each new SSL negotiation.

     

     

    I have performed TCP dumps as suggested, and it looks like the BigIP is acting as it should. I can see the re-negotiation occuring and the client being prompted for a cert, and it looks like the client is returning the same response. I am moving on to test with different browsers to try to verify that this is a client side issue. Since I have little to no control of the end users browser, if I can't find a way to trick the browser into restarting it's session, I may be stuck. I'll post more info after testing.

     

     

    Thanks!

     

    Andy
  • Aaron and all interested,

     

     

    We have finally found a solution, though it is not with the BigIP. The client browser was in fact causing the problem. As the session remains between client and server, so does the certificate cache on the client. The browser would re-submit the first cert chosen, which in this case was an empty cert. Firefox has the option to enable a prompt at each cert request, but I could find no such option in any version of IE. Nothing I tried with the BigIP would clear this cache either. SSL renegotiate would request a new cert, but was under the mercy of the browser to comply.

     

     

    The solution used can be reviewed here - http://forums.asp.net/p/1032469/2854577.aspx2854577 though it does seem limited to Internet Explorer. I've not yet tested this fix under other browsers. We do not currently support other browsers for our application.

     

     

    Thanks again Aaron for the quick responses!

     

    Andy
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    Great info...

     

     

    You might also be able to send a 401 to force a clearing of the auth cache:

     

     

    http://www.adopenstatic.com/cs/blogs/ken/archive/2005/04/12/14.aspx

     

     

    In the past I would have recommended one of three strategies:

     

     

    * Programmatically send a 401 HTTP status to the client (e.g. Response.Status = 401)

     

    * Redirect a user to http://fakeuser:wrongpassword@www.yoursite.com (this doesn't work with patched IE6 anymore). Since fakeuser/wrongpassword isn't a valid Windows account, the user will be prompted to enter valid credentials

     

    * Use the client-side ActiveX control described in KB 195192

     

     

    With the exception of the first option (setting the Response.Status), the methods are mostly ugly hacks IMHO.

     

     

    Now, we have a new way of clearing the IE authentication cache. Beginning with IE6 SP1 the following piece of javascript code will clear IE's credentials cache. Note, that this will clear the credentials cache for the entire iexplore.exe process, so users will be forced to re-authenticate to any site being accessed by that process (in case they have multiple windows open pointing to multiple websites):

     

     

    // Clear current credentials

     

    // Requires IE6 SP1 or later

     

    document.execCommand(ClearAuthenticationCache, false)

     

     

    More information can be found in MSDN: ClearAuthenticationCache (Click here) and execCommand (Click here)

     

     

    I am not sure whether any of these options would work for non-IE browsers. I searched for any kind of server-side method for forcing any type of browser to delete it's SSL cache for a particular site, but couldn't find anything.

     

     

    Aaron