1/* 2 * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* 25 * prothandler.c 26 * SmartCardServices 27 */ 28 29/* 30 * MUSCLE SmartCard Development ( http://www.linuxnet.com ) 31 * 32 * Copyright (C) 1999 33 * David Corcoran <corcoran@linuxnet.com> 34 * Copyright (C) 2004 35 * Ludovic Rousseau <ludovic.rousseau@free.fr> 36 * 37 * $Id: prothandler.c 123 2010-03-27 10:50:42Z ludovic.rousseau@gmail.com $ 38 */ 39 40/** 41 * @file 42 * @brief This handles protocol defaults, PTS, etc. 43 */ 44 45#include "config.h" 46#include <string.h> 47 48#include "wintypes.h" 49#include "pcsclite.h" 50#include "ifdhandler.h" 51#include "debuglog.h" 52#include "readerfactory.h" 53#include "prothandler.h" 54#include "atrhandler.h" 55#include "ifdwrapper.h" 56#include "eventhandler.h" 57 58/* 59 * Function: PHGetDefaultProtocol Purpose : To get the default protocol 60 * used immediately after reset. This protocol is returned from the 61 * function. 62 */ 63 64UCHAR PHGetDefaultProtocol(const unsigned char *pucAtr, DWORD dwLength) 65{ 66 SMARTCARD_EXTENSION sSmartCard; 67 68 /* 69 * Zero out everything 70 */ 71 memset(&sSmartCard, 0x00, sizeof(SMARTCARD_EXTENSION)); 72 73 if (ATRDecodeAtr(&sSmartCard, pucAtr, dwLength)) 74 return sSmartCard.CardCapabilities.CurrentProtocol; 75 else 76 return 0x00; 77} 78 79/* 80 * Function: PHGetAvailableProtocols Purpose : To get the protocols 81 * supported by the card. These protocols are returned from the function 82 * as bit masks. 83 */ 84 85UCHAR PHGetAvailableProtocols(const unsigned char *pucAtr, DWORD dwLength) 86{ 87 SMARTCARD_EXTENSION sSmartCard; 88 89 /* 90 * Zero out everything 91 */ 92 memset(&sSmartCard, 0x00, sizeof(SMARTCARD_EXTENSION)); 93 94 if (ATRDecodeAtr(&sSmartCard, pucAtr, dwLength)) 95 return sSmartCard.CardCapabilities.AvailableProtocols; 96 else 97 return 0x00; 98} 99 100/* 101 * Function: PHSetProtocol Purpose : To determine which protocol to use. 102 * SCardConnect has a DWORD dwPreferredProtocols that is a bitmask of what 103 * protocols to use. Basically, if T=N where N is not zero will be used 104 * first if it is available in ucAvailable. Otherwise it will always 105 * default to T=0. 106 * 107 * IFDSetPTS() is _always_ called so that the driver can initialise its data 108 */ 109 110DWORD PHSetProtocol(struct ReaderContext * rContext, 111 DWORD dwPreferred, UCHAR ucAvailable, UCHAR ucDefault) 112{ 113 DWORD protocol; 114 LONG rv; 115 UCHAR ucChosen; 116 117 /* App has specified no protocol */ 118 if (dwPreferred == 0) 119 return SET_PROTOCOL_WRONG_ARGUMENT; 120 121 /* requested protocol is not available */ 122 if (! (dwPreferred & ucAvailable)) 123 { 124 /* Note: 125 * dwPreferred must be either SCARD_PROTOCOL_T0 or SCARD_PROTOCOL_T1 126 * if dwPreferred == SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 the test 127 * (SCARD_PROTOCOL_T0 == dwPreferred) will not work as expected 128 * and the debug message will not be correct. 129 * 130 * This case may only occur if 131 * dwPreferred == SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 132 * and ucAvailable == 0 since we have (dwPreferred & ucAvailable) == 0 133 * and the case ucAvailable == 0 should never occur (the card is at 134 * least T=0 or T=1) 135 */ 136 Log2(PCSC_LOG_ERROR, "Protocol T=%d requested but unsupported by the card", 137 (SCARD_PROTOCOL_T0 == dwPreferred) ? 0 : 1); 138 return SET_PROTOCOL_WRONG_ARGUMENT; 139 } 140 141 /* set default value */ 142 protocol = ucDefault; 143 144 /* keep only the available protocols */ 145 dwPreferred &= ucAvailable; 146 147 /* we try to use T=1 first */ 148 if (dwPreferred & SCARD_PROTOCOL_T1) 149 ucChosen = SCARD_PROTOCOL_T1; 150 else 151 if (dwPreferred & SCARD_PROTOCOL_T0) 152 ucChosen = SCARD_PROTOCOL_T0; 153 else 154 /* App wants unsupported protocol */ 155 return SET_PROTOCOL_WRONG_ARGUMENT; 156 157 Log2(PCSC_LOG_INFO, "Attempting PTS to T=%d", 158 (SCARD_PROTOCOL_T0 == ucChosen ? 0 : 1)); 159 rv = IFDSetPTS(rContext, ucChosen, 0x00, 0x00, 0x00, 0x00); 160 161 if (IFD_SUCCESS == rv) 162 protocol = ucChosen; 163 else 164 if (IFD_NOT_SUPPORTED == rv) 165 Log2(PCSC_LOG_INFO, "PTS not supported by driver, using T=%d", 166 (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1); 167 else 168 if (IFD_PROTOCOL_NOT_SUPPORTED == rv) 169 Log2(PCSC_LOG_INFO, "PTS protocol not supported, using T=%d", 170 (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1); 171 else 172 { 173 Log3(PCSC_LOG_INFO, "PTS failed (%d), using T=%d", rv, 174 (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1); 175 176 /* ISO 7816-3:1997 ch. 7.2 PPS protocol page 14 177 * - If the PPS exchange is unsuccessful, then the interface device 178 * shall either reset or reject the card. 179 */ 180 return SET_PROTOCOL_PPS_FAILED; 181 } 182 183 return protocol; 184} 185 186