node.jsbrowsertls1.3mtls

TLS1.3 renegotiation


We have a web app + node.js server, mTLS secured. The customer came up with an idea of assigning roles to users via issuing multiple client certificates with different entitlements. Effectively, when the user is done using one of his roles, he wants to click an equivalent of "Logout" and be presented with the browser's choice of client certificates again.

With TLS1.2, it work flawlessly via TLSSocket.renegotiate. I know it's not possible out of the box with TLS1.3, we tried so far:

  1. modify TLS tickets upon "Logout" - no effect
  2. a little Express middleware that responds with 403 after the "logout" - works as expected, but it was naive to think that it would invoke cert choice
  3. implement resumeSession handler, call back with error and null session
  4. implement OCSPRequest handler and simulate revocation. We only went as far as returning error. Returning null Buffer is not possible in TypeScript, this may be a bug in Node.js types.

No. 3 and 4 results in strangely failed requests visible in browser Network Inspector, but without HTTP response. This may mean that something is really happening at TLS level, but it does not invoke the cert choice dialog anyway.

The only way we figured out so far, is to use browser Incognito mode and "logout" by closing it. But Incognito is prohibited by customer's IT dept.

On the positive side, we have one uncommon power. The app is meant to allow only one client at a time (don't ask), so we can even restart the webserver completely after logout. But, if we simulate manually, it goes on with the previously used cert - no choice presented.

As far as my research of TLS 1.3 goes, there is something called "post-handshake authentication" but it is reportedly not implemented in node.js because it's forbidden in HTTP/2.

Any ideas?


Solution

  • Two months of development evidence suggest that it is not possible to renegotiate TLS1.3 by self-written logic on the (node.js) server, the less on the (web browser) client.

    The only way to initiate renegotiation is to close the current tab with established TLS session and open new one. This can be a regular tab, not only Private as claimed in my original question - except Firefox. Firefox seems to remember TLS session even between closed (regular) tabs and the original statement applies.