New PyKCS11 1.5.7 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.
See "PyKCS11 introduction" or "PyKCS11’s documentation".


1.5.7 - December 2019, Ludovic Rousseau
  • add missing files in the .tar.gz

1.5.6 - December 2019, Ludovic Rousseau
  • AppVeyor:
    • generate bdist_wheel
    • add Python 3.7 and 3.8
  • Sample add a -f/--full argument
  • Add support of CKM_AES_GCM mechanism
  • CPKCS11Lib::Load(): return different error codes
  • minor improvements

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 :-(


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.

tokend support is broken Catalina 10.15.1


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".

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.


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/ 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.


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" "">
<plist version="1.0">

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

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.


% grep -A 1 CFBundleShortVersionString /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist

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.


The smart card integration changed in macOS Catalina.

I may write about more specific details in other articles.

Parsing an ATR: old site decommisionned

I modified the web site at to automatically redirect to (after 10 seconds so you have some time to read the message).

The idea is to tell people that the service has moved. You should use only the new site now. See also "Parsing an ATR: new web site URL".

I do not want to use Google App Engine (GAE) any more and do not plan to maintain the old web site (hosted at GAE). So instead of giving access to an unmaintained code I redirect to the new and maintained web site.

Please update your bookmarks.

Parsing an ATR: new web site URL


Since the beginning (in 2009) the Smart card ATR parsing service was hosted on Google App Engine. This is because the Google service is/was free of charge and was a new technology to discover.

You can see the GUI evolution of the ATR parsing service in time from my previous blog articles:

Then I received an email from Google:
We’re writing to you to let you know that the legacy standalone App Engine SDK (appcfg) will be deprecated as of July 30, 2019, in favor of the Generally Available Google Cloud SDK (Cloud SDK).

You will need to migrate your projects off the legacy standalone SDK (appcfg) before the shutdown date of July 30, 2020. Projects included in this email will be whitelisted to use the legacy standalone SDK (appcfg) until July 30, 2020, but any new projects will not be able to use the legacy standalone SDK (appcfg) from July 30, 2019.


In the migration to the Google Cloud SDK I wanted to also migrate from Python 2 to Python 3, and from Bootstrap 3 to Bootstrap 4.  But then I discovered that I would have to migrate from webapp to Flask (not a bad idea) and that some Google API I used were not available for Python 3:
  • user identification
  • sending email
I also discovered that it is not possible to deploy an application using the new SDK without creating a billing account. I had to give my credit card number to Google. Google offers US $300 for 1 year but I do not plan to play extra money for this free service.

Note: if you want to help me see "How to help my projects? Send me bitcoins!" or contact me directly.


The problem is that I use mail service to send me an email when a new ATR is submitted, and I use the user identification service to get the user login so I can contact him/her in case the card description is incorrect.

Backup plan

I tried to use the smtplib Python module to send emails. The code works fine in local/debug mode but not when deployed in Google cloud. I have no idea why it failed.
Problem: I deployed the non-working solution over the normal service (yes, bad idea). So the service was broken and I needed a solution (very) quickly.

Self hosting

Since no Google services I used was available any more, the new solution was using only free software dependencies. And the smtplib solution was not working on Google cloud.

The solution was to host the ATR parsing service myself.

New service

The service is now available at

The old URL is still available for now. I plan to change the main page with a redirection to the new URL at some point.

Contact me if you find a problem or want to discuss an evolution of the service.


Google forced me to migrate.
I don't think it was in their plans to force me to migrate outside of their cloud services 😉.

Improved security of {muscle,pcsclite,ccid} websites

I recently discovered the Mozilla Observatory service:

The Mozilla HTTP Observatory is a set of tools to analyze your website and inform you if you are utilizing the many available methods to secure it.


Initially the 3 websites, and I manage had a very bad score of F or 20/100.

F is is worst score. So I needed to do something to improve the situation and the security a bit.


After some configuration of the web server and some minor update of the web pages I now get a score of A+ or 110/100.

If you find something broken on the web sites please tell me. I may have missed something.


I think I could still improve the security. If you have ideas of what to do just tell me.

ISO 7816-4 spy using Wireshark

In a previous blog article "CCID USB spy using Wireshark" I documented how to use Wireshark to analyse USB CCID packets.

It is also possible to continue the packet decoding to show ISO 7816-4 format commands.

Raw USB packets

By default you will get USB packets.

CCID packets

Enable the USBCCID decoder in the Wireshark menu Analyze -> Decode as...
You will then see CCID packets.
But APDUs sent to the reader may be hard to read is you do not decode ISO 7816-4 directly in your head.
All we get here is Data: 00 a4 04 00 0b a0 00 00 03 97 43 49 44 5f 01 00

ISO 7816 commands

Now enable the ISO 7816 decoder.
And you will see ISO 7816-4 command names.
Here you see that the APDU 00 a4 04 00 0b a0 00 00 03 97 43 49 44 5f 01 00 is a "Select file" (the second byte, INS byte, is 0xA4)


Not all the CCID packets are decoded.

For example the Secure command (0x69) is not (yet) decoded.
Only the first CCID byte is decoded as "Message Type: PC_to_RDR_Secure (0x69)". The remaining of the CCID frame is not decoded. And this command is not easy to decode by hand without the CCID specification.

This CCID Secure command is used with a pinpad reader to make the user enter its PIN code in the pinpad and not on the computer keyboard. See here for a list of pinpad readers working with my CCID driver.
The Secure command uses parameters to set the PIN padding, the messages displayed to the user, the min and max PIN lengths, the validation conditions and some other parameters. Not all pinpad readers support the same set of parameters so the situation is complex.

Windows support

In my previous article "CCID USB spy using Wireshark" I make the USB trace acquisition on a GNU/Linux system.

This time I made the capture on Windows, saved the file on disk (.pcapng format) and used Wireshark on macOS to study the file. Yes, I prefer to NOT use Windows as much as possible.

So whatever the system you are using (GNU/Linux, macOS or Windows, and maybe others) Wireshark can help you.


Wireshark is a very nice tool. I should use it more often to debug issues and understand why a program is working on Windows and not on GNU/Linux. It can be used to do some reverse engineering, especially with complex CCID commands like the Secure command.

New version of libccid: 1.4.31

I just released a version 1.4.31 of libccid the Free Software CCID class smart card reader driver.


1.4.31 - 10 August 2019, Ludovic Rousseau
  • Add support of
    • ACS ACR1252 Reader
    • Aladdin R.D. JaCartaReader
    • Alcor Link AK9563
    • AvestUA AvestKey
    • Avtor SecureToken (idProduct: 0x0020)
    • Bit4id TokenME EVO v2
    • Bit4id miniLector AIR EVO
    • Bit4id miniLector Blue
    • Broadcom Corp 58200 (idProduct: 0x5843)
    • Broadcom Corp 58200 (idProduct: 0x5844)
    • Broadcom Corp 58200 (idProduct: 0x5845)
    • Certgate GmbH ONEKEY ID 2 USB
    • HID Global Crescendo Key 0x0028
    • HID Global Crescendo Key 0x0029
    • HID Global Crescendo Key 0x002B
    • HID Global Crescendo Key 0x002D
    • Identiv SCR3500 C Contact Reader
    • InfoCert WirelessKey
    • NXP PN7462AU CCID
    • Route1 MobiKEY Fusion3
  • MacOSX/configure: fix checking error for dynamic library libusb
  • Some minor improvements for debug

PySCard 1.9.9 released

I just released a new version 1.9.9 of pyscard. PySCard is a python module adding smart cards support (PC/SC) to Python.

The PySCard project is available at:


1.9.9 (August 2019)
  • Makefile: use twine to upload to
  • test: fix Exception test on 32-bits CPU
  • test: correctly handle macOS versions older than 10.10