In Mojave CryptoTokenKit source code is at version 281.200.21. It was at version 281.1.1 in High Sierra 10.13.0 and 281.50.22 in High Sierra 10.13.6.
Since the source code is not available I can't write much more than that.

Saturday, September 22, 2018

My CCID driver had some problems when used on a FreeBSD system. I used FreeBSD 10.4 (stable) but the problem should also be present in more recent or older versions of FreeBSD.

The problem

The problem was that the removal a USB reader was not reported to the PC/SC application. The removal was detected by the PC/SC daemon (pcscd) but something failed in the removal process.

The same problem also prevented the PC/SC daemon to exit correctly when stopped using the keyboard combination Control+C.

After some debugging the cause of the problem was identified. When the CCID driver is stopped (because a reader is removed or pcscd is exited) the driver tries to cancel all the unfinished USB transfers. When the reader provides an interrupt end point to notify card events the CCID driver initiates a USB transfer reading from this end point with a long timeout (10 minutes).

This behaviour can be very confusing for an application. The application has started a PC/SC transaction so it has an exclusive access to the card. No other application can reset the card during a transaction.

The native API to use smart card on macOS is CryptoTokenKit since Yosemite 10.10 (see "PCSC sample in Objective-C" or "PCSC sample in Swift") but many applications need to be portable to Windows, macOS and GNU/Linux and the common PC/SC API is used instead. So it is important to have a correctly working PC/SC API on macOS.

Bug list

I will list known (by me) bugs and will try to maintain the list in the future if/when the bugs are fixed.

Some of the bugs have been reported a few years ago but are still present in High Sierra.

Conclusion

The bugs listed above are not critical for many users. But they may surprise some developers when they try to understand why their code is working fine on GNU/Linux but has a strange behaviour when executed on macOS.

Why is it important

A card reset error can happen while the card is still in the reader. This is a normal PC/SC behaviour in case of multiple PC/SC applications running at the same time. One application may reset the card after using it.
When an application receive the error SCARD_W_RESET_CARD it can assume that the same card is still present in the reader.

A card removed error SCARD_W_REMOVED_CARD indicates that the card was removed. The same card or a different card may now be present in the reader. The application must assume that a different card has been inserted and that any cached information or application internal state should be refreshed by reading the newly inserted card.

Known workaround

dwEventState also contains a number of events in the upper 16 bits (dwEventState & 0xFFFF0000). This number of events is incremented for each card insertion or removal in the specified reader. This can be used to detect a card removal/insertion between two calls to SCardGetStatusChange()

Wednesday, September 12, 2018

Crypto Token Kit

In macOS Sierra (v10.12) Apple introduced the CryptoTokenKit plugin mechanism. This new mechanism is used to replace the tokend mechanism that was deprecated since OS X Lion (v10.7) in 2011.

The CryptoTokenKit API was introduced in OS X Yosemite (v10.10). What is new with macOS Sierra is that a smart card manufacturer can provide a plugin to use the smart card through the Crypto Token Kit API.

By default, macOS provides a Crypto Token Kit plugin to use a PIV card.

Implementation of a CryptoTokenKit plugin

I will not document here how to write a CryptoTokenKit plugin. Refer to Apple documentation for that and in particular the PIVtoken source code. See my article "macOS Sierra and PIVToken source code".

OpenSC plugin

The OpenSC project provides a PKCS#11 library for different smart cards.

Fetch OpenSCToken-1.0.dmg, open the .dmg image, copy the application OpenSCTokenApp.app in your /Applications/ directory.
You need to start the OpenSCTokenApp application at least one time to register the CryptoTokenKit plugin provided by the application. The application does nothing and you can quit it now.

Keychain Access application

The Keychain Access application displays objects returned by the tokend.

If you install only the CryptoTokenKit plugin then you will not see a new keychain in Keychain Access. For me it is a regression. The graphical application was a good tool to display the content of a smart card.

Pairing a card to a user account

After inserting the card you should see a dialog window like the one bellow.

Click on "Pair" to associate the card private key to the user account.

You will need to enter your account password:

Then enter the card PIN code:

And the user account again:

The pairing is now done.

Untrusted Certification Authority

Note that you can pair a card certificate to a user even if the certificate is not trusted. In my case the certificate is issued and signed by CAcert. This Certification Authority is not trusted by macOS (you can see that in the Keychain Access screen copy) but you can still use the untrusted certificate to login.

Check pairing

You can now check that your account is paired to card

$ sc_auth list
Hash: 0B1BEA814EE563AAD70C33D5C7F82472AB26C4C8

You can note that the hash 0B1BEA814EE563AAD70C33D5C7F82472AB26C4C8 correspond to the "certificate #1" "pkhh", the "private key #1" "klbl", the "identity #1" "pkhh" and "klbl" fields from the security export-smartcard output.

Unparing a user

You can unpair a user

$ sc_auth unpair
$ sc_auth list
$

You will get the pairing dialog again after removing and inserting the card again. So it is easy to play with the pairing process.

Pairing dialog status

Disable

If you click on the "Do not show again" on the pairing dialog box the dialog will not be displayed again. You can check the pairing dialog status using:

$ sc_auth pairing_ui -s status
SmartCard Pairing dialog is disabled.

Enable

You can re-enable the pairing dialog using:

$ sc_auth pairing_ui -s enable

$ sc_auth pairing_ui -s status
SmartCard Pairing dialog is enabled.

Usage

Screen unlock

You can lock your screen and unlock it using your smart card and PIN.

sudo(8)

As already seen in "macOS Sierra and pam_smartcard" some services are configured to use a PAM module for smart card.
In macOS Sierra only authorization_ctk and screensaver_ctk were configred to use the pam_smartcard.so module.

In macOS High Sierra the sudo command is also configured to use smart card authentication.

User login

The CryptoTokenKit plugin is enabled only for the user that has started the OpenSCTokenApp application.
Since the login screen is not executed as my user (I am not yet logged) so the plugin is not available at this step.