Blame examples/PCSCv2part10.c

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