I'm developing a Java Card application and have suddenly had two cards stop working, both at the same time.
The cards are J3H081 Java Cards (Java Card 3.0.4, Global Platform 2.2.1) and I'm using both ACR122U and ACR1222L readers.
I had been successfully writing CAP files using GlobalPlatformPro to a card whilst testing, but on one instance it returned an error at the default app selection stage (unfortunately I no longer have the error).
I made a few further attempts at writing the CAP, then switched to the other card I have to (unfortunately, I have only two at the moment) to see if it was a card issue; GlobalPlatformPro reported the same problem for that card too.
I went back to the card application code and made a few changes to see if would help, and when I went to load the app back onto the card, the card wouldn't respond at all (i.e. GlobalPlatformPro reported no card present).
I then tried the other card and got the same result.
I've tried two different readers (as above), and each on two different machines, and get the same result.
On the ACR1222L, the cards only occasionally register on the RF (i.e. I get a beep), but OS cannot see the cards.
When placed on the ACR122U, the card beeps and LED turns green for a moment, but then back to red, and the OS cannot see the card. If I leave the card on the reader, it does this every ~20 seconds (as if it detects the card then fails). If I tap the card, then take it away, and then try to tap it again, it won't beep unless left for ~20 seconds.
MIFARE 1K and 4K cards continue to work as expected with both readers.
At this point, I would assume that it's the cards that have failed, but as it happened to both cards at the same time, I'm wondering if it's something I've done.
Could my app have broken the cards this badly?
EDIT
After some assistance and direction from @MaartenBodewes, I've discovered that the cards appear to be "muting".
I tried reading the cards from an embedded PN5180 reader on a Linux system, and get a bit further; The card will detect, and I can read the ATR using the NFC library supplied with the PN5180 (which I assume is using APDUs under the hood?). However, as soon as I try to send an APDU to the card, I get an error and then the card becomes undetectable again for >20 seconds.
Per the Sun "Java Card Applet Developer’s Guide":
There are a few conditions that cause the card to be blocked (or muted), preventing further use of the card. For example, a card might be blocked when an attempt to breach the card’s security is detected (by perhaps, the personal identification number (PIN) code being entered incorrectly more than five consecutive times). In this case, the issuer needs to be contacted (and the card may need to be returned) to reset the VM from such a blocked state.
Other info I've found whilst Googling suggests that card muting may be a temporal thing, ostensibly to impede brute force attacks on the card. This temporal muting is part of what I believe I am experiencing.
On Windows, I suspect that something like Smart Card Plug and Play tries to issue APDUs to the card which trigger the muting, which is why the card will not appear in Windows (though disabling SCPNP doesn't seem to help).
At this point, I cannot even communicate with GlobalPlatform to select the app, which is prior to any of my app code running.
I had been doing quite a few iterations of loading the app onto the card. The app version loaded immediately prior to the failure was working, and the next iteration installed OK, but GP failed to mark it as default, and it was never executed after that. The second card that has this issue never had the previous app on it, so it could not have been that, that caused it.
Based on some comments from @MichaelRoland, I did some reading about card tearing, and note that one of things mentioned in the context of power failure during transactions is the arrayCopyNonAtomic method, which is something new I introduced in the last version of my app. However, I don't believe a power failure was involved in this case.
Despite that version of the app having never been run on the card, is it possible that simply installing a CAP with this method in it could trigger something like this in GlobalPlatform?
EDIT 2
I've discovered a mistake I made in the install() method for the application that was loaded onto the card. On review, I had an array of size 32768, which I (now) understand would be truncated to zero.
I would have expected this to just fail, however, I did read somewhere that unhandled exceptions may be considered security violations that can lock the card. Though the card seems to only lock temporarily, so I'm not sure if/how it's being retriggered, or if it's even enough to cause this problem.
This leads to the question: could that app have loaded, yet failed to install (which is more or less what I witnessed with GP), and as it's not yet "installed", each time I try to access the card it tries to install the app, fails, and triggers a security violation?
I've tried finding more detailed information on the internals of the application installation and initialization process, but haven't much luck yet.