1/* 2 PCSCv2part10.c: helper functions for PC/SC v2 part 10 services 3 Copyright (C) 2012 Ludovic Rousseau 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18*/ 19 20/* 21 * $Id: PCSCv2part10.c 6559 2013-03-06 14:18:24Z rousseau $ 22 */ 23 24#include <stdio.h> 25#include <arpa/inet.h> 26 27#ifdef __APPLE__ 28#include <PCSC/winscard.h> 29#include <PCSC/wintypes.h> 30#else 31#include <winscard.h> 32#endif 33 34#include "PCSCv2part10.h" 35 36int PCSCv2Part10_find_TLV_property_by_tag_from_buffer( 37 unsigned char *buffer, int length, int property, int * value_int) 38{ 39 unsigned char *p; 40 int found = 0, len; 41 int value = -1; 42 int ret = -1; /* not found by default */ 43 44 p = buffer; 45 while (p-buffer < length) 46 { 47 if (*p++ == property) 48 { 49 found = 1; 50 break; 51 } 52 53 /* go to next tag */ 54 len = *p++; 55 p += len; 56 } 57 58 if (found) 59 { 60 len = *p++; 61 ret = 0; 62 63 switch(len) 64 { 65 case 1: 66 value = *p; 67 break; 68 case 2: 69 value = *p + (*(p+1)<<8); 70 break; 71 case 4: 72 value = *p + (*(p+1)<<8) + (*(p+2)<<16) + (*(p+3)<<24); 73 break; 74 default: 75 /* wrong length for an integer */ 76 ret = -2; 77 } 78 } 79 80 if (value_int) 81 *value_int = value; 82 83 return ret; 84} /* PCSCv2Part10_find_TLV_property_by_tag_from_buffer */ 85 86int PCSCv2Part10_find_TLV_property_by_tag_from_hcard(SCARDHANDLE hCard, 87 int property, int * value) 88{ 89 unsigned char buffer[MAX_BUFFER_SIZE]; 90 LONG rv; 91 DWORD length; 92 unsigned int i; 93 PCSC_TLV_STRUCTURE *pcsc_tlv; 94 DWORD properties_in_tlv_ioctl; 95 int found; 96 97 rv = SCardControl(hCard, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0, 98 buffer, sizeof buffer, &length); 99 if (rv != SCARD_S_SUCCESS) 100 return -1; 101 102 /* get the number of elements instead of the complete size */ 103 length /= sizeof(PCSC_TLV_STRUCTURE); 104 105 pcsc_tlv = (PCSC_TLV_STRUCTURE *)buffer; 106 found = 0; 107 for (i = 0; i < length; i++) 108 { 109 if (FEATURE_GET_TLV_PROPERTIES == pcsc_tlv[i].tag) 110 { 111 properties_in_tlv_ioctl = ntohl(pcsc_tlv[i].value); 112 found = 1; 113 } 114 } 115 116 if (! found) 117 return -3; 118 119 rv= SCardControl(hCard, properties_in_tlv_ioctl, NULL, 0, 120 buffer, sizeof buffer, &length); 121 if (rv != SCARD_S_SUCCESS) 122 return -1; 123 124 return PCSCv2Part10_find_TLV_property_by_tag_from_buffer(buffer, 125 length, property, value); 126} 127 128