TkSmartCard transmitRequest persistently returning Cryptotokenkit error -2 on iOS/iPadOS

We are using the CryptoTokenKit framework, specifically the classes TKSmartCardSlotManager, TKSmartCardSlot, and TKSmartCard, to communicate with smart cards through external USB readers on iOS and iPadOS. In most cases, we are able to detect readers via TKSmartCardSlotManager, and send APDU commands using transmitRequest method, with the following code (where self->_slot and self->_card are previously created TkSmartCardSlot and TkSmartCard, respectively):

#import <CryptoTokenKit/CryptoTokenKit.h>

- (NSData *)sendCardCommand:(NSData *)command
{
    if (!self->_card || !self->_card.valid || self->_slot.state != TKSmartCardSlotStateValidCard)
        return nil;

    NSMutableData *res = [[NSMutableData alloc] init];
    NSError *sessionError = nil;

    [self->_card inSessionWithError:&sessionError executeBlock:^BOOL(NSError **error)
    {
        dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
        
        try {
            [self->_card transmitRequest:command reply:^(NSData * _Nullable response, NSError* _Nullable apduError)
            {
                if (apduError != nil)
                    self->_error = apduError;
                else
                    [res appendData: response];
                
                dispatch_semaphore_signal(semaphore);
            }];
        } catch (NSException *exception) {
            dispatch_semaphore_signal(semaphore);
        }
        
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        if (res.length == 0)
            return NO;

        return YES;
    }];

    return res;
}

However, with certain other USB smart card readers, we occasionally encounter APDU communication failures when calling transmitRequest (for instance, with a HID Global OMNIKEY 5422), which returns the following error: "Domain: CryptoTokenKit Code: -2". Once a failure occurs and transmitRequest starts returning this error, all subsequent calls to transmitRequest fail with the same error. This persists even when:

  • A different smart card is inserted
  • The same card is reinserted
  • A different USB reader (previously working correctly) is connected
  • The TKSmartCard object is recreated via makeSmartCard
  • The slot state changes (observed via KVO)
  • All internal objects (TKSmartCard, TKSmartCardSlot) are reset in the application

At this point, the system appears to be stuck in a non-recoverable state which affects all readers and cards, including those that were previously functioning correctly. The only way to recover from this state is terminating and restarting the application which is running the code. After restarting the app, everything works normally again.

We have created a bug report: FB22339746.

The issue has been reproduced on iOS 26.4 and 18.5. Also on iPadOS 18.1.

Anyone has already faced a similar issue? Could it be related to some internal state of TKSmartCardSlotManager?

Answered by DTS Engineer in 881963022

Thanks for bringing this to the forums.

returns the following error: "Domain: CryptoTokenKit Code: -2"

That is TKErrorCodeCommunicationError, aka TKError.Code.communicationError in Swift. This is a very generic error that basically means that something went wrong with… well… the communication with the smart card.

At this point, the system appears to be stuck in a non-recoverable state which affects all readers and cards

Yeah, that’s not good. This is clearly a bug and I appreciate you filing a bug report about it (FB22339746).

I took a look at your bug and noticed that you haven’t attached a sysdiagnose to it. Or, more accurately, it says that there’s an associated sysdiagnose log but it hasn’t finished uploading. Please run Feedback Assistant on the iOS device that captured the sysdiagnose log and check on its upload status. Alternatively, export the sysdiagnose log to your Mac and upload it from there.

Oh, and I think you already did this, but for the sake of anyone else following along on this thread, make sure that you install the CryptoTokenKit for iOS/iPadOS debug profile before capturing a sysdiagnose log for CryptoTokenKit issues. See our Bug Reporting > Profiles and Logs for more on that.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks for bringing this to the forums.

returns the following error: "Domain: CryptoTokenKit Code: -2"

That is TKErrorCodeCommunicationError, aka TKError.Code.communicationError in Swift. This is a very generic error that basically means that something went wrong with… well… the communication with the smart card.

At this point, the system appears to be stuck in a non-recoverable state which affects all readers and cards

Yeah, that’s not good. This is clearly a bug and I appreciate you filing a bug report about it (FB22339746).

I took a look at your bug and noticed that you haven’t attached a sysdiagnose to it. Or, more accurately, it says that there’s an associated sysdiagnose log but it hasn’t finished uploading. Please run Feedback Assistant on the iOS device that captured the sysdiagnose log and check on its upload status. Alternatively, export the sysdiagnose log to your Mac and upload it from there.

Oh, and I think you already did this, but for the sake of anyone else following along on this thread, make sure that you install the CryptoTokenKit for iOS/iPadOS debug profile before capturing a sysdiagnose log for CryptoTokenKit issues. See our Bug Reporting > Profiles and Logs for more on that.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you for the answer. The sysdiagnose log should be now completely uploaded to Feedback Assistant with the FB22339746 bug report.

TkSmartCard transmitRequest persistently returning Cryptotokenkit error -2 on iOS/iPadOS
 
 
Q