|
Packit |
9f0df5 |
/*
|
|
Packit |
9f0df5 |
PCSCv2part10.c: helper functions for PC/SC v2 part 10 services
|
|
Packit |
9f0df5 |
Copyright (C) 2012 Ludovic Rousseau
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
This library is free software; you can redistribute it and/or
|
|
Packit |
9f0df5 |
modify it under the terms of the GNU Lesser General Public
|
|
Packit |
9f0df5 |
License as published by the Free Software Foundation; either
|
|
Packit |
9f0df5 |
version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
This library is distributed in the hope that it will be useful,
|
|
Packit |
9f0df5 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
9f0df5 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
9f0df5 |
Lesser General Public License for more details.
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
You should have received a copy of the GNU Lesser General Public
|
|
Packit |
9f0df5 |
License along with this library; if not, write to the Free Software
|
|
Packit |
9f0df5 |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
9f0df5 |
*/
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
#include <stdio.h>
|
|
Packit |
9f0df5 |
#include <arpa/inet.h>
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
#ifdef __APPLE__
|
|
Packit |
9f0df5 |
#include <PCSC/winscard.h>
|
|
Packit |
9f0df5 |
#include <PCSC/wintypes.h>
|
|
Packit |
9f0df5 |
#else
|
|
Packit |
9f0df5 |
#include <winscard.h>
|
|
Packit |
9f0df5 |
#endif
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
#include "PCSCv2part10.h"
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
int PCSCv2Part10_find_TLV_property_by_tag_from_buffer(
|
|
Packit |
9f0df5 |
unsigned char *buffer, int length, int property, int * value_int)
|
|
Packit |
9f0df5 |
{
|
|
Packit |
9f0df5 |
unsigned char *p;
|
|
Packit |
9f0df5 |
int found = 0, len;
|
|
Packit |
9f0df5 |
int value = -1;
|
|
Packit |
9f0df5 |
int ret = -1; /* not found by default */
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
p = buffer;
|
|
Packit |
9f0df5 |
while (p-buffer < length)
|
|
Packit |
9f0df5 |
{
|
|
Packit |
9f0df5 |
if (*p++ == property)
|
|
Packit |
9f0df5 |
{
|
|
Packit |
9f0df5 |
found = 1;
|
|
Packit |
9f0df5 |
break;
|
|
Packit |
9f0df5 |
}
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
/* go to next tag */
|
|
Packit |
9f0df5 |
len = *p++;
|
|
Packit |
9f0df5 |
p += len;
|
|
Packit |
9f0df5 |
}
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
if (found)
|
|
Packit |
9f0df5 |
{
|
|
Packit |
9f0df5 |
len = *p++;
|
|
Packit |
9f0df5 |
ret = 0;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
switch(len)
|
|
Packit |
9f0df5 |
{
|
|
Packit |
9f0df5 |
case 1:
|
|
Packit |
9f0df5 |
value = *p;
|
|
Packit |
9f0df5 |
break;
|
|
Packit |
9f0df5 |
case 2:
|
|
Packit |
9f0df5 |
value = *p + (*(p+1)<<8);
|
|
Packit |
9f0df5 |
break;
|
|
Packit |
9f0df5 |
case 4:
|
|
Packit |
9f0df5 |
value = *p + (*(p+1)<<8) + (*(p+2)<<16) + (*(p+3)<<24);
|
|
Packit |
9f0df5 |
break;
|
|
Packit |
9f0df5 |
default:
|
|
Packit |
9f0df5 |
/* wrong length for an integer */
|
|
Packit |
9f0df5 |
ret = -2;
|
|
Packit |
9f0df5 |
}
|
|
Packit |
9f0df5 |
}
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
if (value_int)
|
|
Packit |
9f0df5 |
*value_int = value;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
return ret;
|
|
Packit |
9f0df5 |
} /* PCSCv2Part10_find_TLV_property_by_tag_from_buffer */
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
int PCSCv2Part10_find_TLV_property_by_tag_from_hcard(SCARDHANDLE hCard,
|
|
Packit |
9f0df5 |
int property, int * value)
|
|
Packit |
9f0df5 |
{
|
|
Packit |
9f0df5 |
unsigned char buffer[MAX_BUFFER_SIZE];
|
|
Packit |
9f0df5 |
LONG rv;
|
|
Packit |
9f0df5 |
DWORD length;
|
|
Packit |
9f0df5 |
unsigned int i;
|
|
Packit |
9f0df5 |
PCSC_TLV_STRUCTURE *pcsc_tlv;
|
|
Packit |
9f0df5 |
DWORD properties_in_tlv_ioctl;
|
|
Packit |
9f0df5 |
int found;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
rv = SCardControl(hCard, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0,
|
|
Packit |
9f0df5 |
buffer, sizeof buffer, &length);
|
|
Packit |
9f0df5 |
if (rv != SCARD_S_SUCCESS)
|
|
Packit |
9f0df5 |
return -1;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
/* get the number of elements instead of the complete size */
|
|
Packit |
9f0df5 |
length /= sizeof(PCSC_TLV_STRUCTURE);
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
pcsc_tlv = (PCSC_TLV_STRUCTURE *)buffer;
|
|
Packit |
9f0df5 |
found = 0;
|
|
Packit |
9f0df5 |
for (i = 0; i < length; i++)
|
|
Packit |
9f0df5 |
{
|
|
Packit |
9f0df5 |
if (FEATURE_GET_TLV_PROPERTIES == pcsc_tlv[i].tag)
|
|
Packit |
9f0df5 |
{
|
|
Packit |
9f0df5 |
properties_in_tlv_ioctl = ntohl(pcsc_tlv[i].value);
|
|
Packit |
9f0df5 |
found = 1;
|
|
Packit |
9f0df5 |
}
|
|
Packit |
9f0df5 |
}
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
if (! found)
|
|
Packit |
9f0df5 |
return -3;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
rv= SCardControl(hCard, properties_in_tlv_ioctl, NULL, 0,
|
|
Packit |
9f0df5 |
buffer, sizeof buffer, &length);
|
|
Packit |
9f0df5 |
if (rv != SCARD_S_SUCCESS)
|
|
Packit |
9f0df5 |
return -1;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
return PCSCv2Part10_find_TLV_property_by_tag_from_buffer(buffer,
|
|
Packit |
9f0df5 |
length, property, value);
|
|
Packit |
9f0df5 |
}
|
|
Packit |
9f0df5 |
|