Wednesday, August 26, 2015

How to get my GPG public key?

On the MUSCLE mailing list we got the following question:
From: Jessie Frazelle
Subject: GPG Key

I swear I looked all over the website and downloads page [1]. But I
cannot find what key the tarballs are signed with to import to verify.
I am so sorry for bothering a mailing list with such noise, especially
because as much as I try I know they have to be somewhere and I am
just missing it.

Thanks in advance.


[1] https://alioth.debian.org/frs/?group_id=30105

Check the signature

Let try with the CCID driver. Download the 2 files: ccid-1.4.20.tar.bz2 and ccid-1.4.20.tar.bz2.asc and try to verify the signature.

$ gpg2 ccid-1.4.20.tar.bz2.asc
gpg: assuming signed data in 'ccid-1.4.20.tar.bz2'
gpg: Signature made Wed Aug  5 13:23:24 2015 CEST using RSA key ID E8F9C57E
gpg: Can't check signature: No public key

The signing key ID is E8F9C57E. We need to find this public key.

Fetch the public GPG key

You can use your web search engine for "E8F9C57E". It will return many results, including the public key you are looking for.

One way to get the key is to ask a key server using:
$ gpg2 --keyserver pgp.mit.edu --recv-key E8F9C57E
gpg: requesting key E8F9C57E from hkp server pgp.mit.edu
gpg: key E8F9C57E: public key "Ludovic Rousseau " imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

I used pgp.mit.edu as key server but you can use another one.

Check the signature, again

Then we can verify the signature:
$ gpg2 ccid-1.4.20.tar.bz2.asc
gpg: assuming signed data in 'ccid-1.4.20.tar.bz2'
gpg: Signature made Wed Aug  5 13:23:24 2015 CEST using RSA key ID E8F9C57E
gpg: Good signature from "Ludovic Rousseau " [unknown]
gpg:                 aka "Ludovic Rousseau " [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: F5E1 1B9F FE91 1146 F41D  953D 78A1 B4DF E8F9 C57E

The signature is correct. But the key is not trusted.

Trust the public key?

Then you can verify that the public key ID E8F9C57E is really my public key. You will need to use the web of trust for that.
Maybe you trust one of the keys that signed my public key (level 1)?
Or maybe you trust a key that signed a key that signed my key (level 2)?
etc.

My GPG public key is also available from my web page at http://ludovic.rousseau.free.fr/

Thursday, August 13, 2015

PySCard 1.9.0 released

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

The PySCard project is available at:

Changes:

The main change is the support of Python3. I would not be surprised if some Python3 issues are still present.
After some more testing, stress test and bug fix (if needed) on Python3 I will move the version number to 2.0.0.

1.9.0 (August 2015)
  • add Python3 support (Python2 is still supported)
  • fix a lot of pylint warnings
  • smartcard/test/* replace deprecated assert calls
  • add tox support and coverage reports, run test suite on Travis
  • add Travis CI support to automatically build on Unix
  • add AppVeyor support to automatically build on Windows
  • minor bugs fixed
  • Big thank you to Alex Willmer for his work on pyscard

See also my previous article: PySCard 1.7.0 released

Friday, August 7, 2015

New version of pcsc-tools: 1.4.24

I just released a new version of pcsc-tools, a suite of tools for PC/SC.

Changes:
1.4.24 - 7 August 2015, Ludovic ROUSSEAU
  • 253 new ATRs
  • ATR_analysis: better update of the local cache

Wednesday, August 5, 2015

New version of libccid: 1.4.20

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

Direct download here.

Changes:
1.4.20 - 5 August 2015, Ludovic Rousseau
  • Add support of
    • ACS ACR1251 Dual Reader
    • Access IS NFC Smart Module
    • BIFIT iToken
    • BLUTRONICS BLUDRIVE II CCID (idProduct: 0x1079)
    • Generic MultiCard Device
    • NXP Pegoda 2 N
    • SafeNet eToken 5100
    • SafeNet eToken 7300
    • Yubico Yubikey 4 CCID
    • Yubico Yubikey 4 OTP+CCID
    • Yubico Yubikey 4 OTP+U2F+CCID
    • Yubico Yubikey 4 U2F+CCID
  • Depends on libusb version 1.0.9 instead of 1.0.8
  • The O2 Micro Oz776 reader only supports 9600 bps
  • Change installation directory for Mac OS X El Capitan 10.11

New version of pcsc-lite: 1.8.14

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

Changes:
1.8.14: Ludovic Rousseau
5 August 2015
  • Threading: lock the PC/SC context in a safe way
  • Threading: lock the card context in a safe way
  • SCardGetStatusChange(): fix card movement rare bug
  • Doxygen:
    • SCardTransmit() may return SCARD_E_INSUFFICIENT_BUFFER
    • SCardEndTransaction() The disposition is used and the dwDisposition parameter has an effect.
    • SCardReconnect() do not release locks
    • fix typos
  • Move the source code repository from subversion to git
  • Use asprintf(3) instead of strlcat(3) and strlcpy(3)
  • Allow to use pcscd in a remote session (polkit issue)
  • Some other minor improvements and bug corrections

Tuesday, July 7, 2015

OS X Yosemite bug: SCardConnect blocks in SCARD_SHARE_SHARED mode

This is part of the series: "OS X Yosemite and smart cards: known bugs".

SCardConnect(..., SCARD_SHARE_SHARED, ...)

SCardConnect() do not work correctly on Yosemite in a multi application context.

SCardConnect(..., SCARD_SHARE_SHARED, ...) will block its execution until SCardDisconnect() is called in the other application using the card or the card is removed.

The SCARD_SHARE_SHARED flag indicates that the connection shall be shared by different applications. Different application should be able to use the card at the same time. An application can use SCardBeginTransaction()/SCardEndTransaction() to get a temporary exclusive access to the card.

This can be really problematic if an application is not correctly written and SCardDisconnect() is not called. The concurrent application would be blocked forever on SCardConnect().

When SCardConnect() is unblocked by a card removal it will return the error code SCARD_E_NO_SMARTCARD.

This bug is present in Yosemite version 10.10.4. I have not verified if the bug is also present in previous Yosemite versions. Maybe it is a bug introduced in 10.10.4?

See also

Apple bug report #21703315 "PC/SC SCardConnect() blocks in SCARD_SHARE_SHARED mode"

Sample code

Thanks to Mounir for the initial sample code.

The sample application does:
  1. wait for a card insertion
  2. SCardConnect() to the card
  3. sleep for 3 seconds
  4. SCardDisconnect() from the card
  5. go to step 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#ifdef __APPLE__
#include <PCSC/winscard.h>
#include <PCSC/wintypes.h>
#else
#include <winscard.h>
#endif

SCARDCONTEXT hContext;
SCARD_READERSTATE state;

#define CHECK_ERROR(text) \
    if (err != SCARD_S_SUCCESS) \
        printf("\033[0;31m" text ": %s (0x%08x)\033[00m\n",pcsc_stringify_error(err),err); \
    else \
        timed_log(text ": OK\n");

#define CHECK_EXIT(text) \
    CHECK_ERROR(text) \
    if (err != SCARD_S_SUCCESS) return -1;

static void timed_log(const char *msg)
{
    static struct timeval old_tp;
    struct timeval tp, r;

    gettimeofday(&tp, NULL);

    r.tv_sec = tp.tv_sec - old_tp.tv_sec;
    r.tv_usec = tp.tv_usec - old_tp.tv_usec;
    if (r.tv_usec < 0)
    {
        r.tv_sec--;
        r.tv_usec += 1000000;
    }

    printf("%ld.%.6d %s", r.tv_sec, r.tv_usec, msg);
    old_tp = tp;
}

static int WaitForCardEvent(void)
{
    int insert = 0;

    DWORD err;
    while (1)
    {
        timed_log("Waiting for event...\n");
        err = SCardGetStatusChange(hContext, INFINITE, &state, 1);
        CHECK_EXIT("SCardGetStatusChange")

        timed_log("event detected\n");
        state.dwCurrentState = state.dwEventState;

        if (state.dwEventState & SCARD_STATE_PRESENT)
        {
            if (! (state.dwEventState & SCARD_STATE_MUTE))
            {
                timed_log("card inserted\n");
                if (insert)
                    return 1;
            }
            else
                timed_log("card is mute\n");
        }
        else
        {
            timed_log("card removed\n");
            insert = 1;
        }
    }

    return 0;
}

static int UseCard(const char *mszReaders)
{
    DWORD dwActiveProtocol;
    SCARDHANDLE hCard = 0;

    timed_log("calling SCardConnect\n");
    DWORD err = SCardConnect(hContext, mszReaders, SCARD_SHARE_SHARED,
        SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
    CHECK_EXIT("SCardConnect")
    timed_log("connected\n");

    sleep(3);

#if 1
    timed_log("calling SCardDisconnect\n");
    err = SCardDisconnect(hCard, SCARD_LEAVE_CARD);
    CHECK_ERROR("SCardDisconnect")
#endif

    return 1;
}

int main(void)
{
    LPSTR mszReaders;
    DWORD err, cchReaders;

    err = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
    CHECK_EXIT("SCardEstablishContext")
    cchReaders = 0;

    err = SCardListReaders(hContext, NULL, NULL, &cchReaders);
    CHECK_EXIT("SCardListReaders")
    mszReaders = calloc(cchReaders, sizeof(char));
    if (!mszReaders)
    {
        printf("calloc\n");
        return -1;
    }
    err = SCardListReaders(hContext, NULL, mszReaders, &cchReaders);
    CHECK_EXIT("SCardListReaders")

    printf("Using Reader: %s\n", mszReaders);

    memset(&state, 0, sizeof state);
    state.szReader = mszReaders;
    err = SCardGetStatusChange(hContext, 0, &state, 1);
    CHECK_EXIT("SCardGetStatusChange")

    while (1)
    {
        WaitForCardEvent();

        UseCard(mszReaders);
    }

    SCardReleaseContext(hContext);


    return 0;
}

You need to open 2 terminal windows and run the application concurrently in the 2 terminals.

Result (on Yosemite)

$ CFLAGS="-framework PCSC" make main
cc -framework PCSC main.c -o main

Terminal 1

$ ./main
1436274783.304010 SCardEstablishContext: OK
0.000163 SCardListReaders: OK
0.000108 SCardListReaders: OK
Using Reader: Dell Dell Smart Card Reader Keyboard
0.000971 SCardGetStatusChange: OK
0.000004 Waiting for event...
0.000540 SCardGetStatusChange: OK
0.000005 event detected
0.000001 card removed
0.000001 Waiting for event...

42.709172 SCardGetStatusChange: OK
0.000010 event detected
0.000002 card inserted
0.000001 calling SCardConnect
0.042665 SCardConnect: OK
0.000010 connected
3.000132 calling SCardDisconnect
0.000339 SCardDisconnect: OK
0.000006 Waiting for event...
0.000825 SCardGetStatusChange: OK
0.000006 event detected
0.000001 card inserted
0.000001 Waiting for event...
3.001277 SCardGetStatusChange: OK
0.000008 event detected
0.000001 card inserted
0.000001 Waiting for event...

Terminal 2

$ ./main
1436274812.713724 SCardEstablishContext: OK
0.000145 SCardListReaders: OK
0.000091 SCardListReaders: OK
Using Reader: Dell Dell Smart Card Reader Keyboard
0.001038 SCardGetStatusChange: OK
0.000005 Waiting for event...
0.000717 SCardGetStatusChange: OK
0.000006 event detected
0.000001 card removed
0.000001 Waiting for event...

13.299278 SCardGetStatusChange: OK
0.000007 event detected
0.000001 card inserted
0.000001 calling SCardConnect
3.043707 SCardConnect: OK
0.000014 connected
3.000740 calling SCardDisconnect
0.000396 SCardDisconnect: OK
0.000007 Waiting for event...

Description

I added a newline in the traces just before the card insertion. The number in front of each line is the time that passed since the previous log line. So if you see "1.23 foo" then "foo" happened 1.23 second after the previous log.

In this execution the application in terminal 1 got the card connection in the first place. You can see that SCardConnect() returns after 0.042665 seconds. The state was "connected" for 3.000132 seconds. Then SCardDisconnect() is called.

In terminal 2 we note that SCardConnect() returns after 3.043707 seconds. The application is blocked during the 3 seconds used by the the first application.

Also note that in terminal 1 SCardGetStatusChange() returns after 3.001277 seconds. This is because the card was used by the application in terminal 2 and the card state changed. The bit SCARD_STATE_INUSE changed from 1 (card in use) to 0 (card not used).

Expected result (on Debian)

$ CFLAGS=`pkg-config --cflags libpcsclite` LDFLAGS=`pkg-config --libs libpcsclite` make main
cc -pthread -I/usr/include/PCSC -lpcsclite main.c -o main

Terminal 1

$ ./main1436274912.852172 SCardEstablishContext: OK
0.000144 SCardListReaders: OK
0.000134 SCardListReaders: OK
Using Reader: Gemalto PC Twin Reader (70D7E2EE) 00 00
0.000138 SCardGetStatusChange: OK
0.000012 Waiting for event...
0.000089 SCardGetStatusChange: OK
0.000020 event detected
0.000003 card removed
0.000002 Waiting for event...

11.780610 SCardGetStatusChange: OK
0.000014 event detected
0.000002 card inserted
0.000002 calling SCardConnect
0.033486 SCardConnect: OK
0.000013 connected
3.000073 calling SCardDisconnect
0.000125 SCardDisconnect: OK
0.000016 Waiting for event...

Terminal 2

$ ./main 
1436274916.659394 SCardEstablishContext: OK
0.000163 SCardListReaders: OK
0.000149 SCardListReaders: OK
Using Reader: Gemalto PC Twin Reader (70D7E2EE) 00 00
0.000144 SCardGetStatusChange: OK
0.000033 Waiting for event...
0.000108 SCardGetStatusChange: OK
0.000023 event detected
0.000019 card removed
0.000007 Waiting for event...

7.973306 SCardGetStatusChange: OK
0.000025 event detected
0.000009 card inserted
0.000007 calling SCardConnect
0.033451 SCardConnect: OK
0.000028 connected
3.000083 calling SCardDisconnect
0.000215 SCardDisconnect: OK
0.000025 Waiting for event...

Description

On Linux you can see that the 2 applications run at the same time concurrently. No application is blocked by the other.

Known workaround

None known.

Some ideas that should help:
  • Do not forget to call SCardDisconnect() when you no longer use the card, or another application may be blocked for a long time.
  • Connect to a card for short periods of time if possible. Another application would then get a chance to access the card.

Saturday, June 27, 2015

PySCard 1.7.0 released

Release 1.7.0

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

Changes:

1.7.0 (June 2015)
  • PCSCCardConnection: Fix a problem with mode=SCARD_SHARE_DIRECT
  • add support of cygwin as a build platform
  • Fix a problem with Windows Remote Desktop
  • Switch from distutils to setuptools
  • dropped support for Python 2.5 and earlier (Alex Willmer)
  • dropped support for OS X 10.5 (Leopard) and earlier (Alex Willmer)
  • minor bugs fixed

Provided software

The source code archive pyscard-1.7.0.tar.gz is of course provided.

I also provide a binary installer pyscard-1.7.0.macosx-10.10-intel.tar.gz for Mac OS X 10.10 Yosemite and Python 2.7.

Continuous Integration

The PySCard project now uses two continuous integration platforms:

Windows installers?

Maybe AppVeyor can be used to provide binary installers for Windows. Your help is welcome on this task because I am not a Windows user.