From 3e53f193539e8336e185398aca1ceede1bcdac16 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 21 Aug 2026 13:03:57 +0200 Subject: [PATCH] fail rather than loop indefinitely on an unsuccessful card wait or repeated secure channel resets --- lark | 2 +- .../com/sparrowwallet/sparrow/io/ckcard/CkCardApi.java | 6 ++++-- .../sparrow/io/satochip/SatochipCommandSet.java | 8 ++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lark b/lark index f2b6b662..450758a0 160000 --- a/lark +++ b/lark @@ -1 +1 @@ -Subproject commit f2b6b6624752bf195d9d506f7ee07d2e65a90a03 +Subproject commit 450758a05e80fcc5c3a75131840f1884a06a4332 diff --git a/src/main/java/com/sparrowwallet/sparrow/io/ckcard/CkCardApi.java b/src/main/java/com/sparrowwallet/sparrow/io/ckcard/CkCardApi.java index 1e4e3475..06604980 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/ckcard/CkCardApi.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/ckcard/CkCardApi.java @@ -83,9 +83,11 @@ public class CkCardApi extends CardApi { delayProperty.set(delay); messageProperty.set("Auth delay, waiting " + delay + "s..."); CardWait cardWait = cardProtocol.authWait(); - if(cardWait.success) { - delay = cardWait.auth_delay == null ? 0 : cardWait.auth_delay.intValue(); + if(!cardWait.success) { + throw new CardException("Card did not accept the request to wait out the authentication delay."); } + + delay = cardWait.auth_delay == null ? 0 : cardWait.auth_delay.intValue(); } } } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/satochip/SatochipCommandSet.java b/src/main/java/com/sparrowwallet/sparrow/io/satochip/SatochipCommandSet.java index f931935d..af1ba148 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/satochip/SatochipCommandSet.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/satochip/SatochipCommandSet.java @@ -27,6 +27,8 @@ public class SatochipCommandSet { private static final Logger log = LoggerFactory.getLogger(SatochipCommandSet.class); + private static final int MAX_SECURE_CHANNEL_RESETS = 3; + private final SatoCardTransport cardTransport; private final SecureChannelSession secureChannel; private SatoCardStatus status; @@ -66,6 +68,7 @@ public class SatochipCommandSet { public APDUResponse cardTransmit(APDUCommand plainApdu) { // we try to transmit the APDU until we receive the answer or we receive an unrecoverable error boolean isApduTransmitted = false; + int secureChannelResets = 0; do { try { byte[] apduBytes = plainApdu.serialize(); @@ -114,6 +117,11 @@ public class SatochipCommandSet { // SecureChannel is not initialized else if(sw12 == 0x9C21) { log.error("Error, Satochip secure channel required"); + if(++secureChannelResets > MAX_SECURE_CHANNEL_RESETS) { + // the card keeps asking for a secure channel it will not accept, so stop rather than retry indefinitely + log.error("Error, Satochip secure channel could not be established"); + return new APDUResponse(new byte[0], (byte)0x00, (byte)0x00); + } secureChannel.resetSecureChannel(); } else { // cannot resolve issue at this point