CAC Smartcard Reauthenticate

There are two ways of doing smartcard client authentication on the web: standard TLS/SSL or custom plugins for the browser. I assume you're talking about standard web browsers (IE/FF/Safari) and SSL authentication.

There are two things that matter for PIN prompts:

  • SSL session and SSL session cache of the browser
  • on-card authentication state of the related private key
  • the way middleware is implemented.

In the end, from security perspective, it is the card that knows when to "ask for” a PIN - some cards and keys require a PIN for every operation with the key, some cards are OK to get a PIN once and leave the keys in authenticated state until it is removed from the reader or reset by an application.

If the session in the cache of the browser can not be re-used or when the connection is being established, smart card middleware (PKCS#11 on Linux, CryptoAPI/BaseCSP module on Windows or Tokend on OSX) needs to talk to the keys on the card. If the authentication state on the card requires a PIN to be entered, a callback is usually triggered by the browser. Or if the middleware knows it will need the PIN, it will ask it before talking to the card.

There is no 1:1 relation between entering a PIN and actually re-authenticating access rights to the private key and re-authenticating the SSL session.

With standard SSL, you depend on the way SSL is implemented in browsers and can not have a 100% reliable "re-authenticate by entering PIN" on the client side.

If you are using Linux, then with OpenSC (which, AFAIK can use CAC cards) you can set "transaction_reset" in opensc.conf to true, which results in the card being reset after every transaction (every SSL session negotiation) and this way you can be sure that whenever you open a new SSL session, user has to enter the PIN again. This is a client side configuration though, not a server-initiated feature.


There's a few different pieces of software involved here.

First is the card itself. To perform a digital signature, the CAC has to be in a "verified" state, meaning a PIN was entered after the card was inserted. Beyond that, each key on the card has a flag that indicates whether the PIN has to be entered every time the key is used. I haven't checked, but I think this is set for the "email" key pair on a CAC. Thus, you'd need to find which keys have this "always verify" flag set, and configure the path validator on the service to accept only those keys. You might be able to require a particular OID in extended key usage, or exclude some of the DoD intermediate certificates from path building (flagging them as revoked, perhaps).

The middleware on the machine talking to the card could also cache the PIN, and provide it to the card whenever the card indicates that it requires a PIN before it will complete an operation. I think that ActivClient was doing this with its PIN caching feature through version 6, but in version 7, this option seems to have gone missing. I haven't found anything like this in Windows built-in PIV support. This "feature" could compromise security, so my guess is that it was deliberately removed and there wouldn't be any registry hacks or otherwise to restore the behavior. This is something you wouldn't have control over, unless you manage the users' machines; there's no HTTP header or TLS option that you can use to enforce PIN entry. But, with newer systems, it should not be an issue.

On the server side, a complete handshake has to occur in order to make the client perform authentication. Client authentication won't happen if there's a valid TLS session. So you'd need to find a way to invalidate the TLS session (not the application session, which is probably tied to an HTTP cookie) before requesting authentication, or direct the authentication request to another interface that doesn't have sessions enabled.