Friday, December 9, 2016

New version of pcsc-lite: 1.8.19

I just released a new version of pcsc-lite 1.8.19.
pcsc-lite is a Free Software implementation of the PC/SC (or WinSCard) API for Unix systems.

1.8.19: Ludovic Rousseau
9 December 2016
  • SCardGetStatusChange(): Fix a (rare) race condition
  • Doxygen:
    • SCardGetStatusChange() may return SCARD_E_UNKNOWN_READER
    • SCardConnect() and SCardReconnect() will never return SCARD_E_NOT_READY
  • pcsc-spy:
    • fix display of execution time
    • log the thread number in the results
  • Some other minor improvements

Wednesday, December 7, 2016

macOS Sierra and pam_smartcard

In Sierra a new smart card component has been introduced: pam_smartcard. PAM is Pluggable Authentication Modules.

The source code is available at macOS 10.12 Source and is part of the pam_modules component.


The pam_smartcard(8) manage is:
pam_smartcard(8)          BSD System Manager's Manual         pam_smartcard(8)

     pam_smartcard -- Smartcard PAM module

     [service-name] function-class control-flag pam_smartcard [options]

     The Smartcard PAM module supports authentication function class.  In
     terms of the function-class parameter, this is ``auth.''

   The Smartcard Authentication Module
     This module permits or denies users based on smartcard authentication
     support in the Open Directory database, and the presence of an appropri-
     ate smartcard in the reader attached to the local machine. When a card is
     locked, the user is asked to unlock it with his PIN.

   The following options may be passed to this account management module:
             Continues evaluation even if user's shell is not valid. Normally,
             users with a shell like /usr/bin/false are considered as dis-

     Adding the following line on the top of the /etc/pam.d/sudo enables smartcard support for sudo:
             auth   sufficient

     pam.conf(5), pam(8) SmartCardServices(7)

BSD                             August 27, 2015                            BSD

I guess this is related to the introduction of the native support of PIV cards in Sierra. See "macOS Sierra and PIVToken source code".

The pam_smartcard PAM module is used by two services by default:
  • authorization_ctk
  • screensaver_ctk
$ grep pam_smartcard /etc/pam.d/*
/etc/pam.d/authorization_ctk:auth       required  use_first_pass
/etc/pam.d/screensaver_ctk:auth       required  use_first_pass

$ cat /etc/pam.d/authorization_ctk 
# ctk: auth 
auth       required   use_first_pass
account    required

$ cat /etc/pam.d/screensaver_ctk 
# ctk: auth 
auth       required  use_first_pass
account    required
account    sufficient
account    required no_warn group=admin,wheel fail_safe
account    required no_warn deny group=admin,wheel ruser fail_safe


Another interesting man page is SmartCardServices(7). Here is an extract:
SmartCardServices(7) BSD Miscellaneous Information Manual SmartCardServices(7)

     SmartCardServices -- overview of smart card support

     SmartCardServices is a set of components for OS X smart card support.

     Any smart card which supports the PIV standard is supported natively by
     OS X. Access to smart card items is possible using the keychain inter-
     face. Applications can install additional drivers for smart cards that
     are not natively supported.

     Smart card certificates are automatically added to user's keychain when a
     smart card is inserted. Smart card certificates can be listed with
     security using the list-smartcards or export-smartcard commands. Keychain
     Access GUI cannot be used to manipulate or list these certificates.

     To associate users with smart cards, the system can be set up for either
     fixed key mapping or attribute based mapping. For fixed key use
     sc_auth(8) or use the dialog which appears automatically when an unasso-
     ciated smartcard is inserted into a reader. This dialog can be globally
     suppressed by:

           sudo defaults write /Library/Preferences/ UserPairing -bool NO

     Attribute matching can be set up using the appropriate AttributeMapping
     section in the configuration file as described below. There is no default
     configuration. If no AttributeMapping exists or the configuration file is
     missing, attribute matching is not used. If both fixed key mapping and
     attribute mapping are able to associate the inserted smart card with a
     user, attribute mapping takes precedence.

     By default certificates do not need to be trusted to allow association.
     Certificate trust can be globally enforced by setting:

           sudo defaults write /Library/Preferences/ checkCertificateTrust -bool YES



Since PAM is available in macOS maybe the PAM PKCS#11 module can be used without too much changes? This module is for GNU/Linux but may be adapted for macOS.

In this case, adding support for smart card login in macOS, if you already have a PKCS#11 library for your card, should be easy.


The use of smart card in macOS for high level services (like authentication) is easier in Sierra, at least for PIV smart cards.

I imagine that the support of other smart cards models will be proposed by third parties "soon".

macOS Sierra and smart card source code

Apple released the source code of the open source components they use in Sierra (OS X 10.12 released in September 2016). The components are available at OS X 10.12 Source.

As I did for El Capitan in "OS X El Capitan and smart card source code" I will document what I found.

The smart card related components are:

See "macOS Sierra and smart cards status" for a general discussion of the changes in El Capitan.


The version changed from 55108 in El Capitan to 55111 in Sierra.

The changes are very limited:
  • the Xcode project uses Security.framework
  • 1 bug fixed "to prevent uninitialized value when following CALL ends with exception" according to the source code comment

 SecurityTokend-55111/SecurityTokend.xcodeproj/project.pbxproj    |    6 ++++++
 SecurityTokend-55111/lib/transition.cpp                          |    1 +
 SecurityTokend-55111/security_tokend_client/transition.cpp       |    1 +
 3 files changed, 8 insertions(+)


The version changed from 55008.40.1 in El Capitan (10.11.4) to 55013 in Sierra.

No change:
  • the same libusb version 1.0.9 is used. This version was released in 2012-04-02. The latest libusb version is 1.0.21 released in 2016-10-01.
  • the CCID driver provided by Apple has 4 patches. These patches are related to the way Apple builds the driver.


No disruptive changes this time.

The source code of CryptoTokenKit (introduced in Yosemite. See "OS X Yosemite BETA and smart cards status") is not provided. That is not surprising since this it is an Apple only component and not a fork of an existing free software.

Tuesday, December 6, 2016

OS X El Capitan and CCID evolution

In a previous blog article "OS X El Capitan and CCID driver upgrades" I mentioned the evolution of the CCID driver for the same major release of OS X 10.11.x.

With the availability of the source code at Apple Open Source it is easy to see what happened.

OS X VersionSmartcardCCIDCCID

I will try to closely follow the evolution of macOS Sierra (10.12) source code to avoid surprises in the future.

Sunday, November 20, 2016

Bitcoins received for this blog: 2 years later

Two years ago (November 2014) I proposed to send me bitcoins in "How to help my projects? Send me bitcoins!".


After 2 years I got 3 donations for a total amount of 0.02858649 BTC (or approximately 19.37€). The 3 transactions are public and can be seen at A great thanks to my 3 donors.

This is not a huge amount. In comparison I received 100.27€ from Flattr in 6 years (see "How to help my projects?").

SystemDurationTotal amountMean
Flattr6 years100.27 €16.71 €/year
Bitcoin2 years19.37 €9.67 €/year

The problem with Flattr (as I explained in "My Flattr experience") is that the funds are automatically "reinvested" so the real result after 6 years is 0€ in my pockets.

Adsense? No!

Google just proposed me to enrol in the AdSense program. Their estimation is a gain of 10,18 € per month.

Bonne nouvelle ! Votre compte répond aux critères requis pour bénéficier du traitement AdSense accéléré.
Vous devriez pouvoir gagner jusqu'à 10,18 € par mois*. Faites en sorte que votre blog vienne grossir les rangs de ces millions d'autres qui rapportent de l'argent grâce à AdSense. S'inscrire

*Les revenus mentionnés ne sont que des estimations basées sur le trafic récemment enregistré par votre blog. Nous ne pouvons en garantir le montant. Les comptes et les revenus AdSense doivent également respecter le Règlement du programme et les Conditions d'utilisation AdSense.

But since I do not like ads in web pages (and I use an advertisement blocker) I will not use AdSense or any other advertising system.


Please continue sending bitcoins. My bitcoin address is at the bottom of each blog page.

Sunday, November 6, 2016

ATR statistics: TD1 - Structural, encodes Y2 and T

Article from the series "ATR statistics"

TD1 - Structural, encodes Y2 and T

The ISO 7816-3 specification is not public. So I can't copy/paste part of the text. I will use Wikipedia instead.

From Wikipedia
Interfaces bytes TDi for i≥1, if present, are structural.
TDi encodes in its 4 high-order bits the presence of at most 4 other interface bytes: TAi+1 (resp. TBi+1, TCi+1, TDi+1) follow, in that order, if the 5th (resp. 6th, 7th, 8th) bit of TDi is 1.
TDi encodes in its 4 low-order bits (4th MSbit to 1st LSbit) an integer T, in range [0..15]. T = 15 is invalid in TD1, and in other TDi qualifies the following TAi+1 TBi+1, TCi+1, TDi+1 (if present) as global interface bytes. Other values of T indicates a protocol that the card is willing to use, and that TAi+1 TBi+1, TCi+1, TDi+1 (if present) are specific interface bytes applying only to that protocol. T = 0 is a character-oriented protocol. T = 1 is a block-oriented protocol. T in the range [3..14] is RFU.
Historical note: provision for dynamically qualifying interface bytes as global using T = 15 did not exist in ISO/IEC 7816-3:1989.

89943.39 %
0x8045922.15 %
0x8137217.95 %
0x40954.58 %
0x00693.33 %
0x91462.22 %
0xC0452.17 %
0xC1271.30 %
0x10221.06 %
0x50160.77 %
0x0190.43 %
0x0E80.39 %
0x1120.10 %
0x1F10.05 %
0x3110.05 %
0x3F10.05 %

TD1 (as the other TDi bytes) is structural and indicates:
  • How to interpret the other ATR bytes
  • What communication protocol the card wants to use

For 43% of the ATRs no TD1 is present. So no other TA2, TB2, TC2 or TD2 is present and no protocol is defined so the default T=0 will be used.

For 22% of ATRs TD1 = 0x80 so bit 8 is set to indicate that a TD2 is present and T=0 is used. One such ATR is 3B 80 80 01 01.

For 17% of ATRs TD1 = 0x81 so, as in the previous case, TD2 is present but T=1 is used. One such ATR is 3B 82 81 31 76 43 C0 02 C5

For 5% of ATRs TD1 = 0x40 so TC2 is present and T=0 is used. One such ATR is 3B 85 40 20 68 01 01 00 00

I will not document all the other cases. I let this exercise to the reader.

One special case is TD1 = 0x?E to indicate the T=14 protocol.

From ISO 7816-3:
The type T refers to a transmission protocol and/or qualifies interface bytes.
  • T=0 refers to the half-duplex transmission of characters specified in clause 10.
  • T=1 refers to the half-duplex transmission of blocks specified in clause 11.
  • T=2 and T=3 are reserved for future full-duplex operations.
  • T=4 is reserved for an enhanced half-duplex transmission of characters.
  • T=5 to T=13 are reserved for future use by ISO/IEC JTC 1/SC 17.
  • T=14 refers to transmission protocols not standardized by ISO/IEC JTC 1/SC 17.
  • T=15 does not refer to a transmission protocol, but only qualifies global interface bytes.

As you can see in the list above "T=14 refers to transmission protocols not standardized by ISO/IEC JTC 1/SC 17." In my list T=14 is used only by pay TV cards like 3B 9F 21 0E 49 52 44 45 54 4F 20 41 43 53 03 83 95 00 80 55.

TD1 = 0x?F is also another special case to indicate T=15, which is not a protocol, and will change the interpretation of the following ATR bytes.

Saturday, October 1, 2016

Smart cards on Ubuntu on Windows 10?

Since Windows 10 Anniversary it is possible to install Ubuntu 14.04 as a Windows subsystem (or something like that). See "Run Bash on Ubuntu on Windows" or any other documentation.

Of course I was curious and tried. Yes, I have a Windows partition. It is just used to upgrade the laptop firmware since it is not easy or even possible to upgrade the Dell laptop firmware from GNU/Linux.


After some time the tools needed to build pcsc-lite and libccid are installed. The two builds are successful.

$ /usr/local/sbin/pcscd --version
pcsc-lite version 1.8.18.
Copyright (C) 1999-2002 by David Corcoran <corcoran>.
Copyright (C) 2001-2015 by Ludovic Rousseau <ludovic .rousseau="">.
Copyright (C) 2003-2004 by Damien Sauveron <sauveron>.
Report bugs to <>.
Enabled features: Linux x86_64-unknown-linux-gnu serial usb libudev usbdropdir=/usr/local/lib/pcsc/drivers ipcdir=/var/run/pcscd configdir=/usr/local/etc/reader.conf.d


The build is a success but the execution fails.

Not working libudev

$ sudo /usr/local/sbin/pcscd --foreground --debug
00000000 debuglog.c:289:DebugLogSetLevel() debug level=debug
00001975 configfile.l:358:DBGetReaderList() Parsing conf file: /usr/local/etc/reader.conf.d
00001005 pcscdaemon.c:655:main() pcsc-lite 1.8.18 daemon ready.
libudev: udev_monitor_enable_receiving: bind failed: Invalid argument
00005302 hotplug_libudev.c:758:HPRegisterForHotplugEvents() udev_monitor_enable_receiving() error: -1

^C01658892 pcscdaemon.c:188:signal_thread() read failed: Interrupted system call

Not really surprising, libudev fails to register the reception of events. This was expected since udev is a device manager for the Linux kernel and we do not have a Linux kernel here.

We could configure pcsc-lite to use libusb instead of libudev to manage hotplug. But that would also not work, see bellow.

Not working libusb

$ lsusb
unable to initialize libusb: -99
The libusb library is not usable.

$ strace lsusb
gettimeofday({1475313910, 750505}, NULL) = 0
openat(AT_FDCWD, "/dev/bus/usb", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/proc/bus/usb", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
brk(0x1bfa000)                          = 0x1bfa000
getdents(3, /* 20 entries */, 32768)    = 481
getdents(3, /* 0 entries */, 32768)     = 0
brk(0x1bf2000)                          = 0x1bf2000
close(3)                                = 0
write(2, "unable to initialize libusb: -99"..., 33unable to initialize libusb: -99
) = 33
exit_group(1)                           = ?
+++ exited with 1 +++
This is because the file system does not provide the USB virtual files in /dev/bus/usb/ or /proc/bus/usb/.

$ ls -l /dev
ls: cannot access /dev/lxss: Operation not permitted
ls: /dev/random: Invalid argument
total 0
drwxr-xr-x 2 root     root    0 Oct  1 10:04 block
lrwxrwxrwx 1 root     root   13 Oct  1 10:04 fd -> /proc/self/fd
crw------- 1 root     root 0, 0 Oct  1 11:28 kmsg
c????????? ? ?        ?       ?            ? lxss
crw-rw-rw- 1 root     root 1, 3 Jan  1  1970 null
crw-rw-rw- 0 root     tty  5, 2 Oct  1 10:31 ptmx
drwxr-xr-x 0 root     root    0 Oct  1 10:04 pts
crw-rw-rw- 1 root     root 1, 8 Oct  1 11:28 random
lrwxrwxrwx 1 root     root    8 Oct  1 10:04 shm -> /run/shm
lrwxrwxrwx 1 root     root   15 Oct  1 10:04 stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root     root   15 Oct  1 10:04 stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root     root   15 Oct  1 10:04 stdout -> /proc/self/fd/1
crw------- 1 rousseau tty  4, 1 Oct  1  2016 tty
crw-rw-rw- 1 root     tty  4, 0 Oct  1  2016 tty0
crw------- 1 rousseau tty  4, 1 Oct  1  2016 tty1
crw-rw---- 1 root     tty  4, 2 Oct  1 11:28 tty2
crw-rw-rw- 1 root     root 1, 9 Oct  1 11:28 urandom
crw-rw-rw- 1 root     root 0, 0 Oct  1 11:28 zero

$ ls -l /proc
total 0
dr-xr-xr-x 1 root     root     0 Oct  1 10:07 1
dr-xr-xr-x 1 rousseau rousseau 0 Oct  1 10:07 2
dr-xr-xr-x 1 rousseau rousseau 0 Oct  1 11:29 22063
-r--r--r-- 1 root     root     0 Oct  1 10:04 cmdline
-r--r--r-- 1 root     root     0 Oct  1 10:04 cpuinfo
-r--r--r-- 1 root     root     0 Oct  1 10:04 filesystems
-r--r--r-- 1 root     root     0 Oct  1 10:04 interrupts
-r--r--r-- 1 root     root     0 Oct  1 10:04 loadavg
-r--r--r-- 1 root     root     0 Oct  1 10:04 meminfo
lrwxrwxrwx 1 root     root     0 Oct  1 10:04 mounts -> self/mounts
lrwxrwxrwx 1 root     root     0 Oct  1 10:04 net -> self/net
lrwxrwxrwx 1 root     root     0 Oct  1 10:04 self -> 22063
-r--r--r-- 1 root     root     0 Oct  1 10:04 stat
dr-xr-xr-x 1 root     root     0 Oct  1 10:04 sys
-r--r--r-- 1 root     root     0 Oct  1 10:04 uptime
-r--r--r-- 1 root     root     0 Oct  1 10:04 version

Existing packages

The libccid package is available for this Ubuntu 14.04 in Windows 10.
$ apt-cache policy libccid
  Installed: (none)
  Candidate: 1.4.15-1
  Version table:
     1.4.15-1 0
        500 trusty/universe amd64 Packagess

Since I made a build from the source code I have not installed this package.

Port or not

I was curious to know if the packages have been rebuilt for "Windows" with a special configuration. So I selected a package at random (in fact I used a short package name to limit the number of key presses needed to enter the package name. The m4 package is a good candidate for that.).

m4 package as downloaded by apt from "Windows":
$ pwd
$ sha1sum m4_1.4.17-2ubuntu1_amd64.deb
4358d262605ae065a7dc9b6e0c80b3c7f44bf1cc  m4_1.4.17-2ubuntu1_amd64.deb

m4 package as downloaded from for amd64 architecture:
$ pwd
$ sha1sum m4_1.4.17-2ubuntu1_amd64.deb
4358d262605ae065a7dc9b6e0c80b3c7f44bf1cc  m4_1.4.17-2ubuntu1_amd64.deb

The two packages are exactly the same.

The apt repository is the same as for a real Ubuntu system.
$ cat /etc/apt/sources.list
deb trusty main restricted universe multiverse
deb trusty-updates main restricted universe multiverse
deb trusty-backports main restricted universe multiverse
deb trusty-security main restricted universe multiverse
$ dpkg --print-architecture


As expected many Linux features (udev, USB) are missing. Maybe Microsoft will work on that to provide more support.

I also note that the system is much slower on Ubuntu in Windows than on a real Linux kernel (and a Debian system) on the same hardware. In particular the file system accesses, when installing packages for example, are around an order of magnitude slower.