Assistance Needed: Accessing Smartcard Certificates for Document Signing on iOS

We are preparing to implement document signing using USB tokens on iOS and macOS. Several other applications already support this feature. From my testing and development efforts, I've been unable to reliably access or utilize certificates stored on a smartcard through the iOS APIs. Here are the specifics:

Environment

  • iOS: 15 and later
  • Xcode: Versions 18 and 26
  • Smartcard/Token: ePass 2003 (eMudhra), Feitien token (Capricorn)

Observed Issue :

  • The token is recognized at the system level, with certificates visible in Keychain Access.

  • However, programmatic access to the private keys on the smartcard from within the app is not working.

  • Signing attempts result in Error 6985 and CACC errors.

Approaches Tried:

Updated provisioning profiles with the following entitlements:

  • com.apple.developer.smartcard
  • com.apple.security.device.usb
  1. TKSmartCard
    • Employed TKSmartCard and TKSmartCardSession for interaction.
    • The token is detected successfully.
    • A session can be established, but there's no straightforward method to leverage it for certificate-based signing.
    • Access to signing functions is unavailable; operations yield Error 6985 or CACC errors.
if let smartCard = TKSmartCard(slot: someSlot) {
    smartCard.openSession { session, error in
        if let session = session {
            let command: [UInt8] = [0x00, 0xA4, 0x04, 0x00]
            session.transmit(Data(command)) { response, error in
                print("Response: \(String(describing: response))")
                print("Error: \(String(describing: error))")
            }
        }
    }
}
  1. TokenKit (macOS/iOS) - Utilized TKTokenWatcher to identify available tokens on macOS (not available on iOS).
watcher.setInsertionHandler { tokenID in
    print("Token detected: \(tokenID)")
}
  1. CryptoKit / Security Framework - Attempted to retrieve SecCertificate using SecItemCopyMatching queries, which succeeded on macOS but failed on iOS.
let query: [CFString: Any] = [
    kSecClass: kSecClassCertificate,
    kSecReturnRef: true,
    kSecMatchLimit: kSecMatchLimitAll
]

var items: CFTypeRef?
let status = SecItemCopyMatching(query as CFDictionary, &items)
print("Status: \(status)")  // macOS succeeds, iOS fails
  1. ExternalAccessory Framework (EAAccessory) * Investigated using EAAccessory and EASession for external token communication, but it did not function as expected.

This functionality is critical for my project. Has anyone successfully implemented smartcard-based signing on iOS? Any guidance, sample code, or references to relevant Apple documentation would be greatly appreciated.

Answered by DTS Engineer in 859365022
CryptoKit / Security Framework

Security framework is the right approach here. You can use TKTokenWatcher to learn about tokens coming and going, but to actually sign data with a digital identity on a token you need to use Security framework.

This is not super complex code, but there are some traps for the unwary. And, annoyingly, those traps are subtly different on iOS and macOS. I have a bunch of hints and tips in these threads:

Share and Enjoy

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

CryptoKit / Security Framework

Security framework is the right approach here. You can use TKTokenWatcher to learn about tokens coming and going, but to actually sign data with a digital identity on a token you need to use Security framework.

This is not super complex code, but there are some traps for the unwary. And, annoyingly, those traps are subtly different on iOS and macOS. I have a bunch of hints and tips in these threads:

Share and Enjoy

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

Assistance Needed: Accessing Smartcard Certificates for Document Signing on iOS
 
 
Q