Friday, October 12, 2018

New PyKCS11 1.5.3 available

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

Changes:

1.5.3 - October 2018, Ludovic Rousseau
  • Do not fail when converting a UTF-8 string
  • Documentation: convert from Epydoc to Sphinx
  • some minor improvements

New version of pcsc-lite: 1.8.24

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

Changes
1.8.24: Ludovic Rousseau
12 October 2018
  • the project moved to https://pcsclite.apdu.fr/
  • SCardGetStatusChange(): Fix a rare race condition
  • SCardReleaseContext(): do not release a lock owned by another context
  • SCardReconnect(): suspend card auto power off
  • Allow "=" in serial driver filenames
  • Add the thread id in the pcscd log lines
  • pcsc-spy: correctly handle incomplete log file
  • Simclist: avoid to divide by zero in list_findpos()
  • Some other minor improvements

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.

Saturday, September 22, 2018

Better CCID suport in FreeBSD

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

libUSB issues

I reported the problem using the FreeBSD bug report tool: https://bugs.freebsd.org/

I worked with Hans Petter Selasky (libUSB co-maintainer) to fix the problems. I would like to thank Hans Petter for his availability. That is great to have problems fixed in just a few days.

libusb_cancel_transfer() does NOT cancel a transfer after the USB device is removed

Bug reported at: libusb_cancel_transfer() does NOT cancel a transfer after the USB device is removed

Patch applied in FreeBSD: Revision 338616

Debug is not working correctly

Use of DPRINTF() to print debug message was not working in some functions.

Bug reported at: libusb DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "sync I/O done"); does not work in libusb10_do_transfer_cb()

Patch applied in FreeBSD: Revision 338679

Bogus management after a device removal

Bug reported at: libusb_bulk_transfer() does not fail (with LIBUSB_ERROR_NO_DEVICE) if the device is not more present

This bug is solved by the patch also solving the libusb_cancel_transfer() problem.

Fixed in FreeBSD stable versions

The problems have also been fixed in FreeBSD stable versions 9, 10, 11.

Conclusion

My CCID driver should now work better on FreeBSD.

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.