Friday, November 19, 2010

PCSC sample in C#

Here is the PCSC sample in C# language I promised in PC/SC sample in different languages.

Available wrappers

After searching I found different projects to wrapper PC/SC from C#.

So much projects for the same service gives different messages:

  • the service is needed by "many" users
  • the C# community is fragmented and do not have a central point of discussion (forum, mailing list, web site, etc.) to setup on just one implementation?
  • the authors suffer from the NIH syndrome?



Install the Mono c# compiler:
sudo aptitude install mono-gmcs

I recommend you to use the nice working development IDE, monodevelop:
sudo aptitude install monodevelop

Build pcsc-sharp

  1. Download pscs-sharp, current version is 2010-11-10 (update 5 Nov 2015: the project moved to github project pcsc-sharp and the current version is from Oct 2015)
  2. Unpack the source.
  3. Go into the pcsc-sharp/ directory and simply run make.
    It will compile the PC/SC classes within a second. By default, a "Release" version without debug information will be build. You can change the configuration target by editing the Makefile file. If you do not like the command line, you can use 'monodevelop', the graphical IDE as well. Monodevelop uses Visual Studio's file format for its solution and project files.

Create the HelloWorld application with Monodevelop

  1. Start monodevelop, click at File -> New -> Solution
  2. Select C#" as programming language, use the "Console Project" template and name it "HelloWorld". You can skip the package feature dialog.
  3. You need to add a reference to the pcsc-sharp.dll file.
    To do this right-click at "References" in the Solution panel and choose "Edit References". Click at ".Net Assembly" and browse to the path where the pcsc-sharp.dll file is located. Double click the dll and it will be added to the project.
  4. Use the HelloWorld.cs code listed below.

Source code

using System;
using System.Text;

using PCSC; 

namespace HelloWorld
    class Program
        static void CheckErr(SCardError err)
            if (err != SCardError.Success)
                throw new PCSCException(err,
        static void Main(string[] args)
                // Establish SCard context
                SCardContext hContext = new SCardContext();

                // Retrieve the list of Smartcard readers
                string[] szReaders = hContext.GetReaders();
                if (szReaders.Length <= 0)
                    throw new PCSCException(SCardError.NoReadersAvailable,
                        "Could not find any Smartcard reader.");
                Console.WriteLine("reader name: " + szReaders[0]);

                // Create a reader object using the existing context
                SCardReader reader = new SCardReader(hContext);

                // Connect to the card
                SCardError err = reader.Connect(szReaders[0],
                    SCardProtocol.T0 | SCardProtocol.T1);

                long pioSendPci;
                switch (reader.ActiveProtocol)
                    case SCardProtocol.T0:
                        pioSendPci = SCardPCI.T0;
                    case SCardProtocol.T1:
                        pioSendPci = SCardPCI.T1;
                        throw new PCSCException(SCardError.ProtocolMismatch,
                            "Protocol not supported: "
                            + reader.ActiveProtocol.ToString());

                byte[] pbRecvBuffer = new byte[256];

                // Send SELECT command
                byte[] cmd1 = new byte[] { 0x00, 0xA4, 0x04, 0x00, 0x0A, 0xA0, 
                    0x00, 0x00, 0x00, 0x62, 0x03, 0x01, 0x0C, 0x06, 0x01 };
                err = reader.Transmit(pioSendPci, cmd1, ref pbRecvBuffer);

                Console.Write("response: ");
                for (int i = 0; i < pbRecvBuffer.Length; i++)
                    Console.Write("{0:X2} ", pbRecvBuffer[i]);

                pbRecvBuffer = new byte[256];

                // Send test command
                byte[] cmd2 = new byte[] { 0x00, 0x00, 0x00, 0x00 };
                err = reader.Transmit(pioSendPci, cmd2, ref pbRecvBuffer);

                Console.Write("response: ");
                for (int i = 0; i < pbRecvBuffer.Length; i++)
                    Console.Write("{0:X2} ", pbRecvBuffer[i]);

            catch (PCSCException ex)
                Console.WriteLine("Ouch: "
                    + ex.Message
                    + " (" + ex.SCardError.ToString() + ")");


$ ./HelloWorld.exe
reader name: Gemalto GemPC Twin 00 00
response: 90 00
response: 48 65 6C 6C 6F 20 77 6F 72 6C 64 21 90 00

I don't know how to convert a byte array of ASCII characters to a string. I search a bit for a "%c" equivalent in C# but have not found it. So, exercise for next time: display the "string" returned by the card.

Lessons learned


Monodevelop is a nice tool.

I got caught by a strange (for me) behavior of monodevelop. The HelloWorld project embark/copy its own version of pcsc-sharp.dll the PCSC wrapper in the bin/Debug/ directory. So if you modify the wrapper you need to rebuild the HelloWorld project, not just rerun it.

Maybe it is possible to install the DLL in a system directory or something like that. So that different applications can share the same file.
The HelloWorld.exe file is 5120 bytes, or 5 kiB.
The pcsc-sharp.dll file is 83456 bytes or 81 kiB.


A C# program can be executed directly from the shell on my GNU/Linux system. It is surprising since it is recognised as a Windows binary:
$ file HelloWorld.exe
HelloWorld.exe: PE32 executable for MS Windows (console) Intel 80386 32-bit Mono/.Net assembly

I also tried to execute on Windows XP the binary generated on Gnu/Linux. And it works! No change needed.


Thanks to Daniel Mueller, author of pcsc-sharp, for writing the sample code and a large part of the documentation included in this article.

Update 5 Nov 2015

The project moved to github project pcsc-sharp. It has been active in 2015.

I have not checked my sample code still work with the latest version of the wrapper.

Thursday, November 11, 2010

PSSI: SIM card phone book listing (part 2)

Just a week after my post about a missing SIM card explorer in free software I discover in a the French MISC magazine article "Python Simple Smartcard Interpreter" that such a project exists.

PSSI: Python Simple Smartcard Interpreter

The project is hosted at and uses GNU GPLv3 licence.
" Python script that provides an abstract layer for smartcard reading. Thanks to it, it is possible to read a smartcard by simply adding its structure in the form of a plugin, without taking care of the communication layer. The tool comes with several plugins, namely SIM, EMV, and NAVIGO. "
The project is quiet new. The project was created 30 July 2010 on and the first commit occured on 19 Sept 2010. No stable/numbered release is available.


The software is not just for SIM cards but is generic and uses plugins.


This plugin displays a lot of information about the SIM:
  • Telecom provider
  • Phone book
  • SMS


This plugin also displays a lot of information about the bank card:

Applications on the card

 ATR                         : 3B 65 00 00 66 04 6C 90 00
    Applications List          
       ====   1   ====
          ====   1   ====
             Application information    
                EMV Application information
                   Application ID              : a0 00 00 00 42 10 10 
                   Application name            : CB
                   Application priority        : 1
          ====   2   ====
             Application information    
                EMV Application information
                   Application ID              : a0 00 00 00 03 10 10 
                   Application name            : VISA
                   Application priority        : 2

Card holder name

Application information    
   Track 2 data                : 49 78 38 00 XX XX XX XX YY YY YY YY 
   Cardholder                  : MR ROUSSEAU LUDOVIC       
   Track 1 discretionary data  : 329627000000000673000000

Card validity dates and card number

Application information    
   Validity beginning          : 01 / 09 / 08
   Validity end                : 30 / 09 / 10
   Card number                 : 49 78 38 00 XX XX XX XX 
   PAN sequence number         : 4

The card number has been obscured by me. Even if the card expired a few months ago I think it is safer like this :-)


====   1   ====
====   2   ====
   Amount          : 126.63          ()
   CID             : 64              (Cryptogram Information Data)
   Country         : FRANCE          (Country where the terminal is located)
   Currency        : Euro            ()
   Date            : 18 / 09 / 10    ()
   Type            : Payment         ()
====   3   ====
   Amount          : 36.80           ()
   CID             : 64              (Cryptogram Information Data)
   Country         : FRANCE          (Country where the terminal is located)
   Currency        : Euro            ()
   Date            : 31 / 08 / 10    ()
   Type            : Payment         ()
====   4   ====
   Amount          : 202.60          ()
   CID             : 64              (Cryptogram Information Data)
   Country         : FRANCE          (Country where the terminal is located)
   Currency        : Euro            ()
   Date            : 25 / 08 / 10    ()
   Type            : Payment         ()


Navigo is the smart card used by the RATP in Paris public transport system. I do not have such a card so could not use this plugin.


Another project to dump an EMV card is ccid-utils but this project did not work with my French bank card so I thought my card was not EMV compliant. But I was wrong since PSSI works great with this card.

Another problem with ccid-utils is that even if the program uses Python the core of the project uses C and directly talks to a CCID reader instead of using the PC/SC API through Pyscard. ccid-utils is also very limited regarding the CCID readers it supports.


PSSI is much more than a SIM card explorer. It also works for EMV and Navigo cards. The display of information is nice. The code is Python only so I had no problem using it on Mac OS X. I think I will continue playing with the software and maybe implement other features.

Flattr this

Monday, November 8, 2010

PC/SC client and server on two different hosts

Estobuntu (a remastered Kubuntu Lucid Live CD that uses Estonian by default) uses LTSP (Linux Terminal Server Project) and a modified version of ssh to redirect the pcsc-lite client-server communication channel.

The feature has been added in revision r5373 and will be available in pcsc-lite version 1.6.5.


  • pcscd is running on the remote terminal, where the smart card reader is connected.
  • SSH is used to redirect the pcscd socket /var/run/pcscd/pcscd.comm from the client terminal to a file on the server and then used by the client library.
  • On the server each client session must have its own socket to a different pcscd running on different terminals. So the file is located in the user home directory: $HOME/


On the pcscd side the socket /var/run/pcscd/pcscd.comm is redirected by ssh.

On the side the redirection is done by configuring the environment variable PCSCLITE_CSOCK_NAME.

$ export PCSCLITE_CSOCK_NAME=$HOME/.pcscd.comm
$ the_program


This setup cannot use the auto start feature. The auto start feature allows to start the pcscd daemon only when the is used by an application. Since the pcscd and are now on two different machines it is a bit more complex than just fork+exec. The would have to start pcscd on a different machine. This is possible but is not implemented.


This feature could also be used outside of Estobuntu and LTSP.

SSH does not, natively, redirect a Unix domain socket to a remote Unix domain socket. But maybe a simple tool exists for doing just that. If you know something like that please add a comment. One problem is that Unix domain socket can do more than Internet sockets (like transfer a file handle with SCM_RIGHTS or Unix credentials with SCM_CREDENTIALS), but pcsc-lite does not use these services.

Flattr this

Wednesday, November 3, 2010

SIM card phone book listing

During the Debian minconf Paris 2010 I was asked for a program to use a SIM card.

I do not know any program to correctly manage a SIM card in free software on Unix (but I have not really search for it).

SIM explorer v3.0

In 2004 I wrote a simple Perl program to dump the phone book of a SIM card using the PC/SC Perl wrapper. The program is available on my web site.

The program is very rude and only displays the phone book. No way to edit the phone book.


I am surprised to see so little interest in the area of SIM/USIM cards. The market penetration of GSM was already above 100% in 22 European markets in 2006. So I guess every smart card hacker also has one GSM/3G phone. So we do not lack developers.

Note: I do not have a GSM/3G/smart phone myself :-)

Flattr this

Monday, November 1, 2010

Debian Miniconf Paris/2010

I presented a talk titled "Smart cards in Debian" at the Debian Miniconf Paris, October 2010.

The slides (in English) of my talk are available online. The idea was to stay at a high level and present the different layers use in the smart card world. So no lines of code or screen dumps.

The topics are:
  • ISO 7816-1, 2, 3 and 4
  • Private/proprietary specifications
  • Publicly documented specifications
  • Programmable smart cards
  • CCID
  • PC/SC
  • PKCS#11
  • Python PC/SC wrapper
  • Python PKCS#11 wrapper
  • Electronic ID cards
I did not go into details. I wanted to show a big picture of the different smart card layers. That may be one of the most difficult things in a domain: know what to install and what layer is used by which one.

Comments are welcome.

Flattr this