Thursday, August 9, 2012

libPCSCv2part10

PC/SC v2 part 10 standard "Part 10 IFDs with Secure PIN Entry Capabilities" offers a way to get some information from a smart card driver.

I already blogged about this service in

Using the SCardControl(FEATURE_GET_TLV_PROPERTIES, ...) require some code to parse the result TLV buffer.

Library API

The idea of libPCSCv2part10 is to allow application programmers to use a function as simple as give_me_the_value_of_tag_x().

The library provides two functions:
  • PCSCv2Part10_find_TLV_property_by_tag_from_buffer() "low" level
  • PCSCv2Part10_find_TLV_property_by_tag_from_hcard() "high" level

The difference between the two functions is that PCSCv2Part10_find_TLV_property_by_tag_from_hcard() uses a SCARDHANDLE hCard and PCSCv2Part10_find_TLV_property_by_tag_from_buffer() uses a buffer already retrieved using SCardControl(FEATURE_GET_TLV_PROPERTIES, ...)

The API is documented at libPCSCv2part10.

The project is hosted in the contrib/libPCSCv2part10/ directory of the pcsc-lite project.

Sample code


/*
    sample.c: example of use of libPCSCv2part10 helper functions
    Copyright (C) 2012   Ludovic Rousseau

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

/*
 * $Id: sample.c 6416 2012-08-08 09:49:00Z rousseau $
 */

#include <stdio.h>

#ifdef __APPLE__
#include <PCSC/winscard.h>
#include <PCSC/wintypes.h>
#else
#include <winscard.h>
#endif
#include <reader.h>


#include "PCSCv2part10.h"

/* PCSC error */
#define PCSC_ERROR_EXIT(rv) \
if (rv != SCARD_S_SUCCESS) \
{ \
 printf("Failed at line %d with %s (0x%lX)\n", __LINE__, pcsc_stringify_error(rv), rv); \
 goto end; \
}

int main(void)
{
 LONG rv;
 SCARDCONTEXT hContext;
 SCARDHANDLE hCard;
 int value, ret = -1;
 DWORD dwReaders, dwPref;
 char *mszReaders;

 rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
 PCSC_ERROR_EXIT(rv)

 dwReaders = SCARD_AUTOALLOCATE;
 rv = SCardListReaders(hContext, NULL, (LPSTR)&mszReaders, &dwReaders);
 PCSC_ERROR_EXIT(rv)

 /* use first reader */
 printf("Using reaer: %s\n", mszReaders);

 rv = SCardConnect(hContext, mszReaders,
  SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
  &hCard, &dwPref);

 /* the interesting part is here */
 ret = PCSCv2Part10_find_TLV_property_by_tag_from_hcard(hCard,
  PCSCv2_PART10_PROPERTY_wIdVendor, &value);
 printf("ret: %d\n", ret);
 printf("value for PCSCv2_PART10_PROPERTY_wIdVendor: 0x%04X\n", value),

 rv = SCardDisconnect(hCard, SCARD_LEAVE_CARD);
 PCSC_ERROR_EXIT(rv)

 rv = SCardFreeMemory(hContext, mszReaders);
 PCSC_ERROR_EXIT(rv)

 rv = SCardReleaseContext(hContext);
 PCSC_ERROR_EXIT(rv)

end:
 return ret;
}

How to use it

The code is very short. I don't think it is a good idea to make a library with just two functions. My idea is that a project FooBar using the function will just integrate the two files (PCSCv2part10.c and PCSCv2part10.h) into the project FooBar.

License

The license is GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

Conclusion

Feel free to use the code, make comments or improvements.