Important!

Blog moved to https://blog.apdu.fr/

I moved my blog from https://ludovicrousseau.blogspot.com/ to https://blog.apdu.fr/ . Why? I wanted to move away from Blogger (owne...

Showing posts with label Mac OS X. Show all posts
Showing posts with label Mac OS X. Show all posts

Tuesday, November 15, 2022

macOS Ventura and smart cards status

Ventura (macOS 13.0) is now available since October, 2022.

I will compare this version to the previous one in Monterey I presented in macOS Monterey and smart cards status

CCID

$ grep -A 1 CFBundleShortVersionString /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
	<key>CFBundleShortVersionString</key>
	<string>1.5.0</string>

The CCID driver has been upgraded from version 1.4.34 as in Monterey to version 1.5.0.

Apple Open Source

The Open Source components included in macOS are listed at https://opensource.apple.com/releases/
 
In addition to a .tar.gz archive, the source code is also available in a github (acquired by Microsoft in 2018) repository at https://github.com/apple-oss-distributions/SmartcardCCID.
 
It is then easy to see the patches applied by Apple to the CCID driver:
But the patches have no documentation on the why the patches are needed.
 
The only obvious patch is ccid-info-plist.patch that changes the value of ifdLogLevel from Info.plist configuration file from 3 (CRITICAL + INFO) to 1 (CRITICAL) in order to generate less logs.
 
It is also easy to compare two versions. For example the differences between the version for Monterey and the version for Ventura is available as a github diff between tags SmartcardCCID-55028 and SmartcardCCID-55031.

Crypto Token Kit

Nothing special to say. The source code of this part is not available.
 
My Objective-C sample "PC/SC" sample in Objective-C (synchronous) still builds and works fine.
 

Security message on first connection

On the first connection of my USB smart card reader I got this dialogue box:
It is nice to see the security improvements.
 
As expected, I do not get the dialogue box again after I selected "Allow".

Conclusion

No big changes in Ventura for the smart card world.

Thursday, November 11, 2021

macOS Monterey and smart cards status

Monterey (macOS 12.0 or 12.0.1 in fact) is now available since October, 2021.

I compare this version to the previous one in Big Sur I presented in macOS Big Sur and smart cards status.



PC/SC

Since Yosemite (macOS 10.10 in 2014) the PC/SC layer is no more a fork of pcsc-lite. So comparing versions with pcsc-lite is useless.

$ cat /System/Library/Frameworks/PCSC.framework/Versions/A/Resources/version.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>BuildAliasOf</key>
	<string>CryptoTokenKit</string>
	<key>BuildVersion</key>
	<string>13</string>
	<key>CFBundleShortVersionString</key>
	<string>8.0</string>
	<key>CFBundleVersion</key>
	<string>1</string>
	<key>ProjectName</key>
	<string>SmartCardServices</string>
	<key>SourceVersion</key>
	<string>554040005000000</string>
</dict>
</plist>

The BuildVersion changed from 25 to 13. No idea what that means.

The SourceVersion changed from 487040010000000 to 554040005000000. Again, no idea what that means. Except that Apple made changes to the code.

I have not yet made many tests of the PC/SC layer. So far it works fine.


Crypto Token Kit

CryptoTokenKit is the native smart card API since the complete rewrite in macOS Yosemite 10.10 (OS X Yosemite BETA and smart cards status).

The framework directory changed again. There is no more a /System/Library/Frameworks/CryptoTokenKit.framework/CryptoTokenKit/ directory.

But you can of course still use the CryptoTokenKit framework. My Objective-C sample "PC/SC" sample in Objective-C (synchronous) still builds and works fine.


CCID

$ grep -A 1 CFBundleShortVersionString /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
17:    <key>CFBundleShortVersionString</key>
18-    <string>1.4.34</string>
The CCID driver has been upgraded from version 1.4.32 as in Big Sur to version 1.4.34.
 
I released version 1.4.34 in  January 2021. The latest CCID version (at the time of writing this blog) is 1.4.36 from August 2021.

Apple Open Source

Apple has not yet added macOS Monterey to the Apple Open Source web site. So we can't say much about what Apple provides in Monterey.

macOS Monterey 12.0.1 Release Notes

CryptoTokenKit is not mentioned in the macOS Monterey 12.0.1 Release Notes. So I imagine only minor changes were made.

Conclusion

No big changes in Monterey for the smart card world.

Wednesday, January 13, 2021

macOS Big Sur and smart card source code

Apple released the source code of the open source components they use in Big Sur (macOS 11.0, released in October 2020). The components are available at macOS X 11.0.1 Source.


SmartcardCCID

The SmartcardCCID component moved from version SmartcardCCID-55018.0.2 in Catalina 10.15.0 to SmartcardCCID-55021.40.1 in Big Sur 11.0.1.

Incomplete diff:

diff -ru SmartcardCCID-55018.0.2/SmartcardCCID.plist SmartcardCCID-55021.40.1/SmartcardCCID.plist
--- SmartcardCCID-55018.0.2/SmartcardCCID.plist	2019-08-21 00:16:22.000000000 +0200
+++ SmartcardCCID-55021.40.1/SmartcardCCID.plist	2020-04-28 20:53:09.000000000 +0200
@@ -6,13 +6,13 @@
 		<key>OpenSourceProject</key>
 		<string>ccid</string>
 		<key>OpenSourceVersion</key>
-		<string>1.4.31</string>
+		<string>1.4.32</string>
 		<key>OpenSourceWebsiteURL</key>
 		<string>https://ccid.apdu.fr</string>
 		<key>OpenSourceURL</key>
-		<string>https://ccid.apdu.fr/files/ccid-1.4.31.tar.bz2</string>
+		<string>https://ccid.apdu.fr/files/ccid-1.4.32.tar.bz2</string>
 		<key>OpenSourceImportDate</key>
-		<string>2019-08-20</string>
+		<string>2020-04-27</string>
 		<key>OpenSourceModifications</key>
 		<array>
 			<string>destDirFix.patch - makefile.in, customized destination directory</string>
diff -ru SmartcardCCID-55018.0.2/ccid/Makefile SmartcardCCID-55021.40.1/ccid/Makefile
--- SmartcardCCID-55018.0.2/ccid/Makefile	2019-08-21 00:16:21.000000000 +0200
+++ SmartcardCCID-55021.40.1/ccid/Makefile	2020-08-06 20:06:44.000000000 +0200
@@ -24,11 +24,12 @@
 	find $(DSTROOT)/ -name 'usb*.h' -exec rm \{\} \;
 	rm -r $(DSTROOT)/usr/include
 	rm -r $(DSTROOT)/usr/lib
-	install_name_tool -id $(CCIDDriversPath)$(CCIDdylib) $(DSTROOT)$(CCIDDriversPath)$(CCIDdylib) 
+	install_name_tool -id $(CCIDDriversPath)$(CCIDdylib) $(DSTROOT)$(CCIDDriversPath)$(CCIDdylib)
+	codesign -s - $(DSTROOT)$(CCIDDriversPath)$(CCIDdylib)
 
 # Automatic Extract & Patch
 AEP_Project    = ccid
-AEP_Version    = 1.4.31
+AEP_Version    = 1.4.32
 AEP_ProjVers   = $(AEP_Project)-$(AEP_Version)
 AEP_Filename   = $(AEP_ProjVers).tar.bz2
 AEP_ExtractDir = $(AEP_ProjVers)
[...]

As we already saw in macOS Big Sur and smart cards status the CCID driver was updated from version 1.4.31 to version 1.4.32. You can find the patches Apple applies to the CCID driver in the ccid/files/ directory. Nothing special to say.

In fact, after checking the different releases of Catalina 10.15.x in https://opensource.apple.com/ I found that the CCID driver was upgraded from 1.4.31 to 1.4.32 in Catalina itself from 10.15.5 to 10.15.6.

So Apple upgraded the CCID driver within the same major version version of macOS.
And they missed the opportunity to upgrade to 1.4.33 in Big Sur. Maybe it is planned for a future minor version upgrade of Big Sur?


libusb

SmartcardCCID includes the libusb component used by the CCID driver.

This libusb library is statically linked to the CCID driver and can't be used by another project.

The version is 1.0.9. This is a very old version of libusb that was released in April 2012. The current libusb version is 1.0.24 released in December 2020.

I guess Apple does not want to upgrade a component that works fine enough from them.


SecurityTokend

This component is the same as in Catalina. It is SecurityTokend-55113.

It is strange to still find a tokend related component. Tokend technology is deprecated since Mac OS X Lion in 2011 (Mac OS X Lion and tokend).

Tokend was disabled by default in Catalina but was still usable (macOS Catalina and smart cards status).

In Big Sur tokend are not usable at all.

This component SecurityTokend does not contain any tokend plugin. There were in the Tokend component, not SecurityTokend. This component generates two file: SecurityTokend.framework and libsecurity_tokend_client.a. I am not sure what they are used for.


Conclusion

Interesting parts of the smart card stack would be the CryptoTokenKit and WinSCard layers. But since Apple moved away from the Free Software project pcsc-lite in macOS Yosemite in 2014 (OS X Yosemite and smart cards status) these components are not open source.

Sunday, November 15, 2020

macOS Big Sur and smart cards status

macOS Big Sur (macOS 11.0) is now available since November, 2020.


tokend

A tokend is a piece of software used to bridge a cryptographic device (like a smart card) and the CDSA (Common Data Security Architecture) architecture.

Since macOS Lion (10.7 in 2011) the CDSA/tokend technology is deprecated. See "Mac OS X Lion and tokend".

tokend was disabled by default in Catalina but it was still possible to enable it again.

With macOS Big Sur tokend is now completely removed. The manpage SmartCardServices-legacy(7) is also no more present.

PC/SC

Since Yosemite (macOS 10.10 in 2014) the PC/SC layer is no more a fork of pcsc-lite. So comparing versions with pcsc-lite is useless.
% cat /System/Library/Frameworks/PCSC.framework/Versions/A/Resources/version.plist
<?xml
version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>BuildAliasOf</key> <string>CryptoTokenKit</string> <key>BuildVersion</key> <string>25</string> <key>CFBundleShortVersionString</key> <string>8.0</string> <key>CFBundleVersion</key> <string>1</string> <key>ProjectName</key> <string>SmartCardServices</string> <key>SourceVersion</key> <string>487040010000000</string> </dict> </plist>
The CFBundleShortVersionString is still 8.0 as for Mojave and Catalina. The SourceVersion changed from 408011002000000 to 487040010000000. But I have no idea what that means :-).
 
I have not yet made many tests of the PC/SC layer. So far it works fine.

Crypto Token Kit

CryptoTokenKit is the native smart card API since the complete rewrite in macOS Yosemite 10.10 (OS X Yosemite BETA and smart cards status).

The directory /System/Library/Frameworks/CryptoTokenKit.framework/CryptoTokenKit/ changed a bit between Catalina and Big Sur. For example the file CryptoTokenKit is no more present.

I tried my Objective-C sample and the code still works fine (as expected) even if the binary is now linked to a non-existent library file.
% otool -L ./blog.app/Contents/MacOS/blog
./blog.app/Contents/MacOS/blog:
	/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1673.126.0)
	/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.0.0)
	/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1673.126.0)
	/System/Library/Frameworks/CryptoTokenKit.framework/Versions/A/CryptoTokenKit (compatibility version 1.0.0, current version 1.0.0)
% ls /System/Library/Frameworks/CryptoTokenKit.framework/Versions/A/CryptoTokenKit
ls: /System/Library/Frameworks/CryptoTokenKit.framework/Versions/A/CryptoTokenKit: No such file or directory

CCID

% grep -A 1 CFBundleShortVersionString /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
	<key>CFBundleShortVersionString</key>
	<string>1.4.32</string>
Apple updated the CCID driver from version 1.4.31 in Catalina to 1.4.32 in Big Sur.

Version 1.4.32 is not the latest version available. I released this version on April, 22th 2020.
The latest version (for now) of the CCID driver is 1.4.33 released on June 25th, 2020. 

Apple Silicon

macOS Big Sur is also the operating system for the new Apple computers using the Apple Silicon CPU (an ARM based CPU). The binaries provided with macOS Big Sur are now also compiled for ARM.

For example with the CCID driver:
% cd /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/MacOS/
% file libccid.dylib 
libccid.dylib: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit dynamically linked shared library x86_64] [arm64e:Mach-O 64-bit dynamically linked shared library arm64e]
libccid.dylib (for architecture x86_64):	Mach-O 64-bit dynamically linked shared library x86_64
libccid.dylib (for architecture arm64e):	Mach-O 64-bit dynamically linked shared library arm64e
My CCID driver works fine with GNU/Linux on a RaspberryPi with an ARM CPU. So it is not surprising that it works also fine with an Apple Silicon CPU.

When Apple will publish the patches they made to Free Software programs used in Big Sur at https://opensource.apple.com we will see if some modifications were needed.

Conclusion

No big changes in Big Sur for the smart card world.

Thursday, December 12, 2019

tokend support is NOT broken Catalina

Upgrade regression

3 weeks ago I wrote the article "tokend support is broken Catalina 10.15.1" because I could no more use the tokend I am working on after the upgrade from Catalina 10.15.0 to Catalina 10.15.1.

Fake news?

Today I upgraded to Catalina 10.15.2 and the problem is still present.
To be sure I installed OpenSC and the tokend from OpenSC works fine on Catalina 10.15.2. Good job OpenSC team.

So the problem is not Catalina but my tokend.
I then noticed a line in the system logs:
kernel Sandbox: securityd(638) deny(1) process-exec* [...]

I have a problem with the tokend sandbox and need to fix it. The problem is on my side :-(

Conclusion

I wrongly accused Apple to have introduced a bug in macOS. I am sorry for that.
Next time I will double check the problem is really not on my side.

Saturday, November 23, 2019

tokend support is broken Catalina 10.15.1

Catalina

The tokend technology is deprecated since macOS Lion (10.7 in 2011). With macOS Catalina (10.15 in 2019) the support of tokend is disabled by default. But Apple provides a way to enable it again.

See my previous article "macOS Catalina and smart cards status".

Catalina, first minor update

With the first minor update of Catalina (10.15.1) the support of tokend seems to be broken (not just disabled).

I reported the problem to Apple (feedback FB7455638) but have no news since then.
You can also report the same problem to Apple to give the issue a higher priority.

My recommendations

If you depend on a working tokend support then do not upgrade to Catalina and stay with Mojave (for now).

While in Mojave migrate from tokend to a CryptoTokenKit plugin equivalent. The CryptoTokenKit plugin is the new technology introduced (in macOS Sierra 10.12 in 2016 "macOS Sierra: Smart Card Driver Extensions") to replace tokend.
Once your CTK plugin configuration is working fine you can migrate to Catalina.

Update: December 12, 2019

See the update: "tokend support is NOT broken Catalina".

Monday, October 14, 2019

macOS Catalina and smart cards status

macOS Catalina (macOS 10.15) is now available since 7th October, 2019.


API Differences between 10.14 and 10.15

The differences should be listed in the "What's New in macOS" developer page for macOS Catalina 10.15.

The changes for Mojave are still not yet available. So maybe the changes for Catalina will also not be listed. The latest macOS version listed is 10.13.

tokend

A tokend is a piece of software used to bridge a cryptographic device (like a smart card) and the CDSA (Common Data Security Architecture) architecture.

Since macOS Lion (10.7 in 2011) the CDSA/tokend technology is deprecated. See "Mac OS X Lion and tokend".

Tokend are now disabled by default in macOS Catalina. See the Apple page "Prepare for smart card changes in macOS Catalina":
macOS includes a modern architecture that supports smart cards. This architecture is based on the CryptoTokenKit framework, which supports authentication, encryption, and signing functions, plus MDM controls for managing smart cards within Enterprise environments. Starting with macOS Catalina, legacy smart card support that uses TokenD will be disabled by default.

It is still possible to enable support of tokend. See SmartCardServices-legacy(7) manpage:

sudo defaults write /Library/Preferences/com.apple.security.smartcard Legacy -bool true

My guess is that tokend support will be completely removed in the next major macOS version (10.16 released in 2020).
It is really time to move away from tokend and migrate to CryptoTokenKit.

PC/SC

Since Yosemite (macOS 10.10 in 2014) the PC/SC layer is no more a fork of pcsc-lite. So comparing versions with pcsc-lite is useless.

% cat /System/Library/Frameworks/PCSC.framework/Versions/A/Resources/version.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
 <key>BuildAliasOf</key>
 <string>CryptoTokenKit</string>
 <key>BuildVersion</key>
 <string>2</string>
 <key>CFBundleShortVersionString</key>
 <string>8.0</string>
 <key>CFBundleVersion</key>
 <string>1</string>
 <key>ProjectName</key>
 <string>SmartCardServices</string>
 <key>SourceVersion</key>
 <string>408011002000000</string>
</dict>
</plist>

The CFBundleShortVersionString is still 8.0 as for Mojave.
The SourceVersion changed from 281200021000000 to 408011002000000. But I have no idea what that means :-).

I know Apple made changes in the PC/SC layer in Catalina because I identified and reported a bug in PC/SC during the beta. The bug has been fixed.

Crypto Token Kit

CryptoTokenKit is the native smart card API since the complete rewrite in macOS Yosemite 10.10 (OS X Yosemite BETA and smart cards status).

% strings /System/Library/Frameworks/CryptoTokenKit.framework/CryptoTokenKit | grep BuildRoot
/BuildRoot/Library/Caches/com.apple.xbs/Sources/CryptoTokenKit/CryptoTokenKit-408.11.2/CryptoTokenKit/TKToken.m
/BuildRoot/Library/Caches/com.apple.xbs/Sources/CryptoTokenKit/CryptoTokenKit-408.11.2/CryptoTokenKit/TKSmartCard.m
/BuildRoot/Library/Caches/com.apple.xbs/Sources/CryptoTokenKit/CryptoTokenKit-408.11.2/CryptoTokenKit/TKTokenConfiguration.m
/BuildRoot/Library/Caches/com.apple.xbs/Sources/CryptoTokenKit/CryptoTokenKit-408.11.2/CryptoTokenKit/TKClientToken.m
/BuildRoot/Library/Caches/com.apple.xbs/Sources/CryptoTokenKit/CryptoTokenKit-408.11.2/CryptoTokenKit/TKTokenKeychainItem.m
/BuildRoot/Library/Caches/com.apple.xbs/Sources/CryptoTokenKit/CryptoTokenKit-408.11.2/CryptoTokenKit/TKTokenConnection.m
/BuildRoot/Library/Caches/com.apple.xbs/Sources/CryptoTokenKit/CryptoTokenKit-408.11.2/CryptoTokenKit/TKTokenSession.m
/BuildRoot/Library/Caches/com.apple.xbs/Sources/CryptoTokenKit_Client/CryptoTokenKit-408.11.2/ctkclient/ctkclient.m

In Catalina CryptoTokenKit source code is at version 408.11.2.
It was at version 281.200.21 in Mojave 10.14.0, 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.

CCID


% grep -A 1 CFBundleShortVersionString /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
 <key>CFBundleShortVersionString</key>
 <string>1.4.31</string>

Apple updated the CCID driver from version 1.4.27 in Mojave to 1.4.31 in Catalina.

Version 1.4.31 is the latest version available. I released this version on August 10th 2019.

Conclusion

The smart card integration changed in macOS Catalina.

I may write about more specific details in other articles.

Monday, December 17, 2018

macOS Mojave and smart card source code

Apple released the source code of the open source components they use in Mojave (macOS 10.14, released in September 2018). The components are available at macOS X 10.14 Source.


Many smart card components are now closed source and maintained by Apple for its different OSes. I can cite:

CCID driver

Apple provides my Free Software CCID driver. The source code from Apple is available at:
Version 55017 corresponds to CCID version 1.4.27 and was already present in macOS High Sierra as noted in "macOS High Sierra and smart cards status".

    Tokend

    Apple still provides "support" of the tokend technology even if it is deprecated since OS X Lion (2011). The source code is provided at:
    The version 55111 has not changed since macOS Sierra. see "macOS Sierra and smart card source code".

    Conclusion

    No change in the free software component binaries so also no change in the corresponding component source codes.

    Tuesday, September 25, 2018

    macOS Mojave and smart cards status

    macOS Mojave (macOS 10.14) is now available since 24th September, 2018.


    API Differences between 10.13 and 10.14

    The differences should be listed in the developer page macOS Mojave 10.14.
    The changes for Mojave are not yet available.

    PC/SC

    Since Yosemite (10.10) the PC/SC layer is no more a fork of pcsc-lite. So comparing versions with pcsc-lite is useless.

    $ cat /System/Library/Frameworks/PCSC.framework/Versions/A/Resources/version.plist
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
     <key>BuildAliasOf</key>
     <string>CryptoTokenKit</string>
     <key>BuildVersion</key>
     <string>163</string>
     <key>CFBundleShortVersionString</key>
     <string>8.0</string>
     <key>CFBundleVersion</key>
     <string>1</string>
     <key>ProjectName</key>
     <string>SmartCardServices</string>
     <key>SourceVersion</key>
     <string>281200021000000</string>
    </dict>
    </plist>
    

    The BuildVersion moved from 10 in Sierra 10.13.6 to 163 in Mojave 10.14.0. Maybe Apple made 163 - 10 = 153 internal/alpha/beta releases?

    The SourceVersion moved from 281050022000000 in High Sierra 10.13.6 to 281200021000000 in Mojave 10.14.0. I have no idea how to parse or use this information.

    PC/SC Bugs fixed

    These bugs were found in High Sierra are now fixed in Mojave:
    • Typo in error message from PC/SC call pcsc_stringify_error(), bug #40995115.
      pcsc_stringify_error() returned "Unkown error" instead of ""UnkNown error" for unknown error codes.
    Maybe some other PC/SC bugs (unknown by me) have been fixed.

    CryptoTokenKit

    CryptoTokenKit is the native smart card API since the complete rewrite in macOS Yosemite 10.10 (OS X Yosemite BETA and smart cards status).

    $ strings /System/Library/Frameworks/CryptoTokenKit.framework/CryptoTokenKit | grep BuildRoot
    /BuildRoot/Library/Caches/com.apple.xbs/Sources/CryptoTokenKit/CryptoTokenKit-281.200.21/CryptoTokenKit/TKToken.m
    /BuildRoot/Library/Caches/com.apple.xbs/Sources/CryptoTokenKit/CryptoTokenKit-281.200.21/CryptoTokenKit/TKSmartCard.m
    /BuildRoot/Library/Caches/com.apple.xbs/Sources/CryptoTokenKit/CryptoTokenKit-281.200.21/CryptoTokenKit/TKTokenSession.m

    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.

    CCID driver

    Driver version: 1.4.27.

    $ grep -A 1 CFBundleShortVersionString /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
     <key>CFBundleShortVersionString</key>
     <string>1.4.27</string>
    

    This is the exact same version as in Hight Sierra 10.13.0.

    Note that the CCID version 1.4.28 was released in October 2017 and version 1.4.29 in February 2018. Apple had plenty of time to upgrade the CCID driver. This is surprising.

    The current version of the CCID driver is 1.4.30. This version was released 5 days before Mojave so I was not expecting to see this version included in Mojave.

    Conclusion

    No much visible changes in the smart card layer in macOS Mojave.

    It is surprising Apple has not upgraded the CCID driver since the previous major version of macOS. I understand this major version of macOS is not a revolution but more a stabilisation of macOS.

    Friday, September 21, 2018

    macOS HighSierra bug: SCardEndTransaction() returns SCARD_W_RESET_CARD instead of SCARD_W_REMOVED_CARD

    This is part of the series: "macOS High Sierra and smart cards: known bugs"

    SCardEndTransaction() returns different error codes than on GNU/Linux and Windows

    SCardEndTransaction() on High Sierra returns error codes that are different than on GNU/Linux and Windows.

    SCardEndTransaction() returns SCARD_W_RESET_CARD after a card change

    On High Sierra SCardEndTransaction() returns SCARD_W_RESET_CARD if the card has been removed and inserted again in the reader.

    On GNU/Linux and Windows SCardEndTransaction() returns SCARD_W_REMOVED_CARD instead.

    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.

    See also

    Apple bug report #44672548 "PCSC SCardEndTransaction() returns SCARD_W_RESET_CARD instead of SCARD_W_REMOVED_CARD". Marked as duplicate of #23900844.

    This bug is very similar to previous bugs for other PC/SC functions:

    Sample code

    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    
    #ifdef __APPLE__
    #include <PCSC/winscard.h>
    #include <PCSC/wintypes.h>
    #else
    #include <winscard.h>
    #endif
    
    #define CHECK_RV(fct) if (SCARD_S_SUCCESS != rv) { printf(fct"() failed: %s (0x%08X)\n", pcsc_stringify_error(rv), rv); ret = 0; goto error; } else { printf(fct"(): OK\n"); }
    
    int main(void)
    {
        int ret = 1;
        SCARDCONTEXT hContext;
        SCARDHANDLE hCard;
        DWORD dwActiveProtocol;
        LONG rv;
        char mszReaders[1024];
        DWORD dwReaders = sizeof(mszReaders);
    
        rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
        CHECK_RV("SCardEstablishContext");
    
        rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
        CHECK_RV("SCardListReaders");
    
        rv = SCardConnect(hContext, mszReaders, SCARD_SHARE_SHARED,
            SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard,
            &dwActiveProtocol);
        CHECK_RV("SCardConnect");
    
        rv = SCardBeginTransaction(hCard);
        CHECK_RV("SCardBeginTransaction");
    
        printf("Remove and insert the card. Then press Enter");
        getchar();
    
        rv = SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
        CHECK_RV("SCardEndTransaction");
    
        rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
        CHECK_RV("SCardDisconnect")
    
        rv = SCardReleaseContext(hContext);
        CHECK_RV("SCardReleaseContext")
    
    error:
        return ret;
    }
    

    Result (on High Sierra)

    $ ./main_Mac 
    SCardEstablishContext(): OK
    SCardListReaders(): OK
    SCardConnect(): OK
    SCardBeginTransaction(): OK
    Remove and insert the card. Then press Enter
    SCardEndTransaction() failed: Card was reset. (0x80100068)

    Expected result (on Debian)

    $ ./main_Linux 
    SCardEstablishContext(): OK
    SCardListReaders(): OK
    SCardConnect(): OK
    SCardBeginTransaction(): OK
    Remove and insert the card. Then press Enter
    SCardEndTransaction() failed: Card was removed. (0x80100069)

    Known workaround

    None known.

    macOS HighSierra bug: SCardStatus() returns SCARD_W_RESET_CARD instead of SCARD_W_REMOVED_CARD

    This is part of the series: "macOS High Sierra and smart cards: known bugs"

    SCardStatus() returns different error codes than on GNU/Linux and Windows

    SCardStatus() on High Sierra returns error codes that are different than on GNU/Linux and Windows.

    SCardStatus() returns SCARD_W_RESET_CARD after a card change

    On High Sierra SCardStatus() returns SCARD_W_RESET_CARD if the card has been removed and inserted again in the reader.

    On GNU/Linux and Windows SCardStatus() returns SCARD_W_REMOVED_CARD instead.

    See also

    Apple bug report #44672224 "PC/SC SCardStatus() returns SCARD_W_RESET_CARD instead of SCARD_W_REMOVED_CARD". Marked as duplicate of #23900844.

    This bug is very similar to previous bugs about SCardTransmit() ("macOS HighSierra bug: SCardTransmit() returns different error codes than on GNU/Linux and Windows") and SCardBeginTransaction() ("OS X El Capitan bug: SCardBeginTransaction() returns different error codes than on GNU/Linux and Windows").

    Sample code

    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    
    #ifdef __APPLE__
    #include <PCSC/winscard.h>
    #include <PCSC/wintypes.h>
    #else
    #include <winscard.h>
    #endif
    
    #define CHECK_RV(fct) if (SCARD_S_SUCCESS != rv) { printf(fct"() failed: %s (0x%08X)\n", pcsc_stringify_error(rv), rv); ret = 0; goto error; } else { printf(fct"(): OK\n"); }
    
    int main(void)
    {
        int ret = 1;
        SCARDCONTEXT hContext;
        SCARDHANDLE hCard;
        DWORD dwActiveProtocol;
        LONG rv;
        char mszReaders[1024];
        DWORD dwReaders = sizeof(mszReaders);
    
        rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
        CHECK_RV("SCardEstablishContext");
    
        rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
        CHECK_RV("SCardListReaders");
    
        rv = SCardConnect(hContext, mszReaders, SCARD_SHARE_SHARED,
            SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard,
            &dwActiveProtocol);
        CHECK_RV("SCardConnect");
    
        printf("Remove and insert the card. Then press Enter");
        getchar();
    
        DWORD chReaderLen = 100;
        DWORD dwState;
        DWORD dwProtocol;
        BYTE bAtr[33];
        DWORD cbAtrLen = sizeof bAtr;
        rv = SCardStatus(hCard, mszReaders, &chReaderLen, &dwState, &dwProtocol,
            bAtr, &cbAtrLen);
        CHECK_RV("SCardStatus");
    
        rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
        CHECK_RV("SCardDisconnect")
    
        rv = SCardReleaseContext(hContext);
        CHECK_RV("SCardReleaseContext")
    
    error:
        return ret;
    }
    

    Result (on High Sierra)

    $ ./main_Mac 
    SCardEstablishContext(): OK
    SCardListReaders(): OK
    SCardConnect(): OK
    Remove and insert the card. Then press Enter
    SCardStatus() failed: Card was reset. (0x80100068)

    Expected result (on Debian)

    $ ./main_Linux 
    SCardEstablishContext(): OK
    SCardListReaders(): OK
    SCardConnect(): OK
    Remove and insert the card. Then press Enter
    SCardStatus() failed: Card was removed. (0x80100069)

    Known workaround

    None known.

    macOS High Sierra and smart cards: known bugs

    High Sierra: macOS 10.13

    As I did for Yosemite 10.10 ("OS X Yosemite and smart cards: known bugs") and El Capitan 10.11 ("OS X El Capitan and smart cards: known bugs") I propose to maintain a list of know issues in PC/SC on macOS High Sierra 10.13.

    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.
    1. OS X El Capitan bug: PC/SC is not unusable after fork() (reported in November 2015)
    2. OS X El Capitan bug: SCardBeginTransaction() returns different error codes than on GNU/Linux and Windows (reported in December 2015)
    3. macOS HighSierra bug: SCardTransmit() returns different error codes than on GNU/Linux and Windows (reported in September 2018)
    4. macOS HighSierra bug: SCardStatus() returns SCARD_W_RESET_CARD instead of SCARD_W_REMOVED_CARD (reported in September 2018)
    5. macOS HighSierra bug: SCardEndTransaction() returns SCARD_W_RESET_CARD instead of SCARD_W_REMOVED_CARD (reported in September 2018)

    Missing features

    The missing features are not bugs but services provided but the PC/SC API on Windows and GNU/Linux that would be nice to also have on macOS.
    1. OS X El Capitan missing feature: SCardGetStatusChange() and number of card events (reported in December 2015)
    2. OS X El Capitan missing feature: SCardGetStatusChange() and "\\?PnP?\Notification" (reported in December 2015)
    3. OS X El Capitan missing feature: add support of TAG_IFD_POLLING_THREAD_WITH_TIMEOUT (reported in December 2015)

    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.

    Thursday, September 20, 2018

    macOS HighSierra bug: SCardTransmit() returns different error codes than on GNU/Linux and Windows

    This is part of the series: "macOS High Sierra and smart cards: known bugs"

    SCardTransmit() returns different error codes than on GNU/Linux and Windows

    SCardTransmit() on High Sierra returns error codes that are different than on GNU/Linux and Windows.

    SCardTransmit() returns SCARD_W_RESET_CARD after a card change

    On High Sierra SCardTransmit() returns SCARD_W_RESET_CARD if the card has been removed and inserted again in the reader.

    On GNU/Linux and Windows SCardTransmit() returns SCARD_W_REMOVED_CARD instead.

    See also

    Apple bug report #44638067 "PC/SC SCardTransmit() returns different error codes than on GNU/Linux and Windows". Marked as duplicate of #23900844.

    This bug is very similar to a previous bug I found in El Capitan in 2015 "OS X El Capitan bug: SCardBeginTransaction() returns different error codes than on GNU/Linux and Windows". It is the same effects for the same behaviour but now with SCardTransmit() instead of SCardBeginTransaction().

    The previous bug has been reported to Apple as bug report #23900844 and is still not closed (or fixed or discussed).

    Sample code

    #! /usr/bin/env python3
    
    from smartcard.System import readers
    from smartcard.util import toBytes
    
    import sys
    try:
        r = int(sys.argv[1])
    except IndexError as e:
        r = 0
    
    reader = readers()[r]
    print("Using:", reader)
    
    connection = reader.createConnection()
    connection.connect()
    
    input("Remove and insert the card. Then press Enter")
    
    # Any APDU will work
    apdu = toBytes("00 00 00 00 00")
    response = connection.transmit(apdu)
    print(response)
    

    Result (on High Sierra)

    $ ./transmit_remove_card.py 
    Using: Gemalto PC Twin Reader
    Remove and insert the card. Then press Enter
    Traceback (most recent call last):
      File "./transmit_remove_card.py", line 22, in 
        response = connection.transmit(apdu)
      File "/usr/local/lib/python3.7/site-packages/pyscard-1.9.7-py3.7-macosx-10.13-x86_64.egg/smartcard/CardConnectionDecorator.py", line 82, in transmit
        return self.component.transmit(bytes, protocol)
      File "/usr/local/lib/python3.7/site-packages/pyscard-1.9.7-py3.7-macosx-10.13-x86_64.egg/smartcard/CardConnection.py", line 146, in transmit
        data, sw1, sw2 = self.doTransmit(bytes, protocol)
      File "/usr/local/lib/python3.7/site-packages/pyscard-1.9.7-py3.7-macosx-10.13-x86_64.egg/smartcard/pcsc/PCSCCardConnection.py", line 203, in doTransmit
        SCardGetErrorMessage(hresult))
    smartcard.Exceptions.CardConnectionException: Failed to transmit with protocol T0. Card was reset.

    Expected result (on Debian)


    $ ./transmit_remove_card.py
    Using: Gemalto PC Twin Reader (70D7E2EE) 00 00
    Remove and insert the card. Then press Enter
    Traceback (most recent call last):
      File "./transmit_remove_card.py", line 22, in 
        response = connection.transmit(apdu)
      File "/usr/lib/python3/dist-packages/smartcard/CardConnectionDecorator.py", line 82, in transmit
        return self.component.transmit(bytes, protocol)
      File "/usr/lib/python3/dist-packages/smartcard/CardConnection.py", line 146, in transmit
        data, sw1, sw2 = self.doTransmit(bytes, protocol)
      File "/usr/lib/python3/dist-packages/smartcard/pcsc/PCSCCardConnection.py", line 205, in doTransmit
        SCardGetErrorMessage(hresult))
    smartcard.Exceptions.CardConnectionException: Failed to transmit with protocol T0. Card was removed.

    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

    None known.

    An idea would be to use the dwEventState field of SCardGetStatusChange(). From the pcsc-lite documentation:
    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()

    Unfortunately Apple PC/SC does not support this feature. I reported the missing feature to Apple in bug report #23937633 and "OS X El Capitan missing feature: SCardGetStatusChange() and number of card events" in 2015. But nothing moved since then.

    Wednesday, September 12, 2018

    Smart card integration in macOS Sierra: CryptoTokenKit plugin

    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.

    OpenSCToken: Use OpenSC in CryptoTokenKit by Frank Morgner is a CryptoTokenKit plugin that works with OpenSC.

    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.

    Comparison with OpenSC.tokend

    From the website project:
    • OpenSCToken supports multiple certificates, keys and PINs
    • OpenSCToken has proper support for PIN pad on reader or token
    • OpenSCToken offers easy login with smart card and automatically unlocks the login keychain
    • Tokens are not visible in Keychain Access any more (use sc_auth/security from command line instead)
    • Most non-Apple applications do not yet support CryptoTokenKit. If OpenSCToken is used together with OpenSC.tokend, your token will appear twice in Safari and other Apple-apps.

    Check installation

    To check if the plugin is installed you can use the pluginkit command line tool.

    Before installation:
    $ pluginkit -m -p com.apple.ctk-tokens
         com.apple.CryptoTokenKit.setoken(1.0)
         com.apple.CryptoTokenKit.pivtoken(1.0)

    After installation:
    $ pluginkit -m -p com.apple.ctk-tokens
         org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken(1.0)
         com.apple.CryptoTokenKit.pivtoken(1.0)
         com.apple.CryptoTokenKit.setoken(1.0)

    Verbose

    You can have more verbose output.

    Before installation:
    $ pluginkit -v -m -p com.apple.ctk-tokens
         com.apple.CryptoTokenKit.setoken(1.0) 4D0E5BB3-D45E-42A1-A0AE-24E0D71A6149 2018-07-12 16:37:44 +0000 /System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/setoken.appex
         com.apple.CryptoTokenKit.pivtoken(1.0) A0B7E31C-443B-4B89-9D57-98D6A3736B86 2018-07-12 16:37:44 +0000 /System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/pivtoken.appex
     (2 plug-ins)

    After installation:
    $ pluginkit -v -m -p com.apple.ctk-tokens
         org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken(1.0) 327C0A2C-4A43-4BB6-B858-73594115DCFA 2018-09-09 14:58:30 +0000 /Applications/OpenSCTokenApp.app/Contents/PlugIns/OpenSCToken.appex
         com.apple.CryptoTokenKit.pivtoken(1.0) A0B7E31C-443B-4B89-9D57-98D6A3736B86 2018-07-12 16:37:44 +0000 /System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/pivtoken.appex
         com.apple.CryptoTokenKit.setoken(1.0) 4D0E5BB3-D45E-42A1-A0AE-24E0D71A6149 2018-07-12 16:37:44 +0000 /System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/setoken.appex
     (3 plug-ins)

    This more verbose output allows you to know where on disk the plugin is found.
    To remove/uninstall the plugin you just have to delete the application containing/providing the plugin.

    Verbose + +

    Or an even more verbose output:

    Before installation:
    $ pluginkit -vv -m -p com.apple.ctk-tokens
         com.apple.CryptoTokenKit.setoken(1.0)
                 Path = /System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/setoken.appex
                 UUID = 4D0E5BB3-D45E-42A1-A0AE-24E0D71A6149
            Timestamp = 2018-07-12 16:37:44 +0000
                  SDK = com.apple.ctk-tokens
         Display Name = Secure Enclave Private Key Storage
           Short Name = setoken
    
         com.apple.CryptoTokenKit.pivtoken(1.0)
                 Path = /System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/pivtoken.appex
                 UUID = A0B7E31C-443B-4B89-9D57-98D6A3736B86
            Timestamp = 2018-07-12 16:37:44 +0000
                  SDK = com.apple.ctk-tokens
         Display Name = Personal Identity Verification token driver
           Short Name = pivtoken
    
     (2 plug-ins)

    After installation:
    $ pluginkit -vv -m -p com.apple.ctk-tokens
         org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken(1.0)
                 Path = /Applications/OpenSCTokenApp.app/Contents/PlugIns/OpenSCToken.appex
                 UUID = 327C0A2C-4A43-4BB6-B858-73594115DCFA
            Timestamp = 2018-09-09 14:58:30 +0000
                  SDK = com.apple.ctk-tokens
        Parent Bundle = /Applications/OpenSCTokenApp.app
         Display Name = OpenSC token driver
           Short Name = OpenSCToken
          Parent Name = OpenSCTokenApp
    
         com.apple.CryptoTokenKit.pivtoken(1.0)
                 Path = /System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/pivtoken.appex
                 UUID = A0B7E31C-443B-4B89-9D57-98D6A3736B86
            Timestamp = 2018-07-12 16:37:44 +0000
                  SDK = com.apple.ctk-tokens
         Display Name = Personal Identity Verification token driver
           Short Name = pivtoken
    
         com.apple.CryptoTokenKit.setoken(1.0)
                 Path = /System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/setoken.appex
                 UUID = 4D0E5BB3-D45E-42A1-A0AE-24E0D71A6149
            Timestamp = 2018-07-12 16:37:44 +0000
                  SDK = com.apple.ctk-tokens
         Display Name = Secure Enclave Private Key Storage
           Short Name = setoken
    
     (3 plug-ins)

    List inserted token

    If your smart card is supported by one of the installed CryptoTokenKit plugin you will see it using the command "security list-smartcards".

    $ security list-smartcards
    org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310

    Card content

    There is different ways to display the content of the card.

    system_profiler SPSmartCardsDataType

    $ system_profiler SPSmartCardsDataType
    
        Readers:
    
          #01: Cherry KC 1000 SC Z (ATR:<3b9f9581 00000081="" 300671df="" 31fe9f00="" 6112c4="" 65465305="">)
    
        Reader Drivers:
    
          #01: org.debian.alioth.pcsclite.smartcardccid:1.4.27 (/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle)
    
        Tokend Drivers:
    
          #01: com.apple.tokend.opensc:1.0 (/Library/Security/tokend/OpenSC.tokend)
    
        SmartCard Drivers:
    
          #01: org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:1.0 (/Applications/OpenSCTokenApp.app/Contents/PlugIns/OpenSCToken.appex)
          #02: com.apple.CryptoTokenKit.pivtoken:1.0 (/System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/pivtoken.appex)
    
        Available SmartCards (keychain):
    
            org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310:
    
              #01: Kind: private RSA 2048-bit, Certificate: <0b1bea81 4ee563aa="" ab26c4c8="" c7f82472="" d70c33d5="">, Usage: Sign Decrypt Unwrap 
    Valid from: 2018-09-09 19:50:20 +0000 to: 2019-03-08 19:50:20 +0000, SSL trust: NO, X509 trust: YES 
    
    -----BEGIN CERTIFICATE-----
    MIIFlTCCA32gAwIBAgIDE8gaMA0GCSqGSIb3DQEBCwUAMHkxEDAOBgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSc3VwcG9ydEBjYWNlcnQub3JnMB4XDTE4MDkwOTE5NTAyMFoXDTE5MDMwODE5NTAyMFowTDEYMBYGA1UEAxMPQ0FjZXJ0IFdvVCBVc2VyMTAwLgYJKoZIhvcNAQkBFiFsdWRvdmljLnJvdXNzZWF1K2NhY2VydEBnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcW791p4I7wPdDTpHFzSNQwGvDlbOT5zYqSGTU1EeUNMewgj0KaGGcA9tEPD5B6U089/28QpJDU7LJb1bZygasl5VJxznXofZYP4GLerw8SMKfGPB5M3Yq9Wtxq8A282uzzfH9evvpQDoPxc03FZTyESeF1pr2y1oCNO4tvyd6hQc90zPdmzuXY2I/JwfhF6lJR/NaIFtpUqLJoRgN+pNwWjxvtQx5sjdWnFHW7R1/x+enp2eLTPTt2FRaSOdnCZVx9CNJw0BGTrzjHewp9kbdvLS3/A23ZPa4z+WUxNj4p3AgxJ3vh/VoRD3EhPpyvcfEgS7PWPHWHhKV5Z1CNFz5AgMBAAGjggFRMIIBTTAMBgNVHRMBAf8EAjAAMFYGCWCGSAGG+EIBDQRJFkdUbyBnZXQgeW91ciBvd24gY2VydGlmaWNhdGUgZm9yIEZSRUUgaGVhZCBvdmVyIHRvIGh0dHA6Ly93d3cuQ0FjZXJ0Lm9yZzAOBgNVHQ8BAf8EBAMCA6gwQAYDVR0lBDkwNwYIKwYBBQUHAwQGCCsGAQUFBwMCBgorBgEEAYI3CgMEBgorBgEEAYI3CgMDBglghkgBhvhCBAEwMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vb2NzcC5jYWNlcnQub3JnMDEGA1UdHwQqMCgwJqAkoCKGIGh0dHA6Ly9jcmwuY2FjZXJ0Lm9yZy9yZXZva2UuY3JsMCwGA1UdEQQlMCOBIWx1ZG92aWMucm91c3NlYXUrY2FjZXJ0QGdtYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOCAgEAAsGk23KL8OmpUmnS+rAQOEuHhcJ2gBNgR8Au83QmJKlpmyJD190UIJARd0QPp7583bt3c0iOMw2qtXSDkiFmo/ngyed02UYFSxWRUsoi8RmF8Rjv/xw797vVlO1zbiMcra91Ftf53ylCtGhhoNxyso4lkwXKCJuKUD4+8f02QvpNgG/WE3YtZ2WWiTa2RaXtoTWY3gU1TZVuW1CV7aHbA/xx+Gv/YK/WtMZYvHNmcppfuRsmw4hIGWyibZ073Nsn7DglictRTrNGI4+yJSR8MV53mkhBJHmXRtOJNvLV9vEcnF6qpxd5kMJiTFr6RzQJb86lIebhXlb6RjtbhNZSR0WESnRYzxjgNIkVtwUBamm94JoY1SUJDqS/totB147oRGzD+ha3scq+ZbM5MMniZM2qUbk6nnbiswPBFYo45nQcMGx++q9WoYGsf0euDzhVMKC7uHaIUHcaI1xlJpSoxR6GIOqqcoNRvPSJQy6DSosewBqhnRps6eSUTuqAD5cen9o16zba1T8iiIch5PeI/GbteokSpwSCH/21wjzMdCc8Q2/WHPWfrbyPuB5ymVmXbYZAD3sGcNh0ukzeEFJ2tuTGavtDil3Yka3C0EfLqKdykDPZtwXg9maCV8i6IQUBW3ty10ms5HRc/U2UaG0j+xx53dMxjl3idZmJN/FVOOM=
    -----END CERTIFICATE-----
    
    
        Available SmartCards (token):
    
            org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310:
    
              #01: Kind: private RSA 2048-bit, Certificate: <0b1bea81 4ee563aa="" ab26c4c8="" c7f82472="" d70c33d5="">, Usage: Sign Decrypt Unwrap 
    Valid from: 2018-09-09 19:50:20 +0000 to: 2019-03-08 19:50:20 +0000, SSL trust: NO, X509 trust: YES 
    
    -----BEGIN CERTIFICATE-----
    MIIFlTCCA32gAwIBAgIDE8gaMA0GCSqGSIb3DQEBCwUAMHkxEDAOBgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSc3VwcG9ydEBjYWNlcnQub3JnMB4XDTE4MDkwOTE5NTAyMFoXDTE5MDMwODE5NTAyMFowTDEYMBYGA1UEAxMPQ0FjZXJ0IFdvVCBVc2VyMTAwLgYJKoZIhvcNAQkBFiFsdWRvdmljLnJvdXNzZWF1K2NhY2VydEBnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcW791p4I7wPdDTpHFzSNQwGvDlbOT5zYqSGTU1EeUNMewgj0KaGGcA9tEPD5B6U089/28QpJDU7LJb1bZygasl5VJxznXofZYP4GLerw8SMKfGPB5M3Yq9Wtxq8A282uzzfH9evvpQDoPxc03FZTyESeF1pr2y1oCNO4tvyd6hQc90zPdmzuXY2I/JwfhF6lJR/NaIFtpUqLJoRgN+pNwWjxvtQx5sjdWnFHW7R1/x+enp2eLTPTt2FRaSOdnCZVx9CNJw0BGTrzjHewp9kbdvLS3/A23ZPa4z+WUxNj4p3AgxJ3vh/VoRD3EhPpyvcfEgS7PWPHWHhKV5Z1CNFz5AgMBAAGjggFRMIIBTTAMBgNVHRMBAf8EAjAAMFYGCWCGSAGG+EIBDQRJFkdUbyBnZXQgeW91ciBvd24gY2VydGlmaWNhdGUgZm9yIEZSRUUgaGVhZCBvdmVyIHRvIGh0dHA6Ly93d3cuQ0FjZXJ0Lm9yZzAOBgNVHQ8BAf8EBAMCA6gwQAYDVR0lBDkwNwYIKwYBBQUHAwQGCCsGAQUFBwMCBgorBgEEAYI3CgMEBgorBgEEAYI3CgMDBglghkgBhvhCBAEwMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vb2NzcC5jYWNlcnQub3JnMDEGA1UdHwQqMCgwJqAkoCKGIGh0dHA6Ly9jcmwuY2FjZXJ0Lm9yZy9yZXZva2UuY3JsMCwGA1UdEQQlMCOBIWx1ZG92aWMucm91c3NlYXUrY2FjZXJ0QGdtYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOCAgEAAsGk23KL8OmpUmnS+rAQOEuHhcJ2gBNgR8Au83QmJKlpmyJD190UIJARd0QPp7583bt3c0iOMw2qtXSDkiFmo/ngyed02UYFSxWRUsoi8RmF8Rjv/xw797vVlO1zbiMcra91Ftf53ylCtGhhoNxyso4lkwXKCJuKUD4+8f02QvpNgG/WE3YtZ2WWiTa2RaXtoTWY3gU1TZVuW1CV7aHbA/xx+Gv/YK/WtMZYvHNmcppfuRsmw4hIGWyibZ073Nsn7DglictRTrNGI4+yJSR8MV53mkhBJHmXRtOJNvLV9vEcnF6qpxd5kMJiTFr6RzQJb86lIebhXlb6RjtbhNZSR0WESnRYzxjgNIkVtwUBamm94JoY1SUJDqS/totB147oRGzD+ha3scq+ZbM5MMniZM2qUbk6nnbiswPBFYo45nQcMGx++q9WoYGsf0euDzhVMKC7uHaIUHcaI1xlJpSoxR6GIOqqcoNRvPSJQy6DSosewBqhnRps6eSUTuqAD5cen9o16zba1T8iiIch5PeI/GbteokSpwSCH/21wjzMdCc8Q2/WHPWfrbyPuB5ymVmXbYZAD3sGcNh0ukzeEFJ2tuTGavtDil3Yka3C0EfLqKdykDPZtwXg9maCV8i6IQUBW3ty10ms5HRc/U2UaG0j+xx53dMxjl3idZmJN/FVOOM=
    -----END CERTIFICATE-----

    I also installed the OpenSC_0.18.dmg package so the OpenSC tokend (using the deprecated API) is also installed.

    security export-smartcard

    $ security export-smartcard
    
    ==== certificate #1
     class : "cert"
     subj : <31 18 30 16 06 03 55 04 03 13 0f 43 41 43 45 52 54 20 57 4f 54 20 55 53 45 52 31 30 30 2e 06 09 2a 86 48 86 f7 0d 01 09 01 16 21 6c 75 64 6f 76 69 63 2e 72 6f 75 73 73 65 61 75 2b 63 61 63 65 72 74 40 67 6d 61 69 6c 2e 63 6f 6d>
     cenc : 3
     ctyp : 3
     pkhh : <0b 1b ea 81 4e e5 63 aa d7 0c 33 d5 c7 f8 24 72 ab 26 c4 c8>
     persistref : <>
     agrp : "com.apple.token"
     pdmn : "dk"
     labl : "User PIN (Ludovic Rousseau):ID Root CA de CAcert WoT User (CAcert WoT User)"
     UUID : "B997A93B-052E-4DB0-80B8-46A23A455085"
     mdat : 2018-09-09 19:55:07 +0000
     slnr : <13 c8 1a>
     sync : 0
     sha1 : <04 df f6 71 9e ad 56 97 96 81 6c b5 8b 46 a4 08 cd e0 65 35>
     tkid : "org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310"
     musr : <>
     cdat : 2018-09-09 19:55:07 +0000
     tomb : 0
     issr : <31 10 30 0e 06 03 55 04 0a 13 07 52 4f 4f 54 20 43 41 31 1e 30 1c 06 03 55 04 0b 13 15 48 54 54 50 3a 2f 2f 57 57 57 2e 43 41 43 45 52 54 2e 4f 52 47 31 22 30 20 06 03 55 04 03 13 19 43 41 20 43 45 52 54 20 53 49 47 4e 49 4e 47 20 41 55 54 48 4f 52 49 54 59 31 21 30 1f 06 09 2a 86 48 86 f7 0d 01 09 01 16 12 73 75 70 70 6f 72 74 40 63 61 63 65 72 74 2e 6f 72 67>
     accc : constraints: {
       ord : true
      }
      protection: {
       tkid : "org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310"
      }
    ====
    
    ==== private key #1
     crtr : 0
     esiz : 0
     decr : 1
     persistref : <>
     atag : ""
     kcls : 1
     agrp : "com.apple.token"
     pdmn : "dk"
     bsiz : 2 048
     type : 42
     klbl : <0b 1b ea 81 4e e5 63 aa d7 0c 33 d5 c7 f8 24 72 ab 26 c4 c8>
     edat : 2001-01-01 00:00:00 +0000
     sign : 1
     mdat : 2018-09-09 19:55:07 +0000
     drve : 0
     labl : "User PIN (Ludovic Rousseau):ID Root CA de CAcert WoT User (CAcert WoT User)"
     sync : 0
     musr : <>
     sha1 : <ed 9c 0f 96 fd e3 e0 ee 30 b9 d3 b1 23 13 8b 3c b0 8e 9c ad>
     cdat : 2018-09-09 19:55:07 +0000
     tkid : "org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310"
     sdat : 2001-01-01 00:00:00 +0000
     tomb : 0
     priv : 1
     accc : constraints: {
       od : <ff>,
       osgn : <ff>
      }
      protection: {
       tkid : "org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310"
      }
     unwp : 1
    ====
    
    ==== identity #1
     class : "idnt"
     slnr : <13 c8 1a>
     certdata : <CFData 0x7fdbb2007c00 [0x7fffa8c23af0]>{length = 1433, capacity = 1433, bytes = 0x308205953082037da003020102020313 ... 75998937f15538e3}
     certtkid : "org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310"
     priv : 1
     ctyp : 3
     mdat : 2018-09-09 19:55:07 +0000
     sdat : 2001-01-01 00:00:00 +0000
     bsiz : 2 048
     type : 42
     sha1 : <04 df f6 71 9e ad 56 97 96 81 6c b5 8b 46 a4 08 cd e0 65 35>
     pkhh : <0b 1b ea 81 4e e5 63 aa d7 0c 33 d5 c7 f8 24 72 ab 26 c4 c8>
     cdat : 2018-09-09 19:55:07 +0000
     tomb : 0
     UUID : "B997A93B-052E-4DB0-80B8-46A23A455085"
     persistref : <>
     accc : constraints: {
       od : <ff>,
       osgn : <ff>
      }
      protection: {
       tkid : "org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310"
      }
     sync : 0
     tkid : "org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310"
     subj : <31 18 30 16 06 03 55 04 03 13 0f 43 41 43 45 52 54 20 57 4f 54 20 55 53 45 52 31 30 30 2e 06 09 2a 86 48 86 f7 0d 01 09 01 16 21 6c 75 64 6f 76 69 63 2e 72 6f 75 73 73 65 61 75 2b 63 61 63 65 72 74 40 67 6d 61 69 6c 2e 63 6f 6d>
     pdmn : "dk"
     musr : <>
     sign : 1
     esiz : 0
     decr : 1
     atag : ""
     edat : 2001-01-01 00:00:00 +0000
     klbl : <0b 1b ea 81 4e e5 63 aa d7 0c 33 d5 c7 f8 24 72 ab 26 c4 c8>
     crtr : 0
     unwp : 1
     issr : <31 10 30 0e 06 03 55 04 0a 13 07 52 4f 4f 54 20 43 41 31 1e 30 1c 06 03 55 04 0b 13 15 48 54 54 50 3a 2f 2f 57 57 57 2e 43 41 43 45 52 54 2e 4f 52 47 31 22 30 20 06 03 55 04 03 13 19 43 41 20 43 45 52 54 20 53 49 47 4e 49 4e 47 20 41 55 54 48 4f 52 49 54 59 31 21 30 1f 06 09 2a 86 48 86 f7 0d 01 09 01 16 12 73 75 70 70 6f 72 74 40 63 61 63 65 72 74 2e 6f 72 67>
     cenc : 3
     kcls : 1
     agrp : "com.apple.token"
     labl : "User PIN (Ludovic Rousseau):ID Root CA de CAcert WoT User (CAcert WoT User)"
     drve : 0
    ====

    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.

    $ sudo id
    Enter PIN for 'User PIN (Ludovic Rousseau):ID Root CA de CAcert WoT User (CAcert WoT User)': 
    uid=0(root) gid=0(wheel) groups=0(wheel),1(daemon),2(kmem),3(sys),4(tty),5(operator),8(procview),9(procmod),12(everyone),20(staff),29(certusers),61(localaccounts),80(admin),702(2),705(5),703(3),701(1),33(_appstore),98(_lpadmin),100(_lpoperator),204(_developer),250(_analyticsusers),395(com.apple.access_ftp),398(com.apple.access_screensharing),399(com.apple.access_ssh),704(4)

    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.

    The OpenSCToken web site indicates a way to enable smart card use for the login screen. But this involves to disable the System Integrity Protection (SIP) and I think that is a bad idea.

    There is a way (maybe more) to enable a CryptoTokenKit plugin for the login screen without disabling SIP. I may write about it in another blog article.

    Conclusion

    I wanted to write about CryptoTokenKit plugin since a long time. There is still a lot to write regarding the development and use of a CryptoTokenKit plugin.

    If implemented and integrated correctly a CryptoTokenKit plugin should be very easy to use.