This content has been marked as final. Show 1 reply
The reset parameter to<tt> javax.smartcardio.Card.disconnect() </tt>controls what the underlying PC/SC interface to the reader receives as the parameters to<tt> SCardDisconnect </tt>. The original design, for contact cards per ISO/IEC 7816-3, was in turn controlling if communication with the card should be able to later resume undisturbed (for the value<tt> SCARD_LEAVE_CARD </tt> passed to<tt> SCardDisconnect </tt>), or if the card should be reset (for some other values), so that the next use of the card will return the card to its initial state.
According to several sources, the<tt> reset </tt>parameter tends to do, in some JRE (and as far as I can tell, all JRE with<tt> javax.smartcardio </tt>), the opposite of what its name and documentation suggests;<tt> disconnect() </tt>does
<tt>SCardDisconnect(cardId, (reset ? SCARD_LEAVE_CARD : SCARD_RESET_CARD));</tt>
that is, the card is reset when<tt> reset </tt>is<tt> false </tt>.
This is corroborated by
What's does reset parameter do in card.disconnect() method smart card API
Update: As explained there,
the<tt> reset </tt>parameter has another effect: permission to perform<tt> Card.disconnect(true)</tt> is conditional, while there is no restriction to<tt> Card.disconnect(false)</tt>.
The documentation there says "reset the card using<tt> Card.disconnect(true) </tt>" which confirms the polarity of<tt> reset </tt>is a slip.
For an ISO/IEC 7816-3 contact card reader with a compliant PC/SC interface,<tt> javax.smartcardio.Card.disconnect(false) </tt>, as it really is implemented, should thus be bringing down to low voltage the card's RST contact, stopping whatever the card was doing; and the card should start afresh on the next use, which nominally will be at the next<tt> connect() </tt>issued thru<tt> javax.smartcardio </tt>(or<tt> ScardConnect() </tt>issued otherwise) hitting the same card reader. While on<tt> disconnect(true) </tt>, and subject to permission, the card should be relinquished for uses by other application still with memory of what previously happened, such as the rights opened by presentation of the user's PIN code still enabled, or any similar state (of some protocol, or secure messaging; application or file selected...)
Not resetting the card requires an authorization, when resetting the card is always allowed. I can't imagine any case where the ability to reset the card could constitute a security risk. I can more easily see cases where not reseting the card is a security risk, for the former application w.r.t. the next one using the Smart Card (e.g. the former application accidentally leaves the card open to uses by the next application with the rights associated to PIN code presentation enabled), or vice-versa (the former application selects a trojan applet in the card that will siphon the input of the next application, which blindly expects its applet to be selected by default). Therefore, in my opinion, the slip on<tt> reset </tt>polarity errs on the safe side. One could pretend that's not a bug, but a security feature.
Unfortunately, and independently from the issue of the polarity of the<tt> reset </tt> parameter, things are far from as simple as that, for a multitude of reasons.
1)<tt> SCardDisconnect(SCARD_RESET_CARD) </tt>nominally is such that on the next use of the reader (perhaps: if not too much time has elapsed or/and the card was not moved in the interval), a contact reader will reset the card without first powering it off, contrary to what should have happened with<tt> SCardDisconnect(SCARD_UNPOWER_CARD) </tt>, which there is no documented way to issue using<tt> javax.smartcardio </tt>.
That matters because quite a few cards will behave differently on cold reset (one following insertion of a card, or on next card use after<tt> SCardDisconnect(SCARD_UNPOWER_CARD) </tt>) and on warm reset (one not following a power-off, that is on next card use after<tt> SCardDisconnect(SCARD_RESET_CARD) </tt>). In particular, the ATR may change, with effect on the communication protocol used between the card and the reader. But it is not unheard off that the card's behavior changes well besides the ATR and communication parameters that it controls, depending on if cold or warm reset is used, perhaps for compatibility reasons with old terminals which expect a particular ATR and an application is selected by default on reset.
Therefore, it can happen that things do not work as on initial power-on after the card is reset, but appear to work as on power-on when the card has not been reset.
2) Not quite all ISO/IEC 7816-3 contact readers/drivers honor the three different parameters of<tt> SCardDisconnect </tt>correctly.
3) Things get even messier with contactless ISO/IEC 14443-4 readers and cards. One likely effect of<tt> SCardDisconnect(SCARD_RESET_CARD) </tt>or<tt> SCardDisconnect(SCARD_UNPOWER_CARD) </tt>(but hopefully not<tt> SCardDisconnect(SCARD_LEAVE_CARD) </tt>) is that the card will receive an S(DESELECT) request as defined by ISO/IEC 14443-4, which has an effect depending on the card. For a Java Card card, that should deselect the applet, with the notable effect that some of its transients variables: those allocated (e.g.) with<tt> makeTransientByteArray(CLEAR_ON_DESELECT) </tt>are cleared, but normally no those allocated with<tt> makeTransientByteArray(CLEAR_ON_RESET) </tt>. It is also possible that the card would be briefly powered off (and thus reset on next use), especially with<tt> SCardDisconnect(SCARD_UNPOWER_CARD) </tt>, but unfortunately that's not true with some common contactless readers/drivers.
4) It is further possible that the card is an NFC-enabled mobile phone running on its own battery, in which case an S(DESELECT) or interruption of the power transmitted by the contactless reader may or may not have an effect.
Thus at the end of the day, it is best not to depend on what the<tt> reset </tt> parameters does: it could do any of several things that it is supposed to do, for either values.
The simplest, most secure (with the current<tt> smartcardio </tt>), and (with the notable exception of cards with a warm reset state that significantly differ from their cold reset state) less likely to cause operational failure, is to use<tt> false </tt>as the<tt> reset </tt>parameter, so that the card (with the current<tt> smartcardio </tt>) is warm-reset on next use ; that's also what the official code example does.
But it would be unsafe to assume that the card is indeed reset, or/and the applet deselected, or/and its security context or its transients of any kind be cleared, for any value of <tt> reset </tt>. It also should not be assumed that the card has been reset on connect; an application/applet should be explicitly selected.