CryptoTokenKit framework usage

Hi,

I’m currently working on an app that uses a third-party SDK to perform smart card authentication via PKCS#11 APIs. Specifically, the app interacts with the smart card to retrieve certificates, detect the card reader, and perform encryption and decryption operations on provided data.

I’m wondering if it's possible to replace the PKCS#11 APIs and the third-party SDK with Apple's CryptoTokenKit framework. Does CryptoTokenKit provide equivalent functionality for smart card authentication, certificate management, and encryption/decryption operations?

Additionally, I’ve come across the following CryptoTokenKit documentation:

CryptoTokenKit API - TKSmartCardSlotManager Could you provide an example code or any guidance on how to implement this functionality using CryptoTokenKit, particularly for interacting with smart cards, managing certificates, and performing cryptographic operations?

Thank you for your assistance.

Answered by DTS Engineer in 813037022
Does CryptoTokenKit provide equivalent functionality for smart card authentication, certificate management, and encryption/decryption operations?

Yes. But in most cases you don’t actually need to use CTK directly. Rather, you can find smart card backed keys using the normal SecItem API and then work with them directly. However, if you want to do things like monitor the smart card coming and going then, sure, CTK is what you need.

See this post for more details and some code snippets.

Share and Enjoy

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

Does CryptoTokenKit provide equivalent functionality for smart card authentication, certificate management, and encryption/decryption operations?

Yes. But in most cases you don’t actually need to use CTK directly. Rather, you can find smart card backed keys using the normal SecItem API and then work with them directly. However, if you want to do things like monitor the smart card coming and going then, sure, CTK is what you need.

See this post for more details and some code snippets.

Share and Enjoy

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

Hi,

Thanks for the inputs. We have already tested the flow using smart card-backed keys, and it has worked well when handling NSURLSession requests.

We are currently using PKCS11 APIs available from third party SDK to handle smart card requests for a Remote Desktop solution, which involves cryptographic operations such as signing data and verifying PINs.

We would appreciate your assistance with the following:

Sign Data Without Sending an APDU Command:

Is there an existing PKCS11 API that allows us to sign data?

Retrieving Key/Certificate Attributes (CK_value, CK_Label): Can we retrieve attributes such as CK_VALUE (the key or certificate data) and CK_LABEL (the label associated with the key or certificate) for private/public keys or certificates? If so, could you provide the recommended API?

Obtaining Slot ID from the Smart Card: We need to retrieve the slot ID associated with the smart card, as this ID represents the physical location of the card within the reader. Is there a method to obtain the slot ID for a specific smart card during cryptographic operations?

While Apple doesn’t have PKCS#11 API per se, much of what you’re asking can be done with existing APIs.

Is there an existing PKCS11 API that allows us to sign data?

Yes. Once you have a SecKey object for a private key, you can sign data with that key SecKeyCreateSignature. If that key is physically resident on a hardware token that’s backed by a CTK appex, the system will pass the signing operation to the CTK appex that in turn passes it to the hardware token. In the case of a PIV smart card, there’s a built-in CTK appex that works with most smart cards.

Can we retrieve attributes such as CK_VALUE (the key or certificate data)

I’m not super familiar with PKCS#11 terminology but this part is easy:

  • Any certificates on the smart card appear as certificates in the keychain. You can get such a certificate as a SecCertificate object. If you need the bytes of that certificate, call SecCertificateCopyData. If you need the public key, call SecCertificateCopyKey. If you need the bytes of that, call SecKeyCopyExternalRepresentation.

  • The private key comes back as a SecKey object. You can’t get the bytes of that, obviously, because that’s the whole point of storying the key on a hardware token.

In general I prefer to work with digital identities, that is, the amalgam of a certificate and the private key that matches the public key in that certificate. If you get one of those back from the keychain, call SecIdentityCopyCertificate to get the certificate and SecIdentityCopyPrivateKey to get the private key, then proceed as above.

Can we retrieve attributes [the] CK_LABEL (the label associated with the key or certificate) for private/public keys or certificates?

I’m not familiar enough with PKCS#11 to answer that without more input from you. What does this label actually represent?

Is there a method to obtain the slot ID for a specific smart card during cryptographic operations?

You can learn about slots via TKSmartCardSlotManager.

You can learn about tokens via TKTokenWatcher.

When you get a credential (key, certificate, or digital identity) from the keychain, its kSecAttrTokenID attribute contains the token ID. You can feed that into TKTokenWatcher to get a slot name and then feed the slot name into TKSmartCardSlotManager to get more information about the slot. You can also pass a value for kSecAttrTokenID in to SecItemCopyMatching to filter for items on that token.

Oh, and because I’ve not mentioned them previously, if you’re working with the SecItem API, read these first:

Share and Enjoy

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

CryptoTokenKit framework usage
 
 
Q