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
- Identifying a reader model (part 2)
- FEATURE_CCID_ESC_COMMAND
- Extended APDU support reported by PC/SC and PC/SC workgroup, November 2011 meeting results
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.