CryptoTokenKit

RSS for tag

Access security tokens and the cryptographic assets they store using CryptoTokenKit.

Posts under CryptoTokenKit tag

18 Posts

Post

Replies

Boosts

Views

Activity

Security Resources
General: Forums topic: Privacy & Security Apple Platform Security support document Developer > Security Enabling enhanced security for your app documentation article Creating enhanced security helper extensions documentation article Security Audit Thoughts forums post Cryptography: Forums tags: Security, Apple CryptoKit Security framework documentation Apple CryptoKit framework documentation Common Crypto man pages — For the full list of pages, run: % man -k 3cc For more information about man pages, see Reading UNIX Manual Pages. On Cryptographic Key Formats forums post SecItem attributes for keys forums post CryptoCompatibility sample code Keychain: Forums tags: Security Security > Keychain Items documentation TN3137 On Mac keychain APIs and implementations SecItem Fundamentals forums post SecItem Pitfalls and Best Practices forums post Investigating hard-to-reproduce keychain problems forums post App ID Prefix Change and Keychain Access forums post Smart cards and other secure tokens: Forums tag: CryptoTokenKit CryptoTokenKit framework documentation Mac-specific resources: Forums tags: Security Foundation, Security Interface Security Foundation framework documentation Security Interface framework documentation BSD Privilege Escalation on macOS Related: Networking Resources — This covers high-level network security, including HTTPS and TLS. Network Extension Resources — This covers low-level network security, including VPN and content filters. Code Signing Resources Notarisation Resources Trusted Execution Resources — This includes Gatekeeper. App Sandbox Resources Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com"
0
0
3.8k
Nov ’25
TKTokenDriverConfiguration becomes permanently unusable after ctkd process restart
Background We're building a macOS application that acts as a CryptoTokenKit software token. The architecture follows the documented pattern: a container app (a long-running agent process) manages token registration and identity updates via TKTokenDriverConfiguration, and a separate appex extension process handles the actual signing operations for client sessions. What we're doing At agent startup, the container app calls [TKTokenDriverConfiguration driverConfigurations] to obtain our token driver, then registers a token instance ID: NSDictionary<TKTokenDriverClassID, TKTokenDriverConfiguration *> *driverConfigurations = [TKTokenDriverConfiguration driverConfigurations]; TKTokenDriverConfiguration driver = / first value from driverConfigurations */; [driver addTokenConfigurationForTokenInstanceID:@"setoken"]; When the agent renews a certificate, it pushes updated TKTokenKeychainItem objects to ctkd by setting keychainItems on the TKTokenConfiguration: TKTokenConfiguration *tokenCfg = driver.tokenConfigurations[@"setoken"]; tokenCfg.keychainItems = updatedItems; This works correctly during normal operation. The failure When ctkd is restarted (e.g., killall ctkd, or the system restarts the daemon), all subsequent calls through the existing TKTokenDriverConfiguration reference silently fail. Specifically: [TKTokenDriverConfiguration driverConfigurations] returns the same stale object - it does not establish a new connection to the newly-started ctkd process. There is no error, no exception, and no indication the returned object is invalid. driver.tokenConfigurations[@"setoken"] still returns a non-nil value reflecting the pre-restart state - so any nil check intended to detect "token not registered with ctkd" does not fire. [driver addTokenConfigurationForTokenInstanceID:@"setoken"] appears to succeed (no error) but the token is not actually registered with the new ctkd instance. Setting tokenCfg.keychainItems = updatedItems appears to succeed but the new ctkd instance has no knowledge of the update. The only reliable recovery we've found is restarting the container app process itself, at which point [TKTokenDriverConfiguration driverConfigurations] returns a fresh object connected to the new ctkd instance. What we've investigated There is no public API on TKTokenDriverConfiguration to invalidate or refresh the internal XPC connection to ctkd TKTokenWatcher can observe token insertions/removals, but we found no documented way to use it to detect a ctkd process restart specifically The NSXPCConnection invalidation handler pattern is not accessible through the TKTokenDriverConfiguration abstraction Moving credential management into the appex extension. Since the appex extension is recreated when the ctkd process restarts, we are able to update keychainItems from the extension. However, this comes with it's own set of problems: the extension is ephemeral and using the keychain APIs directly from the extension is not well documented and does not appear to be a supported pattern. Questions Is there a supported API to detect that ctkd has restarted and that the existing TKTokenDriverConfiguration reference is no longer valid? Is there a supported way to obtain a fresh TKTokenDriverConfiguration without restarting the container app? Should the container app be re-architected to avoid holding long-lived TKTokenDriverConfiguration references?
3
0
216
1d
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?
2
0
255
4d
How to write a persistent token to unlock FileVault with a smart card?
I want to write a CryptoTokenKit plugin to be used to unlock FileVault. I understand macOS already provides such a plugin for a PIV smart card https://support.apple.com/en-mz/guide/deployment/dep806850525/web Perfect. I want to do the same for a non-PIV smart card. So I have to provide my own CryptoTokenKit plugin. I already implemented a smart card plugin TKSmartCardToken. I can use it so pair the user with the smart card and use the smart card to login (except for the 1st login when the disk is still encrypted). As far as I understand for preboot I need to provide a "persistent token" https://support.apple.com/en-mz/guide/deployment/dep4e2622249/web From Xcode I created an empty application, and added a "Persistent Token Extension" (instead of a "Smart Card Token Extension"). After built I can see my new token in the output of "pluginkit -m -p com.apple.ctk-tokens". My questions: how and when is my plugin loaded? I added calls to os_log_error() in all the empty methods created by the Xcode template but I do not find my log messages in the console Apple provides a sample code for an old (2016) PIV token in https://developer.apple.com/library/archive/samplecode/PIVToken/Introduction/Intro.html Is the source code of the PIV token used at pre-boot also available? Thanks
2
0
73
5d
How to reset user preference for crypto token kit access
When an app is trying to access identities put in the keychain by cryptotokenkit extension, the user gets asked a permission pop-up which reads 'Token Access Request" would like access a token provided by: " with 2 options 'Don't allow' and 'OK' I accidently clicked "Don't allow" and now can't access identities put in crypto token kit. How can I reset the preference?
9
0
951
6d
How to store certificate to `com.apple.token` keychain access group.
I’m developing an iOS application and aiming to install a PKCS#12 (.p12) certificate into the com.apple.token keychain access group so that Microsoft Edge for iOS, managed via MDM/Intune, can read and use it for client certificate authentication. I’m attempting to save to the com.apple.token keychain access group, but I’m getting error -34018 (errSecMissingEntitlement) and the item isn’t saved. This occurs on both a physical device and the simulator. I’m using SecItemAdd from the Security framework to store it. Is this the correct approach? https://developer.apple.com/documentation/security/secitemadd(::) I have added com.apple.token to Keychain Sharing. I have also added com.apple.token to the app’s entitlements. Here is the code I’m using to observe this behavior: public static func installToTokenGroup(p12Data: Data, password: String) throws -> SecIdentity { // First, import the P12 to get the identity let options: [String: Any] = [ kSecImportExportPassphrase as String: password ] var items: CFArray? let importStatus = SecPKCS12Import(p12Data as CFData, options as CFDictionary, &items) guard importStatus == errSecSuccess, let array = items as? [[String: Any]], let dict = array.first else { throw NSError(domain: NSOSStatusErrorDomain, code: Int(importStatus), userInfo: [NSLocalizedDescriptionKey: "Failed to import P12: \(importStatus)"]) } let identity = dict[kSecImportItemIdentity as String] as! SecIdentity let addQuery: [String: Any] = [ kSecClass as String: kSecClassIdentity, kSecValueRef as String: identity, kSecAttrLabel as String: kSecAttrAccessGroupToken, kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock, kSecAttrAccessGroup as String: kSecAttrAccessGroupToken ] let status = SecItemAdd(addQuery as CFDictionary, nil) if status != errSecSuccess && status != errSecDuplicateItem { throw NSError(domain: NSOSStatusErrorDomain, code: Int(status), userInfo: [NSLocalizedDescriptionKey: "Failed to add to token group: \(status)"]) } return identity }
1
0
221
1w
Securing code signing ceritifcates in the secure enclave
I am on a mission to secure our key material for our iOS app's code signing certificate. My first endeavor with storing the code signing certificate on a YubiKey is a marginal success - it seems that with a pin policy that requires entering the PIN at least once we must enter the PIN umpteen times per build. Creating a certificate with a policy of never would be ill-advised. On the other hand, we could chose to store the code signing certificate in the Secure Enclave. However, it seems that I am only allowed to create eliptic curve private keys and not RSA keys in the secure enclave. When I attempt to upload a certificate signing request to AppStoreConnect, I am told that only an RSA2048 key will do. What I am after is a way to authenticate access to the certificate once per boot so that we can make multiple builds per day without manual intervention whilst also ensuring that the key material is not stored on disk. A yubikey would be preferable, but I am fine with the secure enclave if need be. Is there a way to achieve this? Best regards, Emīls
1
0
193
Feb ’26
Get identities from a smart card in an authorization plugin
Hello, I’m working on an authorization plugin which allows users to login and unlock their computer with various methods like a FIDO key. I need to add smart cards support to it. If I understand correctly, I need to construct a URLCredential object with the identity from the smart card and pass it to the completion handler of URLSessionDelegate.urlSession(_:didReceive:completionHandler:) method. I’ve read the documentation at Using Cryptographic Assets Stored on a Smart Card, TN3137: On Mac keychain APIs and implementations, and SecItem: Pitfalls and Best Practices and created a simple code that reads the identities from the keychain: CFArrayRef identities = nil; OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)@{ (id)kSecClass: (id)kSecClassIdentity, (id)kSecMatchLimit: (id)kSecMatchLimitAll, (id)kSecReturnRef: @YES, }, (CFTypeRef *)&identities); if (status == errSecSuccess && identities) { os_log(OS_LOG_DEFAULT, "Found identities: %{public}ld\n", CFArrayGetCount(identities)); } else { os_log(OS_LOG_DEFAULT, "Error: %{public}ld\n", (long)status); } When I use this code in a simple demo app, it finds my Yubikey identities without problem. When I use it in my authorization plugin, it doesn’t find anything in system.login.console right and finds Yubikey in authenticate right only if I register my plugin as non-,privileged. I tried modifying the query in various ways, in particular by using SecKeychainCopyDomainSearchList with the domain kSecPreferencesDomainDynamic and adding it to the query as kSecMatchSearchList and trying other SecKeychain* methods, but ended up with nothing. I concluded that the identities from a smart card are being added to the data protection keychain rather than to a file based keychain and since I’m working in a privileged context, I won’t be able to get them. If this is indeed the case, could you please advise how to proceed? Thanks in advance.
12
0
2.6k
Jan ’26
Persistent Tokens for Keychain Unlock in Platform SSO
While working with Platform SSO on macOS, I’m trying to better understand how the system handles cases where a user’s local account password becomes unsynchronized with their Identity Provider (IdP) password—for example, when the device is offline during a password change. My assumption is that macOS may store some form of persistent token during the Platform SSO user registration process (such as a certificate or similar credential), and that this token could allow the system to unlock the user’s login keychain even if the local password no longer matches the IdP password. I’m hoping to get clarification on the following: Does macOS actually use a persistent token to unlock the login keychain when the local account password is out of sync with the IdP password? If so, how is that mechanism designed to work? If such a capability exists, is it something developers can leverage to enable a true passwordless authentication experience at the login window and lock screen (i.e., avoiding the need for a local password fallback)? I’m trying to confirm what macOS officially supports so I can understand whether passwordless login is achievable using the persistent-token approach. Thanks in advance for any clarification.
1
3
293
Dec ’25
CryptoTokenKit: TKSmartCardSlotManager.default is nil on macOS (Designed for iPad) but works on iPadOS and macOS
I have an iOS/iPadOS app and 'm trying to communicate with usb smart card reader using CryptoTokenKit on all platforms (ios/ipados/macos). Minimal Repro Code import CryptoTokenKit import SwiftUI struct ContentView: View { @State var status = "" var body: some View { VStack { Text("Status: \(status)") } .padding() .onAppear { let manager = TKSmartCardSlotManager.default if manager != nil { status = "Initialized" } else { status = "Unsupported" } } } } And my entitlement file has only one key: com.apple.security.smartcard = YES Behavior • iPadOS (on device): status = "Initialized" ✅ • macOS (native macOS app, with the required CryptoTokenKit entitlement): status = "Initialized" ✅ • macOS (Designed for iPad, regardless of CryptoTokenKit entitlement): status = "Unsupported" → TKSmartCardSlotManager.default is nil ❌ Expectation Given that the same iPadOS build initializes TKSmartCardSlotManager, I expected the iPad app running in Designed for iPad mode on Apple silicon Mac to behave the same (or to have a documented limitation). Questions Is CryptoTokenKit (and specifically TKSmartCardSlotManager) supported for iPad apps running on Mac in Designed for iPad mode? If support exists, what entitlements / capabilities are required for USB smart-card access in this configuration? If not supported, is Mac Catalyst the correct/only path on macOS to access USB smart-card readers via CryptoTokenKit? Are there recommended alternatives for iPad apps on Mac (Designed for iPad) to communicate with USB smart-card readers (e.g., ExternalAccessory, DriverKit, etc.), or is this scenario intentionally unsupported? Thanks!
2
0
239
Nov ’25
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 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))") } } } } TokenKit (macOS/iOS) - Utilized TKTokenWatcher to identify available tokens on macOS (not available on iOS). watcher.setInsertionHandler { tokenID in print("Token detected: \(tokenID)") } 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 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.
3
0
297
Nov ’25
Use CCID interface instead of CryptoTokenKit API
Hi, Is it possible for a macOS (or iOS/ipadOS) app to communicate with a CCID-compliant reader using the CCID interface (i.e., directly sending the PC_TO_RDR_* messages) instead of using the CryptoTokenKit API? Apple's CCID driver (/System/Library/CryptoTokenKit/usbsmartcardreaderd.slotd) seems to support all the PC_TO_RDR and RDR_TO_PC messages: https://blog.apdu.fr/posts/2023/11/apple-own-ccid-driver-in-sonoma/#enable-my-ccid-driver The background for this question is that we develop smartcard products and we'd like to use the finer grained settings provided by the CCID specification for testing/demo purposes. Thank you.
1
0
136
Oct ’25
Swift iOS iPadOS app for Smartcard Token PIV using CryptoTokenKit
Please excuse my lack of understanding of what are probably fundamental concepts in iOS/iPadOS development but I have searched far and wide for documentation and haven't had much luck so far. I am not sure that what I want to do is even possible with an iPad iPadOS app. Goals: Develop a Swift iPadOS app that can digitally sign a file using a PIV SmartCard/Token (Personal Identity Verification Card): Insert a PIV SmartCard/Token (such as a Yubikey 5Ci) into the lightning port of an iPadOS device iPad (NOT MacOS) Interface with the SmartCard/Token to access the user's PIV certificate/signature and "use it" to sign a file Question 1: How to get the PIV Certificate from SmartCard/Token/Yubikey into iPadOS keychain?   * Do we need to get the PIV certificate into the iOS keychain? Is there another way to interact with a SmartCard directly?   * This should prompt the user for their PIN? Question 2: How to get our Swift app to hook into the event that the SmartCard/Token is inserted into the device and then interface with the user's certificate?   * When is the user prompted to enter their PIN for SmartCard/Token/Yubikey?   * Do we need to use CyrptoTokenKit to interface with a smartcard inserted into the lightning port of an iOS device?
14
1
3.9k
Sep ’25
Yubikey Authentication iPad/iOS26
Hey all, Question for the masses.... Does the Yubikey authentication have a OS dependency and it only works with a stable, public OS? Does Azure/Okta/Yubikey beta OS26? My CEO installed iPadOS 26 on his iPad and was not able to authenticate via Yubikey into our company environment. I ran the same scenario on my iPad using iPadOS 26 and I had the same results. Downgrading to iPAdOS doesn't pose these issues. I'm assuming something isn't fine-tuned yet?
1
1
419
Aug ’25
Accessing PIV Smart Card Certificates from iPadOS application.
I am new to swift development, and it's possible that I'm missing something fundamental/obvious. If so, I apologize in advance. My team is developing an application for iPadOS using SwiftUI, and I'm trying to accomplish something similar to what the original inquirer is asking for in this thread: https://developer.apple.com/forums/thread/725152. The only difference is that I'm trying to use a PIV smart card to achieve authentication to a server rather than digitally sign a document. Unfortunately, I'm getting stuck when attempting to run the list() function provided in the accepted answer to the post mentioned above. When attempting to call SecItemCopyMatching(), I'm getting a -34018 missing entitlement error. I've attempted to add the com.apple.token to my app's keychain-access-groups entitlements, but this does not resolve the issue. I have checked the entitlements in my built app, per the recommendation in the troubleshooting guide here: https://developer.apple.com/forums/thread/114456. The entitlement for com.apple.token is indeed present in the plist. Based on other documentation I've read, however, it seems that the explicit declaration of com.apple.token should not even be required in the entitlements. Is there something obvious that I'm missing here that would prevent my app from accessing the token access group?
5
0
241
Jul ’25
Integrating CryptoTokenKit with productsign
Hi all, I'm using a CryptoTokenKit (CTK) extension to perform code signing without having the private key stored on my laptop. The extension currently only supports the rsaSignatureDigestPKCS1v15SHA256 algorithm: func tokenSession(_ session: TKTokenSession, supports operation: TKTokenOperation, keyObjectID: TKToken.ObjectID, algorithm: TKTokenKeyAlgorithm) -> Bool { return algorithm.isAlgorithm(SecKeyAlgorithm.rsaSignatureDigestPKCS1v15SHA256) } This setup works perfectly with codesign, and signing completes without any issues. However, when I try to use productsign, the system correctly detects and delegates signing to my CTK extension, but it seems to always request rsaSignatureDigestPKCS1v15SHA1 instead: productsign --timestamp --sign <identity> unsigned.pkg signed.pkg productsign: using timestamp authority for signature productsign: signing product with identity "Developer ID Installer: <org> (<team>)" from keychain (null) ... Error Domain=NSOSStatusErrorDomain Code=-50 "algid:sign:RSA:digest-PKCS1v15:SHA1: algorithm not supported by the key" ... productsign: error: Failed to sign the product. From what I understand, older versions of macOS used SHA1 for code signing, but codesign has since moved to SHA256 (at least when legacy compatibility isn't a concern). Oddly, productsign still seems to default to SHA1, even in 2025. Is there a known way to force productsign to use SHA256 instead of SHA1 for the signature digest algorithm? Or is there some flag or configuration I'm missing? Thanks in advance!
7
0
626
Jun ’25
SecKeyCreateDecryptedDataWithParameters always fails with algo not supported
Attempting to DECRYPT a cipher message using the Apple API SecKeyCreateDecryptedData(privateKey, .rsaEncryptionOAEPSHA256, encryptedMessage). Decryption ALWAYS fails for every algorithm. SecKeyCreateDecryptedDataWithParameters Error: `Domain=NSOSStatusErrorDomain Code=-50 "algid:encrypt:RSA:OAEP:SHA256: algorithm not supported by the key &lt;SecKeyRef:('com.yubico.Authenticator.TokenExtension:5621CDF8560D4C412030886584EC4C9E394CC376DD9738B0CCBB51924FC26EB6') 0x3007fd150&gt;" UserInfo={numberOfErrorsDeep=0, NSDescription=algid:encrypt:RSA:OAEP:SHA256: algorithm not supported by the key &lt;SecKeyRef:('com.yubico.Authenticator.TokenExtension:5621CDF8560D4C412030886584EC4C9E394CC376DD9738B0CCBB51924FC26EB6') 0x3007fd150&gt;}` Decryption failed: SecKeyCreateDecryptedData returned nil. Error: One or more parameters passed to a function were not valid. When checking with SecKeyIsAlgorithmSupported(privateKey, .decrypt, &lt;ANYalgorithm&gt;) all algorithms fail. Btw - The privateKey does support decryption when retrieving the attributes. Important to know: The private key is a reference to an external private key placed in the iOS Keychain via a 3rd party CryptoTokenKit Extension app. When I perform, the SecKeyCreateSignature(...) and pass in the SAME privateKey reference, the OS automatically calls the 3rd party app to perform a successful signing with the private key that reside on a YubiKey. Here's my code for obtaining the private key reference from an Identity: func getKeyPairFromIdentity() -&gt; (privateKey: SecKey, publicKey: SecKey)? { let query = NSDictionary( dictionary: [ kSecClass as String: kSecClassIdentity, kSecAttrTokenID as String: self.tokenID!, kSecReturnRef as String: kCFBooleanTrue as Any ] ) var identityRef: CFTypeRef? let status = SecItemCopyMatching(query, &amp;identityRef) if status == errSecSuccess, let identity = identityRef { var privateKeyRef: SecKey? let keyStatus = SecIdentityCopyPrivateKey(identity as! SecIdentity, &amp;privateKeyRef) if keyStatus == errSecSuccess, let privateKey = privateKeyRef { let publicKey = SecKeyCopyPublicKey(privateKey) if let publicKey = publicKey { print("Private and public keys extracted successfully.") return (privateKey, publicKey) } else { print("Failed to extract public key from private key.") return nil } } else { print("SecIdentityCopyPrivateKey: Private key not found error: \(keyStatus)") return nil } } else { print("SecIdentity not found or error: \(status)") return nil } }
4
0
270
Apr ’25
TKTokenSession not used
Hi, I'm working on developing my own CryptoTokenKit (CTK) extension to enable codesign with HSM-backed keys. Here's what I’ve done so far: The container app sets up the tokenConfiguration with TKTokenKeychainCertificate and TKTokenKeychainKey. The extension registers successfully and is visible via pluginkit when launching the container app. The virtual smartcard appears when running security list-smartcards. The certificate, key, and identity are all visible using security export-smartcard -i [card]. However, nothing appears in the Keychain. After adding logging and reviewing output in the Console, I’ve observed the following behavior when running codesign: My TKTokenSession is instantiated correctly, using my custom TKToken implementation — so far, so good. However, none of the following TKTokenSession methods are ever called: func tokenSession(_ session: TKTokenSession, beginAuthFor operation: TKTokenOperation, constraint: Any) throws -> TKTokenAuthOperation func tokenSession(_ session: TKTokenSession, supports operation: TKTokenOperation, keyObjectID: TKToken.ObjectID, algorithm: TKTokenKeyAlgorithm) -> Bool func tokenSession(_ session: TKTokenSession, sign dataToSign: Data, keyObjectID: Any, algorithm: TKTokenKeyAlgorithm) throws -> Data func tokenSession(_ session: TKTokenSession, decrypt ciphertext: Data, keyObjectID: Any, algorithm: TKTokenKeyAlgorithm) throws -> Data func tokenSession(_ session: TKTokenSession, performKeyExchange otherPartyPublicKeyData: Data, keyObjectID objectID: Any, algorithm: TKTokenKeyAlgorithm, parameters: TKTokenKeyExchangeParameters) throws -> Data The only relevant Console log is: default 11:31:15.453969+0200 PersistentToken [0x154d04850] invalidated because the client process (pid 4899) either cancelled the connection or exited There’s no crash report related to the extension, so my assumption is that ctkd is closing the connection for some unknown reason. Is there any way to debug this further? Thank you for your help.
3
0
147
Apr ’25
Security Resources
General: Forums topic: Privacy & Security Apple Platform Security support document Developer > Security Enabling enhanced security for your app documentation article Creating enhanced security helper extensions documentation article Security Audit Thoughts forums post Cryptography: Forums tags: Security, Apple CryptoKit Security framework documentation Apple CryptoKit framework documentation Common Crypto man pages — For the full list of pages, run: % man -k 3cc For more information about man pages, see Reading UNIX Manual Pages. On Cryptographic Key Formats forums post SecItem attributes for keys forums post CryptoCompatibility sample code Keychain: Forums tags: Security Security > Keychain Items documentation TN3137 On Mac keychain APIs and implementations SecItem Fundamentals forums post SecItem Pitfalls and Best Practices forums post Investigating hard-to-reproduce keychain problems forums post App ID Prefix Change and Keychain Access forums post Smart cards and other secure tokens: Forums tag: CryptoTokenKit CryptoTokenKit framework documentation Mac-specific resources: Forums tags: Security Foundation, Security Interface Security Foundation framework documentation Security Interface framework documentation BSD Privilege Escalation on macOS Related: Networking Resources — This covers high-level network security, including HTTPS and TLS. Network Extension Resources — This covers low-level network security, including VPN and content filters. Code Signing Resources Notarisation Resources Trusted Execution Resources — This includes Gatekeeper. App Sandbox Resources Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com"
Replies
0
Boosts
0
Views
3.8k
Activity
Nov ’25
TKTokenDriverConfiguration becomes permanently unusable after ctkd process restart
Background We're building a macOS application that acts as a CryptoTokenKit software token. The architecture follows the documented pattern: a container app (a long-running agent process) manages token registration and identity updates via TKTokenDriverConfiguration, and a separate appex extension process handles the actual signing operations for client sessions. What we're doing At agent startup, the container app calls [TKTokenDriverConfiguration driverConfigurations] to obtain our token driver, then registers a token instance ID: NSDictionary<TKTokenDriverClassID, TKTokenDriverConfiguration *> *driverConfigurations = [TKTokenDriverConfiguration driverConfigurations]; TKTokenDriverConfiguration driver = / first value from driverConfigurations */; [driver addTokenConfigurationForTokenInstanceID:@"setoken"]; When the agent renews a certificate, it pushes updated TKTokenKeychainItem objects to ctkd by setting keychainItems on the TKTokenConfiguration: TKTokenConfiguration *tokenCfg = driver.tokenConfigurations[@"setoken"]; tokenCfg.keychainItems = updatedItems; This works correctly during normal operation. The failure When ctkd is restarted (e.g., killall ctkd, or the system restarts the daemon), all subsequent calls through the existing TKTokenDriverConfiguration reference silently fail. Specifically: [TKTokenDriverConfiguration driverConfigurations] returns the same stale object - it does not establish a new connection to the newly-started ctkd process. There is no error, no exception, and no indication the returned object is invalid. driver.tokenConfigurations[@"setoken"] still returns a non-nil value reflecting the pre-restart state - so any nil check intended to detect "token not registered with ctkd" does not fire. [driver addTokenConfigurationForTokenInstanceID:@"setoken"] appears to succeed (no error) but the token is not actually registered with the new ctkd instance. Setting tokenCfg.keychainItems = updatedItems appears to succeed but the new ctkd instance has no knowledge of the update. The only reliable recovery we've found is restarting the container app process itself, at which point [TKTokenDriverConfiguration driverConfigurations] returns a fresh object connected to the new ctkd instance. What we've investigated There is no public API on TKTokenDriverConfiguration to invalidate or refresh the internal XPC connection to ctkd TKTokenWatcher can observe token insertions/removals, but we found no documented way to use it to detect a ctkd process restart specifically The NSXPCConnection invalidation handler pattern is not accessible through the TKTokenDriverConfiguration abstraction Moving credential management into the appex extension. Since the appex extension is recreated when the ctkd process restarts, we are able to update keychainItems from the extension. However, this comes with it's own set of problems: the extension is ephemeral and using the keychain APIs directly from the extension is not well documented and does not appear to be a supported pattern. Questions Is there a supported API to detect that ctkd has restarted and that the existing TKTokenDriverConfiguration reference is no longer valid? Is there a supported way to obtain a fresh TKTokenDriverConfiguration without restarting the container app? Should the container app be re-architected to avoid holding long-lived TKTokenDriverConfiguration references?
Replies
3
Boosts
0
Views
216
Activity
1d
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?
Replies
2
Boosts
0
Views
255
Activity
4d
How to write a persistent token to unlock FileVault with a smart card?
I want to write a CryptoTokenKit plugin to be used to unlock FileVault. I understand macOS already provides such a plugin for a PIV smart card https://support.apple.com/en-mz/guide/deployment/dep806850525/web Perfect. I want to do the same for a non-PIV smart card. So I have to provide my own CryptoTokenKit plugin. I already implemented a smart card plugin TKSmartCardToken. I can use it so pair the user with the smart card and use the smart card to login (except for the 1st login when the disk is still encrypted). As far as I understand for preboot I need to provide a "persistent token" https://support.apple.com/en-mz/guide/deployment/dep4e2622249/web From Xcode I created an empty application, and added a "Persistent Token Extension" (instead of a "Smart Card Token Extension"). After built I can see my new token in the output of "pluginkit -m -p com.apple.ctk-tokens". My questions: how and when is my plugin loaded? I added calls to os_log_error() in all the empty methods created by the Xcode template but I do not find my log messages in the console Apple provides a sample code for an old (2016) PIV token in https://developer.apple.com/library/archive/samplecode/PIVToken/Introduction/Intro.html Is the source code of the PIV token used at pre-boot also available? Thanks
Replies
2
Boosts
0
Views
73
Activity
5d
How to reset user preference for crypto token kit access
When an app is trying to access identities put in the keychain by cryptotokenkit extension, the user gets asked a permission pop-up which reads 'Token Access Request" would like access a token provided by: " with 2 options 'Don't allow' and 'OK' I accidently clicked "Don't allow" and now can't access identities put in crypto token kit. How can I reset the preference?
Replies
9
Boosts
0
Views
951
Activity
6d
How to store certificate to `com.apple.token` keychain access group.
I’m developing an iOS application and aiming to install a PKCS#12 (.p12) certificate into the com.apple.token keychain access group so that Microsoft Edge for iOS, managed via MDM/Intune, can read and use it for client certificate authentication. I’m attempting to save to the com.apple.token keychain access group, but I’m getting error -34018 (errSecMissingEntitlement) and the item isn’t saved. This occurs on both a physical device and the simulator. I’m using SecItemAdd from the Security framework to store it. Is this the correct approach? https://developer.apple.com/documentation/security/secitemadd(::) I have added com.apple.token to Keychain Sharing. I have also added com.apple.token to the app’s entitlements. Here is the code I’m using to observe this behavior: public static func installToTokenGroup(p12Data: Data, password: String) throws -> SecIdentity { // First, import the P12 to get the identity let options: [String: Any] = [ kSecImportExportPassphrase as String: password ] var items: CFArray? let importStatus = SecPKCS12Import(p12Data as CFData, options as CFDictionary, &items) guard importStatus == errSecSuccess, let array = items as? [[String: Any]], let dict = array.first else { throw NSError(domain: NSOSStatusErrorDomain, code: Int(importStatus), userInfo: [NSLocalizedDescriptionKey: "Failed to import P12: \(importStatus)"]) } let identity = dict[kSecImportItemIdentity as String] as! SecIdentity let addQuery: [String: Any] = [ kSecClass as String: kSecClassIdentity, kSecValueRef as String: identity, kSecAttrLabel as String: kSecAttrAccessGroupToken, kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock, kSecAttrAccessGroup as String: kSecAttrAccessGroupToken ] let status = SecItemAdd(addQuery as CFDictionary, nil) if status != errSecSuccess && status != errSecDuplicateItem { throw NSError(domain: NSOSStatusErrorDomain, code: Int(status), userInfo: [NSLocalizedDescriptionKey: "Failed to add to token group: \(status)"]) } return identity }
Replies
1
Boosts
0
Views
221
Activity
1w
Securing code signing ceritifcates in the secure enclave
I am on a mission to secure our key material for our iOS app's code signing certificate. My first endeavor with storing the code signing certificate on a YubiKey is a marginal success - it seems that with a pin policy that requires entering the PIN at least once we must enter the PIN umpteen times per build. Creating a certificate with a policy of never would be ill-advised. On the other hand, we could chose to store the code signing certificate in the Secure Enclave. However, it seems that I am only allowed to create eliptic curve private keys and not RSA keys in the secure enclave. When I attempt to upload a certificate signing request to AppStoreConnect, I am told that only an RSA2048 key will do. What I am after is a way to authenticate access to the certificate once per boot so that we can make multiple builds per day without manual intervention whilst also ensuring that the key material is not stored on disk. A yubikey would be preferable, but I am fine with the secure enclave if need be. Is there a way to achieve this? Best regards, Emīls
Replies
1
Boosts
0
Views
193
Activity
Feb ’26
Get identities from a smart card in an authorization plugin
Hello, I’m working on an authorization plugin which allows users to login and unlock their computer with various methods like a FIDO key. I need to add smart cards support to it. If I understand correctly, I need to construct a URLCredential object with the identity from the smart card and pass it to the completion handler of URLSessionDelegate.urlSession(_:didReceive:completionHandler:) method. I’ve read the documentation at Using Cryptographic Assets Stored on a Smart Card, TN3137: On Mac keychain APIs and implementations, and SecItem: Pitfalls and Best Practices and created a simple code that reads the identities from the keychain: CFArrayRef identities = nil; OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)@{ (id)kSecClass: (id)kSecClassIdentity, (id)kSecMatchLimit: (id)kSecMatchLimitAll, (id)kSecReturnRef: @YES, }, (CFTypeRef *)&identities); if (status == errSecSuccess && identities) { os_log(OS_LOG_DEFAULT, "Found identities: %{public}ld\n", CFArrayGetCount(identities)); } else { os_log(OS_LOG_DEFAULT, "Error: %{public}ld\n", (long)status); } When I use this code in a simple demo app, it finds my Yubikey identities without problem. When I use it in my authorization plugin, it doesn’t find anything in system.login.console right and finds Yubikey in authenticate right only if I register my plugin as non-,privileged. I tried modifying the query in various ways, in particular by using SecKeychainCopyDomainSearchList with the domain kSecPreferencesDomainDynamic and adding it to the query as kSecMatchSearchList and trying other SecKeychain* methods, but ended up with nothing. I concluded that the identities from a smart card are being added to the data protection keychain rather than to a file based keychain and since I’m working in a privileged context, I won’t be able to get them. If this is indeed the case, could you please advise how to proceed? Thanks in advance.
Replies
12
Boosts
0
Views
2.6k
Activity
Jan ’26
Persistent Tokens for Keychain Unlock in Platform SSO
While working with Platform SSO on macOS, I’m trying to better understand how the system handles cases where a user’s local account password becomes unsynchronized with their Identity Provider (IdP) password—for example, when the device is offline during a password change. My assumption is that macOS may store some form of persistent token during the Platform SSO user registration process (such as a certificate or similar credential), and that this token could allow the system to unlock the user’s login keychain even if the local password no longer matches the IdP password. I’m hoping to get clarification on the following: Does macOS actually use a persistent token to unlock the login keychain when the local account password is out of sync with the IdP password? If so, how is that mechanism designed to work? If such a capability exists, is it something developers can leverage to enable a true passwordless authentication experience at the login window and lock screen (i.e., avoiding the need for a local password fallback)? I’m trying to confirm what macOS officially supports so I can understand whether passwordless login is achievable using the persistent-token approach. Thanks in advance for any clarification.
Replies
1
Boosts
3
Views
293
Activity
Dec ’25
CryptoTokenKit: TKSmartCardSlotManager.default is nil on macOS (Designed for iPad) but works on iPadOS and macOS
I have an iOS/iPadOS app and 'm trying to communicate with usb smart card reader using CryptoTokenKit on all platforms (ios/ipados/macos). Minimal Repro Code import CryptoTokenKit import SwiftUI struct ContentView: View { @State var status = "" var body: some View { VStack { Text("Status: \(status)") } .padding() .onAppear { let manager = TKSmartCardSlotManager.default if manager != nil { status = "Initialized" } else { status = "Unsupported" } } } } And my entitlement file has only one key: com.apple.security.smartcard = YES Behavior • iPadOS (on device): status = "Initialized" ✅ • macOS (native macOS app, with the required CryptoTokenKit entitlement): status = "Initialized" ✅ • macOS (Designed for iPad, regardless of CryptoTokenKit entitlement): status = "Unsupported" → TKSmartCardSlotManager.default is nil ❌ Expectation Given that the same iPadOS build initializes TKSmartCardSlotManager, I expected the iPad app running in Designed for iPad mode on Apple silicon Mac to behave the same (or to have a documented limitation). Questions Is CryptoTokenKit (and specifically TKSmartCardSlotManager) supported for iPad apps running on Mac in Designed for iPad mode? If support exists, what entitlements / capabilities are required for USB smart-card access in this configuration? If not supported, is Mac Catalyst the correct/only path on macOS to access USB smart-card readers via CryptoTokenKit? Are there recommended alternatives for iPad apps on Mac (Designed for iPad) to communicate with USB smart-card readers (e.g., ExternalAccessory, DriverKit, etc.), or is this scenario intentionally unsupported? Thanks!
Replies
2
Boosts
0
Views
239
Activity
Nov ’25
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 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))") } } } } TokenKit (macOS/iOS) - Utilized TKTokenWatcher to identify available tokens on macOS (not available on iOS). watcher.setInsertionHandler { tokenID in print("Token detected: \(tokenID)") } 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 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.
Replies
3
Boosts
0
Views
297
Activity
Nov ’25
Use CCID interface instead of CryptoTokenKit API
Hi, Is it possible for a macOS (or iOS/ipadOS) app to communicate with a CCID-compliant reader using the CCID interface (i.e., directly sending the PC_TO_RDR_* messages) instead of using the CryptoTokenKit API? Apple's CCID driver (/System/Library/CryptoTokenKit/usbsmartcardreaderd.slotd) seems to support all the PC_TO_RDR and RDR_TO_PC messages: https://blog.apdu.fr/posts/2023/11/apple-own-ccid-driver-in-sonoma/#enable-my-ccid-driver The background for this question is that we develop smartcard products and we'd like to use the finer grained settings provided by the CCID specification for testing/demo purposes. Thank you.
Replies
1
Boosts
0
Views
136
Activity
Oct ’25
Swift iOS iPadOS app for Smartcard Token PIV using CryptoTokenKit
Please excuse my lack of understanding of what are probably fundamental concepts in iOS/iPadOS development but I have searched far and wide for documentation and haven't had much luck so far. I am not sure that what I want to do is even possible with an iPad iPadOS app. Goals: Develop a Swift iPadOS app that can digitally sign a file using a PIV SmartCard/Token (Personal Identity Verification Card): Insert a PIV SmartCard/Token (such as a Yubikey 5Ci) into the lightning port of an iPadOS device iPad (NOT MacOS) Interface with the SmartCard/Token to access the user's PIV certificate/signature and "use it" to sign a file Question 1: How to get the PIV Certificate from SmartCard/Token/Yubikey into iPadOS keychain?   * Do we need to get the PIV certificate into the iOS keychain? Is there another way to interact with a SmartCard directly?   * This should prompt the user for their PIN? Question 2: How to get our Swift app to hook into the event that the SmartCard/Token is inserted into the device and then interface with the user's certificate?   * When is the user prompted to enter their PIN for SmartCard/Token/Yubikey?   * Do we need to use CyrptoTokenKit to interface with a smartcard inserted into the lightning port of an iOS device?
Replies
14
Boosts
1
Views
3.9k
Activity
Sep ’25
Yubikey Authentication iPad/iOS26
Hey all, Question for the masses.... Does the Yubikey authentication have a OS dependency and it only works with a stable, public OS? Does Azure/Okta/Yubikey beta OS26? My CEO installed iPadOS 26 on his iPad and was not able to authenticate via Yubikey into our company environment. I ran the same scenario on my iPad using iPadOS 26 and I had the same results. Downgrading to iPAdOS doesn't pose these issues. I'm assuming something isn't fine-tuned yet?
Replies
1
Boosts
1
Views
419
Activity
Aug ’25
Accessing PIV Smart Card Certificates from iPadOS application.
I am new to swift development, and it's possible that I'm missing something fundamental/obvious. If so, I apologize in advance. My team is developing an application for iPadOS using SwiftUI, and I'm trying to accomplish something similar to what the original inquirer is asking for in this thread: https://developer.apple.com/forums/thread/725152. The only difference is that I'm trying to use a PIV smart card to achieve authentication to a server rather than digitally sign a document. Unfortunately, I'm getting stuck when attempting to run the list() function provided in the accepted answer to the post mentioned above. When attempting to call SecItemCopyMatching(), I'm getting a -34018 missing entitlement error. I've attempted to add the com.apple.token to my app's keychain-access-groups entitlements, but this does not resolve the issue. I have checked the entitlements in my built app, per the recommendation in the troubleshooting guide here: https://developer.apple.com/forums/thread/114456. The entitlement for com.apple.token is indeed present in the plist. Based on other documentation I've read, however, it seems that the explicit declaration of com.apple.token should not even be required in the entitlements. Is there something obvious that I'm missing here that would prevent my app from accessing the token access group?
Replies
5
Boosts
0
Views
241
Activity
Jul ’25
Integrating CryptoTokenKit with productsign
Hi all, I'm using a CryptoTokenKit (CTK) extension to perform code signing without having the private key stored on my laptop. The extension currently only supports the rsaSignatureDigestPKCS1v15SHA256 algorithm: func tokenSession(_ session: TKTokenSession, supports operation: TKTokenOperation, keyObjectID: TKToken.ObjectID, algorithm: TKTokenKeyAlgorithm) -> Bool { return algorithm.isAlgorithm(SecKeyAlgorithm.rsaSignatureDigestPKCS1v15SHA256) } This setup works perfectly with codesign, and signing completes without any issues. However, when I try to use productsign, the system correctly detects and delegates signing to my CTK extension, but it seems to always request rsaSignatureDigestPKCS1v15SHA1 instead: productsign --timestamp --sign <identity> unsigned.pkg signed.pkg productsign: using timestamp authority for signature productsign: signing product with identity "Developer ID Installer: <org> (<team>)" from keychain (null) ... Error Domain=NSOSStatusErrorDomain Code=-50 "algid:sign:RSA:digest-PKCS1v15:SHA1: algorithm not supported by the key" ... productsign: error: Failed to sign the product. From what I understand, older versions of macOS used SHA1 for code signing, but codesign has since moved to SHA256 (at least when legacy compatibility isn't a concern). Oddly, productsign still seems to default to SHA1, even in 2025. Is there a known way to force productsign to use SHA256 instead of SHA1 for the signature digest algorithm? Or is there some flag or configuration I'm missing? Thanks in advance!
Replies
7
Boosts
0
Views
626
Activity
Jun ’25
SecKeyCreateDecryptedDataWithParameters always fails with algo not supported
Attempting to DECRYPT a cipher message using the Apple API SecKeyCreateDecryptedData(privateKey, .rsaEncryptionOAEPSHA256, encryptedMessage). Decryption ALWAYS fails for every algorithm. SecKeyCreateDecryptedDataWithParameters Error: `Domain=NSOSStatusErrorDomain Code=-50 "algid:encrypt:RSA:OAEP:SHA256: algorithm not supported by the key &lt;SecKeyRef:('com.yubico.Authenticator.TokenExtension:5621CDF8560D4C412030886584EC4C9E394CC376DD9738B0CCBB51924FC26EB6') 0x3007fd150&gt;" UserInfo={numberOfErrorsDeep=0, NSDescription=algid:encrypt:RSA:OAEP:SHA256: algorithm not supported by the key &lt;SecKeyRef:('com.yubico.Authenticator.TokenExtension:5621CDF8560D4C412030886584EC4C9E394CC376DD9738B0CCBB51924FC26EB6') 0x3007fd150&gt;}` Decryption failed: SecKeyCreateDecryptedData returned nil. Error: One or more parameters passed to a function were not valid. When checking with SecKeyIsAlgorithmSupported(privateKey, .decrypt, &lt;ANYalgorithm&gt;) all algorithms fail. Btw - The privateKey does support decryption when retrieving the attributes. Important to know: The private key is a reference to an external private key placed in the iOS Keychain via a 3rd party CryptoTokenKit Extension app. When I perform, the SecKeyCreateSignature(...) and pass in the SAME privateKey reference, the OS automatically calls the 3rd party app to perform a successful signing with the private key that reside on a YubiKey. Here's my code for obtaining the private key reference from an Identity: func getKeyPairFromIdentity() -&gt; (privateKey: SecKey, publicKey: SecKey)? { let query = NSDictionary( dictionary: [ kSecClass as String: kSecClassIdentity, kSecAttrTokenID as String: self.tokenID!, kSecReturnRef as String: kCFBooleanTrue as Any ] ) var identityRef: CFTypeRef? let status = SecItemCopyMatching(query, &amp;identityRef) if status == errSecSuccess, let identity = identityRef { var privateKeyRef: SecKey? let keyStatus = SecIdentityCopyPrivateKey(identity as! SecIdentity, &amp;privateKeyRef) if keyStatus == errSecSuccess, let privateKey = privateKeyRef { let publicKey = SecKeyCopyPublicKey(privateKey) if let publicKey = publicKey { print("Private and public keys extracted successfully.") return (privateKey, publicKey) } else { print("Failed to extract public key from private key.") return nil } } else { print("SecIdentityCopyPrivateKey: Private key not found error: \(keyStatus)") return nil } } else { print("SecIdentity not found or error: \(status)") return nil } }
Replies
4
Boosts
0
Views
270
Activity
Apr ’25
TKTokenSession not used
Hi, I'm working on developing my own CryptoTokenKit (CTK) extension to enable codesign with HSM-backed keys. Here's what I’ve done so far: The container app sets up the tokenConfiguration with TKTokenKeychainCertificate and TKTokenKeychainKey. The extension registers successfully and is visible via pluginkit when launching the container app. The virtual smartcard appears when running security list-smartcards. The certificate, key, and identity are all visible using security export-smartcard -i [card]. However, nothing appears in the Keychain. After adding logging and reviewing output in the Console, I’ve observed the following behavior when running codesign: My TKTokenSession is instantiated correctly, using my custom TKToken implementation — so far, so good. However, none of the following TKTokenSession methods are ever called: func tokenSession(_ session: TKTokenSession, beginAuthFor operation: TKTokenOperation, constraint: Any) throws -> TKTokenAuthOperation func tokenSession(_ session: TKTokenSession, supports operation: TKTokenOperation, keyObjectID: TKToken.ObjectID, algorithm: TKTokenKeyAlgorithm) -> Bool func tokenSession(_ session: TKTokenSession, sign dataToSign: Data, keyObjectID: Any, algorithm: TKTokenKeyAlgorithm) throws -> Data func tokenSession(_ session: TKTokenSession, decrypt ciphertext: Data, keyObjectID: Any, algorithm: TKTokenKeyAlgorithm) throws -> Data func tokenSession(_ session: TKTokenSession, performKeyExchange otherPartyPublicKeyData: Data, keyObjectID objectID: Any, algorithm: TKTokenKeyAlgorithm, parameters: TKTokenKeyExchangeParameters) throws -> Data The only relevant Console log is: default 11:31:15.453969+0200 PersistentToken [0x154d04850] invalidated because the client process (pid 4899) either cancelled the connection or exited There’s no crash report related to the extension, so my assumption is that ctkd is closing the connection for some unknown reason. Is there any way to debug this further? Thank you for your help.
Replies
3
Boosts
0
Views
147
Activity
Apr ’25