Package smartcard :: Package pcsc :: Module PCSCPart10
[hide private]
[frames] | no frames]

Source Code for Module smartcard.pcsc.PCSCPart10

  1  """PCSCPart10: PC/SC Part 10 (pinpad) 
  2   
  3  __author__ = "Ludovic Rousseau" 
  4   
  5  Copyright 2009-2010 Ludovic Rosseau 
  6  Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr 
  7   
  8  This file is part of pyscard. 
  9   
 10  pyscard is free software; you can redistribute it and/or modify 
 11  it under the terms of the GNU Lesser General Public License as published by 
 12  the Free Software Foundation; either version 2.1 of the License, or 
 13  (at your option) any later version. 
 14   
 15  pyscard is distributed in the hope that it will be useful, 
 16  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 18  GNU Lesser General Public License for more details. 
 19   
 20  You should have received a copy of the GNU Lesser General Public License 
 21  along with pyscard; if not, write to the Free Software 
 22  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
 23  """ 
 24   
 25  from smartcard.scard import * 
 26   
 27  # constants defined in PC/SC v2 Part 10 
 28  CM_IOCTL_GET_FEATURE_REQUEST = SCARD_CTL_CODE(3400) 
 29   
 30  FEATURE_VERIFY_PIN_START = 0x01 
 31  FEATURE_VERIFY_PIN_FINISH = 0x02 
 32  FEATURE_MODIFY_PIN_START = 0x03 
 33  FEATURE_MODIFY_PIN_FINISH = 0x04 
 34  FEATURE_GET_KEY_PRESSED = 0x05 
 35  FEATURE_VERIFY_PIN_DIRECT = 0x06 
 36  FEATURE_MODIFY_PIN_DIRECT = 0x07 
 37  FEATURE_MCT_READER_DIRECT = 0x08 
 38  FEATURE_MCT_UNIVERSAL = 0x09 
 39  FEATURE_IFD_PIN_PROPERTIES = 0x0A 
 40  FEATURE_ABORT = 0x0B 
 41  FEATURE_SET_SPE_MESSAGE = 0x0C 
 42  FEATURE_VERIFY_PIN_DIRECT_APP_ID = 0x0D 
 43  FEATURE_MODIFY_PIN_DIRECT_APP_ID = 0x0E 
 44  FEATURE_WRITE_DISPLAY = 0x0F 
 45  FEATURE_GET_KEY = 0x10 
 46  FEATURE_IFD_DISPLAY_PROPERTIES = 0x11 
 47  FEATURE_GET_TLV_PROPERTIES = 0x12 
 48  FEATURE_CCID_ESC_COMMAND = 0x13 
 49   
 50  Features = { 
 51  "FEATURE_VERIFY_PIN_START": FEATURE_VERIFY_PIN_START, 
 52  "FEATURE_VERIFY_PIN_FINISH": FEATURE_VERIFY_PIN_FINISH, 
 53  "FEATURE_MODIFY_PIN_START": FEATURE_MODIFY_PIN_START, 
 54  "FEATURE_MODIFY_PIN_FINISH": FEATURE_MODIFY_PIN_FINISH, 
 55  "FEATURE_GET_KEY_PRESSED": FEATURE_GET_KEY_PRESSED, 
 56  "FEATURE_VERIFY_PIN_DIRECT": FEATURE_VERIFY_PIN_DIRECT, 
 57  "FEATURE_MODIFY_PIN_DIRECT": FEATURE_MODIFY_PIN_DIRECT, 
 58  "FEATURE_MCT_READER_DIRECT": FEATURE_MCT_READER_DIRECT, 
 59  "FEATURE_MCT_UNIVERSAL": FEATURE_MCT_UNIVERSAL, 
 60  "FEATURE_IFD_PIN_PROPERTIES": FEATURE_IFD_PIN_PROPERTIES, 
 61  "FEATURE_ABORT": FEATURE_ABORT, 
 62  "FEATURE_SET_SPE_MESSAGE": FEATURE_SET_SPE_MESSAGE, 
 63  "FEATURE_VERIFY_PIN_DIRECT_APP_ID": FEATURE_VERIFY_PIN_DIRECT_APP_ID, 
 64  "FEATURE_MODIFY_PIN_DIRECT_APP_ID": FEATURE_MODIFY_PIN_DIRECT_APP_ID, 
 65  "FEATURE_WRITE_DISPLAY": FEATURE_WRITE_DISPLAY, 
 66  "FEATURE_GET_KEY": FEATURE_GET_KEY, 
 67  "FEATURE_IFD_DISPLAY_PROPERTIES": FEATURE_IFD_DISPLAY_PROPERTIES, 
 68  "FEATURE_GET_TLV_PROPERTIES": FEATURE_GET_TLV_PROPERTIES, 
 69  "FEATURE_CCID_ESC_COMMAND": FEATURE_CCID_ESC_COMMAND} 
 70   
 71  # properties returned by FEATURE_GET_TLV_PROPERTIES 
 72  PCSCv2_PART10_PROPERTY_wLcdLayout = 1 
 73  PCSCv2_PART10_PROPERTY_bEntryValidationCondition = 2 
 74  PCSCv2_PART10_PROPERTY_bTimeOut2 = 3 
 75  PCSCv2_PART10_PROPERTY_wLcdMaxCharacters = 4 
 76  PCSCv2_PART10_PROPERTY_wLcdMaxLines = 5 
 77  PCSCv2_PART10_PROPERTY_bMinPINSize = 6 
 78  PCSCv2_PART10_PROPERTY_bMaxPINSize = 7 
 79  PCSCv2_PART10_PROPERTY_sFirmwareID = 8 
 80  PCSCv2_PART10_PROPERTY_bPPDUSupport = 9 
 81   
 82  Properties = { 
 83  "PCSCv2_PART10_PROPERTY_wLcdLayout": PCSCv2_PART10_PROPERTY_wLcdLayout, 
 84  "PCSCv2_PART10_PROPERTY_bEntryValidationCondition": PCSCv2_PART10_PROPERTY_bEntryValidationCondition, 
 85  "PCSCv2_PART10_PROPERTY_bTimeOut2": PCSCv2_PART10_PROPERTY_bTimeOut2, 
 86  "PCSCv2_PART10_PROPERTY_wLcdMaxCharacters": PCSCv2_PART10_PROPERTY_wLcdMaxCharacters, 
 87  "PCSCv2_PART10_PROPERTY_wLcdMaxLines": PCSCv2_PART10_PROPERTY_wLcdMaxLines, 
 88  "PCSCv2_PART10_PROPERTY_bMinPINSize": PCSCv2_PART10_PROPERTY_bMinPINSize, 
 89  "PCSCv2_PART10_PROPERTY_bMaxPINSize": PCSCv2_PART10_PROPERTY_bMaxPINSize, 
 90  "PCSCv2_PART10_PROPERTY_sFirmwareID": PCSCv2_PART10_PROPERTY_sFirmwareID} 
 91   
 92  # we already have:       Features['FEATURE_x'] = FEATURE_x 
 93  # we will now also have: Features[FEATURE_x] = 'FEATURE_x' 
 94  for k in Features.keys(): 
 95      Features[Features[k]] = k 
 96   
 97  for k in Properties.keys(): 
 98      Properties[Properties[k]] = k 
 99   
100   
101 -def getFeatureRequest(cardConnection):
102 """ Get the list of Part10 features supported by the reader. 103 104 @param cardConnection: L{CardConnection} object 105 106 @rtype: list 107 @return: a list of list [[tag1, value1], [tag2, value2]] 108 """ 109 response = cardConnection.control(CM_IOCTL_GET_FEATURE_REQUEST, []) 110 features = [] 111 while (len(response) > 0): 112 tag = response[0] 113 control = (((((response[2] << 8) + response[3]) << 8) + response[4]) << 8) + response[5] 114 try: 115 features.append([Features[tag], control]) 116 except KeyError: 117 pass 118 del response[:6] 119 return features
120 121
122 -def hasFeature(featureList, feature):
123 """ return the controlCode for a feature or None 124 125 @param feature: feature to look for 126 @param featureList: feature list as returned by L{getFeatureRequest()} 127 128 @return: feature value or None 129 """ 130 for f in featureList: 131 if f[0] == feature or Features[f[0]] == feature: 132 return f[1]
133 134
135 -def getPinProperties(cardConnection, featureList=None, controlCode=None):
136 """ return the PIN_PROPERTIES structure 137 138 @param cardConnection: L{CardConnection} object 139 @param featureList: feature list as returned by L{getFeatureRequest()} 140 @param controlCode: control code for L{FEATURE_IFD_PIN_PROPERTIES} 141 142 @rtype: dict 143 @return: a dict """ 144 if controlCode is None: 145 if featureList is None: 146 featureList = getFeatureRequest(cardConnection) 147 controlCode = hasFeature(featureList, FEATURE_IFD_PIN_PROPERTIES) 148 149 if controlCode is None: 150 return {'raw': []} 151 152 response = cardConnection.control(controlCode, []) 153 d = { 154 'raw': response, 155 'LcdLayoutX': response[0], 156 'LcdLayoutY': response[1], 157 'EntryValidationCondition': response[2], 158 'TimeOut2': response[3]} 159 160 return d
161 162
163 -def getTlvProperties(cardConnection, featureList=None, controlCode=None):
164 """ return the GET_TLV_PROPERTIES structure 165 166 @param cardConnection: L{CardConnection} object 167 @param featureList: feature list as returned by L{getFeatureRequest()} 168 @param controlCode: control code for L{FEATURE_GET_TLV_PROPERTIES} 169 170 @rtype: dict 171 @return: a dict """ 172 if controlCode is None: 173 if featureList is None: 174 featureList = getFeatureRequest(cardConnection) 175 controlCode = hasFeature(featureList, FEATURE_GET_TLV_PROPERTIES) 176 177 if controlCode is None: 178 return {'raw': []} 179 180 response = cardConnection.control(controlCode, []) 181 d = { 182 'raw': response, 183 } 184 185 # create a new list to consume it 186 tmp = list(response) 187 while tmp: 188 tag = tmp[0] 189 len = tmp[1] 190 data = tmp[2:2 + len] 191 192 if PCSCv2_PART10_PROPERTY_sFirmwareID == tag: 193 # convert to a string 194 data = "".join([chr(c) for c in data]) 195 # we now suppose the value is an integer 196 elif 1 == len: 197 # byte 198 data = data[0] 199 elif 2 == len: 200 # 16 bits value 201 data = data[1] * 256 + data[0] 202 elif 4 == len: 203 # 32 bits value 204 data = ((data[3] * 256 + data[2]) * 256 + data[1]) * 256 + data[0] 205 206 # store the value in the dictionnary 207 d[Properties[tag]] = data 208 209 del tmp[0:2 + len] 210 211 return d
212 213 if __name__ == '__main__': 214 """Small sample illustrating the use of PCSCPart10.""" 215 from smartcard.pcsc.PCSCReader import readers 216 cc = readers()[0].createConnection() 217 cc.connect(mode=SCARD_SHARE_DIRECT) 218 219 #print cc.control( CM_IOCTL_GET_FEATURE_REQUEST ) 220 features = getFeatureRequest(cc) 221 print features 222 223 print hasFeature(features, FEATURE_VERIFY_PIN_START) 224 print hasFeature(features, FEATURE_VERIFY_PIN_DIRECT) 225 226 properties = getPinProperties(cc) 227 print "\nPinProperties:" 228 for k in properties.keys(): 229 print " %s: %s" % (k, properties[k]) 230 231 print "\nTlvProperties:" 232 properties = getTlvProperties(cc) 233 for k in properties.keys(): 234 print " %s: %s" % (k, properties[k]) 235