Smart Cards in .NET

I’ll begin with an introduction to the smart card standards and especially the PC/SC specification, which I believe is the most widely accepted platform for developing and deploying Smart Card Applications and will move on to the problems encountered while accessing smart cards from the .NET environment. Concluding the article I’ll present the solution, which I adopted to resolve the problem and I hope that will help you with writing Smart Card Enabled applications in .NET.


Smart Cards have been around for many years now with the SUN® initiative of JavaCard™ technology to develop Smart Card solutions. They have created  a lot of buzz in the IT world, especially the IT-enabled services sector. In this article we’ll be reading about the problems encountered while developing Smart Card enabled applications in .NET and then will see a solution for the same.
This solution may not be the best, but that it works just great for me! We’ll develop a pure, managed Smart Card Class library in future articles of this series.

Background:
Recently I needed to use a Smart Card reader from a C# application and I thought there would be support for it in some namespace in the FCL. But to my surprise there is no support for Smart Card access.
 I tried to find some third party class libraries or Components which I could use but I ended up with some Delphi Components and a few articles explaining how to access WinSCard.dll Functions in C#. I tried that option but was unable to make the CLR work with the types, which vary in the native Win32 and the .NET environment. I couldn’t find anything that would satisfy all my requirements.

So I had two options to accomplish the task.

  • To use P/Invoke and access the WinSCard.dll raw API, and
  • To use the System.Runtime.InteropServices namespace which provides a collection of classes useful for accessing COM objects, and native APIs from .NET.

I tried the first option and realized that there would be a lot of trouble in this hit and miss method of identifying correct prototypes for the WinSCard.dll exported functions. So I was left with just one option: Writing a COM component for Smart Card access and later use the InteropServices to use it in .NET.  It worked!

{mospagebreak title=The Solution}

I have used ATL to develop the component but anyone using the component need not know any COM or ATL details.  If you know them it’s a plus because you can modify the component to suit your needs. I’ve tried to encapsulate enough of the WinSCard API to write a Smart Card enabled application, but there are too many possibilities. So I’ve provided the source code to the component that you can modify and use. Also provided is a sample MFC application, another  in Visual Basic 6.0 and a .NET application that successfully uses the WinSCard.dll to communicate to the Smart Card Reader.

As a plus it’s implemented as a Dual interface so even scripting clients, like JScript and VB Script, can use it.

All the workings are encapsulated in a single class CPCSCReader, exposing a single interface IPCSCReader.The Class Diagram is displayed below:

Smart Cards
 
Figure 1 The CPCSCReader Class

As one can infer from the class Diagram there are two public properties that can be used to identify whether the reader has a card in it and whether it is powered on. I’ve provided a constructor other than the default constructor, which only accepts reader name as its parameter. There are eight other public methods that can be used to communicate with the smart card reader and manage the UI notifications displayed to the user of the application.

{mospagebreak title=Three More Methods}

The following three methods provide the necessary UI components:

  1. SelectReader: Presents the user with a dialog that displays the available IFDs connected to the PC and allows selection of one.
  2. EjectCard: Presents the user with a dialog that notifies the user that the card can be removed safely from the reader.
  3. InsertCard: Presents the user with a dialog signifying that the reader can receive a card now.

And the following five methods provide the way to easy smart card access:

  1. OpenReader
  2. CloseReader
  3. GetReaderName
  4. SetReaderName
  5. SendCommand

I finalized all these UI items and methods after reviewing the PS/SC workgroup (http://www.pcscworkgroup.com) recommendations for implementing such a library. The specification is open and is available for free download at the website.

The COM component is implemented as a DLL and it needs to be registered on the client machine, which can be done by simply running regsvr32.exe <DLL Name> at the command prompt.

Once the component is registered you can use it in a variety of programming languages to access smart Card IFDs which are based on PC/SC specifications. I’m glad that most, if not all of the available Smart Card readers fall under this category. You can find three such usages in the samples accompanying this article.  Let’s move on to .NET and smart cards.

Create a Windows Application in C# or VB.NET. Using the Add Reference … | COM Components tab locate the SCardLib 1.0 Type library and add it to your project. The following images will explain to you how to do it.

Smart Cards 

Smart cards

{mospagebreak title=A New Reference}

And as you click the OK button a new reference is added to the project as shown below:

Smart cards

You may add a using or imports directive to include this namespace to your current files and use this class without really worrying about the details. The Interop generates the code such that the types available perfectly match the interface methods prototypes, which was the biggest hurdle in using P/Invoke.

I issued some commands using the buttons as in the image below. It responded well by returning the appropriate results. I’ve not written the whole business logic code for the application but just how the application would use this Interop generated class.

As soon as the Select Reader button is clicked the following code opens a reader selection Dialog.  Once the user selects and clicks the Ok button it tries to open the reader.

Smart cards

[code]
private void BtnSelectAndOpenReader_Click(object sender, System.EventArgs e)
{
 try
 {
  m_strReaderName = Reader.SelectReader();
  
  if(m_strReaderName.Length > 0)
  {
   if( Reader.OpenReader() == 0 )
   {
    m_bIsReaderOpen = true;
    mcsStatusBar.Text = "Reader opened successfully";
    string strRes;
int nResLen =Reader.SendCommand("00A4040007A0000000031010", 12,out strRes);
   }
  }
 }
 catch(System.Exception ex)
 {
MessageBox.Show(this.Owner ,"An error has occured:nn" + ex.ToString()+ "nnError Message : " + ex.Message );
 }
}
[/code]

{mospagebreak title=The Code}

The ATL COM Component code is self-explanatory, provided you have a fair knowledge of the Microsoft WinSCard.dll API. I’d like to highlight the design I had in my mind.

There is one class CPCSCReader and three other helper classes CReaderSelDlg, CSCEjectDlg and CSCInsertDlg. These work as shown in diagram below:

Smart Cards


The SCardLib COM Component

The Smart Card related code, which relies heavily in WinSCard.dll, resides in the CPCSCReader and IPCSCReader interface implemenatation. The workhorse of this component is the following WinSCard.dll exported APIs:

  • SCardEstablishContext
  • SCardConnect
  • SCardStatus
  • SCardDisconnect
  • SCardTransmit
  • The code in Helper Classes is mostly UI related.

At one place in the CReaderSelDlg implementation I needed to find all the available cards, so one WinSCard API (SCardListReaders) has been used there. More details about these API’s can be found in the MSDN.

Points of Interest

There are several advantages if you’re using such an approach to access Smart Cards in .NET. The most visible one is isolation from the WinSCard API with the COM wrapper and the type conversion from Win32 types to .NET types.  This is done effectively and precisely by the IDE itself. Any comments and suggestion can be posted to me here.

People have great ideas and sometimes it’s just the implementation that falters. Maybe now with the help of this library and any code derived from it, excellent smart card enabled applications can be developed. I’ll continue to refine this Library and fix any bugs that are reported to me. Hope this helps you roll out your first Smart Card application soon!

See you again in the next article in this series where we’ll develop a completely managed wrapper over WinSCard API.

4 thoughts on “Smart Cards in .NET

[gp-comments width="770" linklove="off" ]