CryptoTokenKit

RSS for tag

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

CryptoTokenKit Documentation

Pinned Posts

Posts under CryptoTokenKit tag

18 Posts
Sort by:
Post not yet marked as solved
2 Replies
162 Views
Hello All, I am new to iOS development and would like to detect the smart card readers connected to USB-C port on iOS (16+) devices. The smart card reader is a custom hardware and not MFi certified. So as per my understanding, I cannot use ExternalAccessory.framework without MFi certification. Correct? How else can I achieve this? Does TKSmartCardSlotManager works for this purpose (or is it only for NFC devices?)? Is there any example for how to use this interface? I couldn't find any example for this as a starting point... Thanks in advance.
Posted
by user_2411.
Last updated
.
Post not yet marked as solved
0 Replies
2k Views
General: Apple Platform Security support document Security Overview Cryptography: DevForums 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 DevForums post SecItem attributes for keys DevForums post CryptoCompatibility sample code Keychain: DevForums tags: Security Security > Keychain Items documentation TN3137 On Mac keychain APIs and implementations SecItem Fundamentals DevForums post SecItem Pitfalls and Best Practices DevForums post Investigating hard-to-reproduce keychain problems DevForums post Smart cards and other secure tokens: DevForums tag: CryptoTokenKit CryptoTokenKit framework documentation Mac-specific frameworks: DevForums tags: Security Foundation, Security Interface Security Foundation framework documentation Security Interface framework documentation 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"
Posted
by eskimo.
Last updated
.
Post not yet marked as solved
1 Replies
917 Views
Hi there, I could not find any previous post about this so I figured I should open one. It looks like the use of CryptoTokenKit modules (whether SmartCard or Persistent ones) is hindered on headless environments. This was observed on AWS backed macOS machines, and also on actual physical machines when using CI/CD tools with no GUI access. My first guess is that this is due to the fact that loading the CTK Extension relies on running the GUI CTK App, which is not possible in pure headless fashion. The bug report FB12135879 was filled in this regard. Any input on this would be appreciated. Thanks,
Posted
by mostafaid.
Last updated
.
Post not yet marked as solved
2 Replies
226 Views
Issue: The screen saver is not shown, and the user is not locked after removing a smart card with a logged in user. I have tried setting tokenRemovalAction to 1, along with various other com.apple.security.smartcard defaults, and I have also tried setting "turn on screen saver when login token removed." None of this makes the screen locked on card removal. Is this an issue with MacOS14 or is there a different setting/value that has to be set for this to work correctly?
Posted
by Aaron1231.
Last updated
.
Post not yet marked as solved
2 Replies
254 Views
I've developed a crypto token kit extension using the Xcode template. I've successfully added the certificate and its corresponding private key to the keychain. However, when attempting to sign with this certificate, I need to call a command-line interface (CLI) that I've created. The CLI is located at ~/Applications/mycli/cli_executable. My issue arises because the extension is sandboxed, prohibiting direct communication with the CLI. I attempted to remove the sandbox, but that didn't resolve the problem (the extension wasn't being registered without the app sandboxed). Additionally, the CLI relies on a database, so simply copying the file to the app container folder isn't a feasible solution (unless it's a symlink – I'm unsure if this is possible). How can I effectively address this problem and enable communication between the sandboxed extension and my CLI (GoLang app)? Thank you.
Posted Last updated
.
Post not yet marked as solved
2 Replies
281 Views
I am working on a macOS application written on Swift 5, where the user can login using a smartcard. When user enters the smartcard and selects this way of authentication, we display the certificates on the card for the user to select. Once selected, the user enters the PIN and logs in. I am able to show the certificates using the SecItemCopyMatching call mentioned in this answer. But along with the PIN, I need to send the following information for successfully logging in. Card's name -> for example, Identity Device (NIST SP 800-73 [PIV]) Crypto service provider's name -> for example, Microsoft Base Smart Card Crypto Provider Container name -> in the format aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee Questions: I want to understand how to get this information from the certificate present on the smartcard. (not important) When I run the SecItemCopyMatching call, I get 8 objects in an array but I know that there are only 2 certs on it. Currently, I cast it into a set and see just 2 SecCertificate objects that I need. Is there a better solution to this?
Posted Last updated
.
Post not yet marked as solved
0 Replies
275 Views
I have verified a PIN in a smart card and I'd like to delete this internal state of the card. Unfortunately, the card doesn't support this with a dedicated command, which is why I'd like to reset the card (cold/warm reset as described in PC/SC, for example). The CryptoTokenKit documentation doesn't seem to have an API for that. Does anyone have an idea how to implement this? Note, that if the smart card is not reset and does not support logout, then the card is permanently in an authenticated state so that related keys can be misused by any other CTK session or even via the PC/SC interface.
Posted
by fdsafdas.
Last updated
.
Post not yet marked as solved
3 Replies
377 Views
Hello, I am developing a smartcard CTK extension for macOS. I have trouble to smartcard logon the first time after a reboot or a logout (e.g. when there is the text "Your password is required to enable touch id"). Trouble = I'm not asked for the PIN. But time to time after a logout (from whatever account), I can login with the smartcard. After a lockscreen I can always login with the smartcard. Is there an easy way to debug the logon process ? Regards, ++dom
Posted
by dom_.
Last updated
.
Post not yet marked as solved
5 Replies
455 Views
Hi, I want to support client certifcate authentication for a URL loaded in WKWebView. Certificate is in the smartcard that is connected to iOS device through lightning port smart card reader. For USB-C type reader, iOS supports this out of the box. But for the lightning port reader, I thought of writing a CTK extension to access smartcard and read the certificate. I have a smart card sdk to access the smartcard. Could you please let me know which is the extension that should be used for this purpose. There are 2 types of extensions available in Xcode. Smartcard extension and Persistent Token extension. Which one should be used for this case? When I tried persistent token extension, it seems to hit sign function inside Tokensession class but with smartcard extension it is not getting called when I try to access the URL in WKWebView after certificate selection. Also the smartcard sdk has EAAccessory framework dependency. Is EAAccessory allowed to be used in CTK extension? https://developer.apple.com/forums/thread/111691?answerId=342707022 says EAAccessory is not working inside app extension. Thanks in advance.
Posted
by iosseek.
Last updated
.
Post not yet marked as solved
4 Replies
1.4k Views
I need an OV certificate to code sign an Electron application. I was used to build in Jenkins the application oth for Windows and macOS using Electron-Forge (https://www.electronforge.io/guides/code-signing/code-signing-macos). To be more specific use XCode and Keychain to store the certificate. Sadly, new certificate industry requirements will force me to use Azure Key Vaults (or other cloud HSM alternatives) to store the certificate. I need to find a way to code-sign it for macOS from Azure Key Vaults or equivalent solutions. Thank you
Posted Last updated
.
Post not yet marked as solved
1 Replies
367 Views
Hello, I am creating CryptotokenKit persistent token extension for macOS using Xcode on Sonoma. The goal is to support external crypto provider over network (with API calls). I created a bare minimum app and a new target “Persistent Token Extension”. Before I go into specific implementation, I wanted to check if my extension/token initialises correctly. My understanding is that once the host app is started and the extension is registered by the OS, future queries for digital identities should check with it as well. I tried is accessing mTLS website with Safari and Firefox that require client certificates, as well running custom application using SecItemCopyMatching to query the keychain for identities. However, Token / TokenDriver seem to not initialize (logging never executes). Am I missing something here? pluginkit sees the extension: $ pluginkit -vvvvmi demo.TokenApp.TokenExt demo.TokenApp.TokenExt(1.0) Path = /Users/alexander/Library/Developer/Xcode/DerivedData/TokenApp-dzulesgoanwnacguirprimnipibk/Build/Intermediates.noindex/Previews/TokenApp/Products/Debug/TokenApp.app/Contents/PlugIns/TokenExt.appex UUID = 617526E8-987A-493F-A9E3-6295FF5AB00D Timestamp = 2024-01-19 13:13:35 +0000 SDK = com.apple.ctk-tokens Parent Bundle = /Users/alexander/Library/Developer/Xcode/DerivedData/TokenApp-dzulesgoanwnacguirprimnipibk/Build/Intermediates.noindex/Previews/TokenApp/Products/Debug/TokenApp.app Display Name = TokenExt Short Name = TokenExt Parent Name = TokenApp Platform = macOS Token.swift: import CryptoTokenKit import OSLog class Token: TKToken, TKTokenDelegate { private let log = Logger(subsystem: "demo.tokenapp", category: "Token"); func createSession(_ token: TKToken) throws -> TKTokenSession { log.log(level: .info, "Token.createSession") return TokenSession(token:self) } } TokenDriver.swift: import CryptoTokenKit import OSLog class TokenDriver: TKTokenDriver, TKTokenDriverDelegate { private let log = Logger(subsystem: "demo.tokenapp", category: "TokenDriver"); func tokenDriver(_ driver: TKTokenDriver, tokenFor configuration: TKToken.Configuration) throws -> TKToken { log.log(level: .info, "TokenDriver.tokenDriver") return Token(tokenDriver: self, instanceID: configuration.instanceID) } }
Posted Last updated
.
Post not yet marked as solved
1 Replies
605 Views
I am having trouble creating a CSR to renew a SecIdentity whose private SecKey is stored in slot 9d of a smartcard. For slot 9a, I am able to accomplish this by way of SecKeyCreateSignature using CertificateSigningRequest from a gently-modified fork of swift-certificates/swift-crypto to sort out all the details. But for the SecKey associated with slot 9d, the Security framework instantly returns an "algorithm not supported by the key" error when I call SecKeyCreateSignature, without even prompting for a PIN. I believe the difference is that kSecAttrCanSign is true for slot 9a but false for slot 9d. The value makes some sense for day-to-day usage because this identity is usually not used for signing, but if we are to occasionally sign a CSR for this key an exception would need to be made. Is there any way to basically force this exception with the Security framework? Again the actual private key material is not available so the only access as far as I'm aware is via the enumerated SecKey reference. Is there any way to SecKeyCreateWithData a secondary reference to the same underlying (but unexportable!) key but with allowed-usage attributes of my own choosing?
Posted
by natevw.
Last updated
.
Post not yet marked as solved
2 Replies
2.4k Views
I am developing a Java app that integrates with SmartCard reader. One of the features that I try to implement is reading/setting terminal (card reader) configuration without a tag being present on the reader. This can be done by sending so called escape codes. But to enable these escape codes we need to enable them in the driver. In case of macOS this will be SmartCardServices and the file that I should edit is: /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist I need to set ifdDriverOptions property to 0x0001. This procedure was described in this helpful GitHub comment https://github.com/pokusew/nfc-pcsc/issues/13 I tried to follow other instructions provided there but I hit the wall with read-only file system error. I wonder if there is an idiomatic way to change these settings. Why this is important? Sending new configuration via escape command is the only way to un-brick terminal that was (by mistake) wrongly configured.
Posted
by 0xmarcin.
Last updated
.
Post not yet marked as solved
2 Replies
740 Views
I am working on an iOS application that deals with scanning SmartCards at entry points to see who is entering a facility. We are currently using proprietary smartcard readers from a company and their SDK to directly access the reader and issue APDU commands to get the smartcard information, such as certificate, expiration date, etc. The plan is to be able to have a person insert a smartcard, the system recognize it, validate the expiration date and cert chain, record who it is and then tell the user to pull the card and move on. This process needs to be fast. PIN entries are not required. We are trying to move away from the 3rd party SDK and proprietary card reader to be able to use any CCID compliant reader and CryptoTokenKit from Apple. Information on this seems to be very limited from what searching. I've started with some simple code (not complete): var card : TKSmartCard? = nil let card = slot?.makeSmartCard() if (card != nil && card?.isValid != nil) { card?.beginSession(reply: { something, error in let nistEndpoint : [UInt8] = [0x00, 0xA4, 0x04, 0x00, 0x0B, 0xA0, 0x00, 0x00, 0x03, 0x08, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00] let nistRequest = Data.init(bytes: nistEndpoint) card?.transmit(nistRequest, reply: { data, error in if error == nil { // Do stuff }else { // log the error } }) } When I run this on an iPad with a USB connected card reader, I am seeing the card reader, getting its name, seeing that a card is in the reader and the 'card?.isValid' is coming back. The card?.transmit is throwing an error however and returns TKError.Code.tokenNotFound (-7). Questions: I see that the CryptoTokenKit API requires the entitlement of com.apple.security.smartcard, but no where during the creation of a provisioning profile process in my dev account give me the option to add that specific entitlement. Is this something that has be specially assigned by Apple? Is what I'm trying to accomplish possible using CryptoTokenKit on an iOS device? Does anyone know of any tutorials or examples of this? Thank you in advance.
Posted
by jon595.
Last updated
.
Post marked as solved
10 Replies
1.9k Views
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?
Posted Last updated
.
Post not yet marked as solved
1 Replies
933 Views
I am trying to learn how PAM works in macOS, in that process I came across one of the apple open source project in git hub. So I downloaded the project and opened it in xcode. When I tried to build the project initially I got base SDK error. I resolved that by changing the value to macOS(initially the value for base SDK is macosx.internal). After that most of the dependency error are resolved but now I am getting some of the header files are not found and also some of '.a' files are also missing. I have explored over the internet for those files but unable to get those. I have attached the missing header files and '.a' files below. Can you please help me in build this project. GitHub link: [https://github.com/apple-oss-distributions/pam_modules/tree/pam_modules-195) Header files: #include <Security/SecKeychainPriv.h> #include <OpenDirectory/OpenDirectoryPriv.h> #include <Heimdal/krb5.h>
Posted Last updated
.
Post not yet marked as solved
1 Replies
943 Views
Hi, I am trying to implement an app which performs cert based authentication through smart card. I have few queries related to the same I have included com.apple.token in the key chain accessory group. I am able to fetch the certificates from the keychain using Yubi key Type c. But this is not working for Yubi key lighting port. Does Apple support lighting port readers? What is the need of crypto token kit extension if we are able to list the certificates from key chain just by adding com.apple.token in the entitlements file.
Posted
by Pratibhas.
Last updated
.
Post not yet marked as solved
0 Replies
815 Views
I am trying to build csr string from publickeyBits and signature from dongle. Below is the swift code portion for generating csr. public func buildCSRAndReturnStringUsingDongle(enrollmentId: String, password: String) -> String? { let tagPublic = "public" + enrollmentId self.dongle = DongleManager.getInstance() self.dongle?.generateKeyPair(enrollmentId: enrollmentId, password: password) let publicKeyFromDongle: String = (self.dongle?.getPublicKeyBits(enrollmentId: enrollmentId, password: password))! print("Public Key is: \n",publicKeyFromDongle) let keyDict: [NSString: Any] = [ kSecAttrKeyType: kSecAttrKeyTypeRSA, kSecAttrKeyClass: kSecAttrKeyClassPublic, kSecAttrKeySizeInBits: 2048 as Any, kSecAttrApplicationTag: tagPublic.data(using: .utf8), ] var error: Unmanaged<CFError>? let publicKeyFromDongleData = Data.init(base64Encoded: publicKeyFromDongle) guard let publicKeySecKey = SecKeyCreateWithData(publicKeyFromDongleData! as CFData, keyDict as CFDictionary, &error) else { print("Failed to create public key:", error!.takeRetainedValue()) return nil } let publickeyBits = KeyPairManager.getInstance().getPublicKeyBits(publicKey: publicKeySecKey, enrollmentId: enrollmentId).0 let certificationRequestInfo = buldCertificationRequestInfo(publickeyBits!) let bytes: [UInt8] = certificationRequestInfo.map { $0 } let certificationRequestStr = String(decoding: bytes, as: UTF8.self) let signaturedString = self.dongle?.sign(password: password, data : certificationRequestStr, enrollmentId: enrollmentId) var signature = [UInt8](repeating: 0, count: 256) var signatureLen: Int = signature.count let signatureData = signaturedString!.data(using: .hexadecimal) signatureData!.copyBytes(to: &signature, count: signatureData!.count) signatureLen = signatureData!.count print("signature length: " + String(signatureLen)) print("signature: "+signatureData!.base64EncodedString()) var certificationRequest = Data(capacity: 1024) certificationRequest.append(certificationRequestInfo) let shaBytes = keyAlgorithm.sequenceObjectEncryptionType certificationRequest.append(shaBytes, count: shaBytes.count) var signData = Data(capacity: 2049) let zero: UInt8 = 0 // Prepend zero signData.append(zero) signData.append(signature, count: signatureLen) appendBITSTRING(signData, into: &certificationRequest) enclose(&certificationRequest, by: sequenceTag) // Enclose into SEQUENCE let csrString = certificationRequest.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0)) .addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) print(csrString) let head = "-----BEGIN CERTIFICATE REQUEST-----\n" let foot = "-----END CERTIFICATE REQUEST-----\n" var isMultiple = false var newCSRString = head //Check if string size is a multiple of 64 if csrString!.count % 64 == 0 { isMultiple = true } for (integer, character) in csrString!.enumerated() { newCSRString.append(character) if (integer != 0) && ((integer + 1) % 64 == 0) { newCSRString.append("\n") } if (integer == csrString!.count-1) && !isMultiple { newCSRString.append("\n") } } newCSRString += foot return newCSRString } I wrote a Wrapper where sign function is as of given below. We had a getPublicBits() function here and i think that is working properly. So, I skip this here. - (NSString*) sign: (NSString*)password data: (NSString*)data enrollmentId: (NSString*)enrollmentId { Dongle *d = (Dongle*)****; char * pass = strdup([password UTF8String]); char * signDataStr = strdup([data UTF8String]); char * enId = strdup([enrollmentId UTF8String]); NSData* data2 = [data dataUsingEncoding:NSUTF8StringEncoding]; char *signData = (char *)[data2 bytes]; NSString* signaturedString = [NSString stringWithCString:d->sign(pass, signData, enId).c_str() encoding:[NSString defaultCStringEncoding]]; return signaturedString; } I used signUtil method from safenet sdk's library. std::string Dongle::signUtil(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPrivateKey, char* password, char* data) { //std::cout<<"data is: " << *data; CK_RV retCode = CKR_OK; int isPaddingRequired = 0; int isDataFromUser = 0; CK_MECHANISM mech; CK_BYTE pSigData[3000]; #ifndef PKCS11_V1 CK_ULONG usSigLen = sizeof(pSigData); #else CK_ULONG usSigLen = 0; #endif char *pInputData = 0; unsigned long ulInputDataLen = strlen(data); std::cout << "length: " << ulInputDataLen; CK_BYTE_PTR pInData = (CK_BYTE_PTR)data; std::cout << "Mechanism: [6]SHA256-RSA" <<std::endl; retCode = C_Login(hSession, CKU_USER, (CK_UTF8CHAR_PTR)password, strlen(password)); mech.mechanism = CKM_SHA256_RSA_PKCS; mech.pParameter = 0; mech.ulParameterLen = 0; isDataFromUser = 0; if( retCode == CKR_OK ) { if( isPaddingRequired ) { for(unsigned long ulLoop=ulInputDataLen; ulLoop<64; ++ulLoop) { pInData[ulLoop] = 0; } ulInputDataLen = 64; } } if (retCode == CKR_OK) { retCode = C_SignInit(hSession, &mech, hPrivateKey); } CK_ULONG usInLen = (CK_ULONG)ulInputDataLen; // get the signature length if(retCode == CKR_OK) { retCode = C_Sign(hSession, pInData, usInLen, (CK_BYTE_PTR)NULL_PTR, &usSigLen); } // get the signature if(retCode == CKR_OK) { retCode = C_Sign(hSession, pInData, usInLen, (CK_BYTE_PTR)pSigData, &usSigLen); } std::string returnSignature = ""; if( (retCode == CKR_OK) && usSigLen ) { std::cout << "Signed Data " << std::endl << "(hex) "; for(unsigned long ulLoop=0; ulLoop<usSigLen; ++ulLoop) { char pBuffer[25]; sprintf(pBuffer, "%02x", pSigData[ulLoop]); std::cout << pBuffer; returnSignature += pBuffer; } std::cout << std::endl; } // Release memory if( pInputData ) { delete pInputData; } return returnSignature; } I debug a lot and according to csr decoder, only the signature is invalid. public key and signature algorithm are valid.
Posted Last updated
.