piv-go icon indicating copy to clipboard operation
piv-go copied to clipboard

Windows - exclusive transaction is only usable for 5 seconds

Open Joerger opened this issue 6 months ago • 2 comments

On Windows, an exclusive transaction from SCardBeginTransaction is only usable for 5 seconds. After this timeout, all operations will result with SCARD_W_RESET_CARD - "The smart card has been reset, so any shared state information is invalid.".

From the Winscard API docs:

If a transaction is held on the card for more than five seconds with no operations happening on that card, then the card is reset. Calling any of the Smart Card and Reader Access Functions or Direct Card Access Functions on the card that is transacted results in the timer being reset to continue allowing the transaction to be used.

The SCardBeginTransaction function is a smart card and reader access function. For more information about other access functions, see Smart Card and Reader Access Functions.

To resolve this, the caller must refresh the transaction with SCardReconnect.

From the Winscard API docs:

The SCardReconnect function reestablishes an existing connection between the calling application and a smart card. This function moves a card handle from direct access to general access, or acknowledges and clears an error condition that is preventing further access to the card.

I've validated that this approach works and am working on preparing a PR.

Related downstream issues:

  • https://github.com/gravitational/teleport/issues/54332
  • https://github.com/FiloSottile/yubikey-agent/issues/70

Joerger avatar May 06 '25 22:05 Joerger

Probably time to finally do https://github.com/go-piv/piv-go/pull/108 ?

ericchiang avatar May 06 '25 22:05 ericchiang

Probably time to finally do #108 ?

That's been on my radar as it would be useful alongside application-side PIN caching. Do you plan on completing that PR or do you need someone to take it over (I may or may not have the bandwidth for it at the moment).

That said, supporting refreshing exclusive transactions will still be useful with PIV internal PIN caching. How would you like to see this implemented? Should this be an automatic retry mechanism on SCARD_W_RESET_CARD, e.g. within func (t *scTx) Transmit?

Joerger avatar May 06 '25 23:05 Joerger