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 __future__ import print_function 
 26  from smartcard.scard import * 
 27   
 28  # constants defined in PC/SC v2 Part 10 
 29  CM_IOCTL_GET_FEATURE_REQUEST = SCARD_CTL_CODE(3400) 
 30   
 31  FEATURE_VERIFY_PIN_START = 0x01 
 32  FEATURE_VERIFY_PIN_FINISH = 0x02 
 33  FEATURE_MODIFY_PIN_START = 0x03 
 34  FEATURE_MODIFY_PIN_FINISH = 0x04 
 35  FEATURE_GET_KEY_PRESSED = 0x05 
 36  FEATURE_VERIFY_PIN_DIRECT = 0x06 
 37  FEATURE_MODIFY_PIN_DIRECT = 0x07 
 38  FEATURE_MCT_READER_DIRECT = 0x08 
 39  FEATURE_MCT_UNIVERSAL = 0x09 
 40  FEATURE_IFD_PIN_PROPERTIES = 0x0A 
 41  FEATURE_ABORT = 0x0B 
 42  FEATURE_SET_SPE_MESSAGE = 0x0C 
 43  FEATURE_VERIFY_PIN_DIRECT_APP_ID = 0x0D 
 44  FEATURE_MODIFY_PIN_DIRECT_APP_ID = 0x0E 
 45  FEATURE_WRITE_DISPLAY = 0x0F 
 46  FEATURE_GET_KEY = 0x10 
 47  FEATURE_IFD_DISPLAY_PROPERTIES = 0x11 
 48  FEATURE_GET_TLV_PROPERTIES = 0x12 
 49  FEATURE_CCID_ESC_COMMAND = 0x13 
 50   
 51  Features = { 
 52  "FEATURE_VERIFY_PIN_START": FEATURE_VERIFY_PIN_START, 
 53  "FEATURE_VERIFY_PIN_FINISH": FEATURE_VERIFY_PIN_FINISH, 
 54  "FEATURE_MODIFY_PIN_START": FEATURE_MODIFY_PIN_START, 
 55  "FEATURE_MODIFY_PIN_FINISH": FEATURE_MODIFY_PIN_FINISH, 
 56  "FEATURE_GET_KEY_PRESSED": FEATURE_GET_KEY_PRESSED, 
 57  "FEATURE_VERIFY_PIN_DIRECT": FEATURE_VERIFY_PIN_DIRECT, 
 58  "FEATURE_MODIFY_PIN_DIRECT": FEATURE_MODIFY_PIN_DIRECT, 
 59  "FEATURE_MCT_READER_DIRECT": FEATURE_MCT_READER_DIRECT, 
 60  "FEATURE_MCT_UNIVERSAL": FEATURE_MCT_UNIVERSAL, 
 61  "FEATURE_IFD_PIN_PROPERTIES": FEATURE_IFD_PIN_PROPERTIES, 
 62  "FEATURE_ABORT": FEATURE_ABORT, 
 63  "FEATURE_SET_SPE_MESSAGE": FEATURE_SET_SPE_MESSAGE, 
 64  "FEATURE_VERIFY_PIN_DIRECT_APP_ID": FEATURE_VERIFY_PIN_DIRECT_APP_ID, 
 65  "FEATURE_MODIFY_PIN_DIRECT_APP_ID": FEATURE_MODIFY_PIN_DIRECT_APP_ID, 
 66  "FEATURE_WRITE_DISPLAY": FEATURE_WRITE_DISPLAY, 
 67  "FEATURE_GET_KEY": FEATURE_GET_KEY, 
 68  "FEATURE_IFD_DISPLAY_PROPERTIES": FEATURE_IFD_DISPLAY_PROPERTIES, 
 69  "FEATURE_GET_TLV_PROPERTIES": FEATURE_GET_TLV_PROPERTIES, 
 70  "FEATURE_CCID_ESC_COMMAND": FEATURE_CCID_ESC_COMMAND} 
 71   
 72  # properties returned by FEATURE_GET_TLV_PROPERTIES 
 73  PCSCv2_PART10_PROPERTY_wLcdLayout = 1 
 74  PCSCv2_PART10_PROPERTY_bEntryValidationCondition = 2 
 75  PCSCv2_PART10_PROPERTY_bTimeOut2 = 3 
 76  PCSCv2_PART10_PROPERTY_wLcdMaxCharacters = 4 
 77  PCSCv2_PART10_PROPERTY_wLcdMaxLines = 5 
 78  PCSCv2_PART10_PROPERTY_bMinPINSize = 6 
 79  PCSCv2_PART10_PROPERTY_bMaxPINSize = 7 
 80  PCSCv2_PART10_PROPERTY_sFirmwareID = 8 
 81  PCSCv2_PART10_PROPERTY_bPPDUSupport = 9 
 82  PCSCv2_PART10_PROPERTY_dwMaxAPDUDataSize = 10 
 83  PCSCv2_PART10_PROPERTY_wIdVendor = 11 
 84  PCSCv2_PART10_PROPERTY_wIdProduct = 12 
 85   
 86  Properties = { 
 87  "PCSCv2_PART10_PROPERTY_wLcdLayout": PCSCv2_PART10_PROPERTY_wLcdLayout, 
 88  "PCSCv2_PART10_PROPERTY_bEntryValidationCondition": \ 
 89      PCSCv2_PART10_PROPERTY_bEntryValidationCondition, 
 90  "PCSCv2_PART10_PROPERTY_bTimeOut2": PCSCv2_PART10_PROPERTY_bTimeOut2, 
 91  "PCSCv2_PART10_PROPERTY_wLcdMaxCharacters": \ 
 92  PCSCv2_PART10_PROPERTY_wLcdMaxCharacters, 
 93  "PCSCv2_PART10_PROPERTY_wLcdMaxLines": PCSCv2_PART10_PROPERTY_wLcdMaxLines, 
 94  "PCSCv2_PART10_PROPERTY_bMinPINSize": PCSCv2_PART10_PROPERTY_bMinPINSize, 
 95  "PCSCv2_PART10_PROPERTY_bMaxPINSize": PCSCv2_PART10_PROPERTY_bMaxPINSize, 
 96  "PCSCv2_PART10_PROPERTY_sFirmwareID": PCSCv2_PART10_PROPERTY_sFirmwareID, 
 97  "PCSCv2_PART10_PROPERTY_bPPDUSupport": PCSCv2_PART10_PROPERTY_bPPDUSupport, 
 98  "PCSCv2_PART10_PROPERTY_dwMaxAPDUDataSize": PCSCv2_PART10_PROPERTY_dwMaxAPDUDataSize, 
 99  "PCSCv2_PART10_PROPERTY_wIdVendor": PCSCv2_PART10_PROPERTY_wIdVendor, 
100  "PCSCv2_PART10_PROPERTY_wIdProduct": PCSCv2_PART10_PROPERTY_wIdProduct} 
101   
102  # we already have:       Features['FEATURE_x'] = FEATURE_x 
103  # we will now also have: Features[FEATURE_x] = 'FEATURE_x' 
104  for k in list(Features.keys()): 
105      Features[Features[k]] = k 
106   
107  for k in list(Properties.keys()): 
108      Properties[Properties[k]] = k 
109   
110   
111 -def getFeatureRequest(cardConnection):
112 """ Get the list of Part10 features supported by the reader. 113 114 @param cardConnection: L{CardConnection} object 115 116 @rtype: list 117 @return: a list of list [[tag1, value1], [tag2, value2]] 118 """ 119 response = cardConnection.control(CM_IOCTL_GET_FEATURE_REQUEST, []) 120 features = [] 121 while (len(response) > 0): 122 tag = response[0] 123 control = (((((response[2] << 8) + \ 124 response[3]) << 8) + \ 125 response[4]) << 8) + \ 126 response[5] 127 try: 128 features.append([Features[tag], control]) 129 except KeyError: 130 pass 131 del response[:6] 132 return features
133 134
135 -def hasFeature(featureList, feature):
136 """ return the controlCode for a feature or None 137 138 @param feature: feature to look for 139 @param featureList: feature list as returned by L{getFeatureRequest()} 140 141 @return: feature value or None 142 """ 143 for f in featureList: 144 if f[0] == feature or Features[f[0]] == feature: 145 return f[1]
146 147
148 -def getPinProperties(cardConnection, featureList=None, controlCode=None):
149 """ return the PIN_PROPERTIES structure 150 151 @param cardConnection: L{CardConnection} object 152 @param featureList: feature list as returned by L{getFeatureRequest()} 153 @param controlCode: control code for L{FEATURE_IFD_PIN_PROPERTIES} 154 155 @rtype: dict 156 @return: a dict """ 157 if controlCode is None: 158 if featureList is None: 159 featureList = getFeatureRequest(cardConnection) 160 controlCode = hasFeature(featureList, FEATURE_IFD_PIN_PROPERTIES) 161 162 if controlCode is None: 163 return {'raw': []} 164 165 response = cardConnection.control(controlCode, []) 166 d = { 167 'raw': response, 168 'LcdLayoutX': response[0], 169 'LcdLayoutY': response[1], 170 'EntryValidationCondition': response[2], 171 'TimeOut2': response[3]} 172 173 return d
174 175
176 -def getTlvProperties(cardConnection, featureList=None, controlCode=None):
177 """ return the GET_TLV_PROPERTIES structure 178 179 @param cardConnection: L{CardConnection} object 180 @param featureList: feature list as returned by L{getFeatureRequest()} 181 @param controlCode: control code for L{FEATURE_GET_TLV_PROPERTIES} 182 183 @rtype: dict 184 @return: a dict """ 185 if controlCode is None: 186 if featureList is None: 187 featureList = getFeatureRequest(cardConnection) 188 controlCode = hasFeature(featureList, FEATURE_GET_TLV_PROPERTIES) 189 190 if controlCode is None: 191 return {'raw': []} 192 193 response = cardConnection.control(controlCode, []) 194 d = { 195 'raw': response, 196 } 197 198 # create a new list to consume it 199 tmp = list(response) 200 while tmp: 201 tag = tmp[0] 202 len = tmp[1] 203 data = tmp[2:2 + len] 204 205 if PCSCv2_PART10_PROPERTY_sFirmwareID == tag: 206 # convert to a string 207 data = "".join([chr(c) for c in data]) 208 # we now suppose the value is an integer 209 elif 1 == len: 210 # byte 211 data = data[0] 212 elif 2 == len: 213 # 16 bits value 214 data = data[1] * 256 + data[0] 215 elif 4 == len: 216 # 32 bits value 217 data = ((data[3] * 256 + data[2]) * 256 + data[1]) * 256 + data[0] 218 219 # store the value in the dictionnary 220 try: 221 d[Properties[tag]] = data 222 except KeyError: 223 d["UNKNOWN"] = data 224 225 del tmp[0:2 + len] 226 227 return d
228 229 if __name__ == '__main__': 230 """Small sample illustrating the use of PCSCPart10.""" 231 from smartcard.pcsc.PCSCReader import PCSCReader 232 cc = PCSCReader.readers()[0].createConnection() 233 cc.connect(mode=SCARD_SHARE_DIRECT) 234 235 #print(cc.control(CM_IOCTL_GET_FEATURE_REQUEST)) 236 features = getFeatureRequest(cc) 237 print(features) 238 239 print(hasFeature(features, FEATURE_VERIFY_PIN_START)) 240 print(hasFeature(features, FEATURE_VERIFY_PIN_DIRECT)) 241 242 properties = getPinProperties(cc) 243 print("\nPinProperties:") 244 for k, v in list(properties.items()): 245 print(" %s: %s" % (k, v)) 246 247 print("\nTlvProperties:") 248 properties = getTlvProperties(cc) 249 for k, v in list(properties.items()): 250 print(" %s: %s" % (k, v)) 251