/usr/share/pyshared/smartcard/pcsc/PCSCCardConnection.py is in python-pyscard 1.6.12.1-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | """PCSCCardConnection class manages connections thru a PCSC reader.
__author__ = "http://www.gemalto.com"
Copyright 2001-2012 gemalto
Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com
This file is part of pyscard.
pyscard is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
pyscard is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with pyscard; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
from smartcard.CardConnection import CardConnection
from smartcard.Exceptions import (CardConnectionException,
NoCardException, SmartcardException)
from smartcard.Observer import Observable
from smartcard.scard import *
def translateprotocolmask(protocol):
"""Translate CardConnection protocol mask into PCSC protocol mask."""
pcscprotocol = 0
if None != protocol:
if CardConnection.T0_protocol & protocol:
pcscprotocol |= SCARD_PROTOCOL_T0
if CardConnection.T1_protocol & protocol:
pcscprotocol |= SCARD_PROTOCOL_T1
if CardConnection.RAW_protocol & protocol:
pcscprotocol |= SCARD_PROTOCOL_RAW
if CardConnection.T15_protocol & protocol:
pcscprotocol |= SCARD_PROTOCOL_T15
return pcscprotocol
def translateprotocolheader(protocol):
"""Translate protocol into PCSC protocol header."""
pcscprotocol = 0
if None != protocol:
if CardConnection.T0_protocol == protocol:
pcscprotocol = SCARD_PCI_T0
if CardConnection.T1_protocol == protocol:
pcscprotocol = SCARD_PCI_T1
if CardConnection.RAW_protocol == protocol:
pcscprotocol = SCARD_PCI_RAW
return pcscprotocol
dictProtocolHeader = {SCARD_PCI_T0: 'T0', SCARD_PCI_T1: 'T1',
SCARD_PCI_RAW: 'RAW'}
dictProtocol = {SCARD_PROTOCOL_T0: 'T0', SCARD_PROTOCOL_T1: 'T1',
SCARD_PROTOCOL_RAW: 'RAW', SCARD_PROTOCOL_T15: 'T15',
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1: 'T0 or T1'}
class PCSCCardConnection(CardConnection):
"""PCSCCard connection class. Handles connection with a card thru a
PCSC reader."""
def __init__(self, reader):
"""Construct a new PCSC card connection.
reader: the reader in which the smartcard to connect to is located.
"""
CardConnection.__init__(self, reader)
self.hcard = None
hresult, self.hcontext = SCardEstablishContext(SCARD_SCOPE_USER)
if hresult != 0:
raise CardConnectionException(
'Failed to establish context : ' + \
SCardGetErrorMessage(hresult))
def __del__(self):
"""Destructor. Clean PCSC connection resources."""
# race condition: module CardConnection
# can disappear before __del__ is called
self.disconnect()
hresult = SCardReleaseContext(self.hcontext)
if hresult != 0:
raise CardConnectionException(
'Failed to release context: ' + \
SCardGetErrorMessage(hresult))
CardConnection.__del__(self)
def connect(self, protocol=None, mode=None, disposition=None):
"""Connect to the card.
If protocol is not specified, connect with the default
connection protocol.
If mode is not specified, connect with SCARD_SHARE_SHARED."""
CardConnection.connect(self, protocol)
pcscprotocol = translateprotocolmask(protocol)
if 0 == pcscprotocol:
pcscprotocol = self.getProtocol()
if mode == None:
mode = SCARD_SHARE_SHARED
# store the way to dispose the card
if disposition == None:
disposition = SCARD_UNPOWER_CARD
self.disposition = disposition
hresult, self.hcard, dwActiveProtocol = SCardConnect(
self.hcontext, str(self.reader), mode, pcscprotocol)
if hresult != 0:
self.hcard = None
if SCARD_W_REMOVED_CARD == hresult:
raise NoCardException(
'Unable to connect: ' + \
SCardGetErrorMessage(hresult))
else:
raise CardConnectionException(
'Unable to connect with protocol: ' + \
dictProtocol[pcscprotocol] + '. ' + \
SCardGetErrorMessage(hresult))
protocol = 0
for p in dictProtocol:
if p == dwActiveProtocol:
protocol = eval("CardConnection.%s_protocol" % dictProtocol[p])
PCSCCardConnection.setProtocol(self, protocol)
def disconnect(self):
"""Disconnect from the card."""
# when __del__() is invoked in response to a module being deleted,
# e.g., when execution of the program is done, other globals referenced
# by the __del__() method may already have been deleted.
# this causes CardConnection.disconnect to except with a TypeError
try:
CardConnection.disconnect(self)
except TypeError:
pass
if None != self.hcard:
hresult = SCardDisconnect(self.hcard, self.disposition)
if hresult != 0:
raise CardConnectionException(
'Failed to disconnect: ' + \
SCardGetErrorMessage(hresult))
self.hcard = None
def getATR(self):
"""Return card ATR"""
CardConnection.getATR(self)
if None == self.hcard:
raise CardConnectionException('Card not connected')
hresult, reader, state, protocol, atr = SCardStatus(self.hcard)
if hresult != 0:
raise CardConnectionException(
'Failed to get status: ' + \
SCardGetErrorMessage(hresult))
return atr
def doTransmit(self, bytes, protocol=None):
"""Transmit an apdu to the card and return response apdu.
bytes: command apdu to transmit (list of bytes)
protocol: the transmission protocol, from CardConnection.T0_protocol,
CardConnection.T1_protocol,
or CardConnection.RAW_protocol
return: a tuple (response, sw1, sw2) where
sw1 is status word 1, e.g. 0x90
sw2 is status word 2, e.g. 0x1A
response are the response bytes excluding status words
"""
if None == protocol:
protocol = self.getProtocol()
CardConnection.doTransmit(self, bytes, protocol)
pcscprotocolheader = translateprotocolheader(protocol)
if 0 == pcscprotocolheader:
raise CardConnectionException(
'Invalid protocol in transmit: must be' + \
'CardConnection.T0_protocol, ' + \
'CardConnection.T1_protocol, or ' + \
'CardConnection.RAW_protocol')
if None == self.hcard:
raise CardConnectionException('Card not connected')
hresult, response = SCardTransmit(
self.hcard, pcscprotocolheader, bytes)
if hresult != 0:
raise CardConnectionException(
'Failed to transmit with protocol ' + \
dictProtocolHeader[pcscprotocolheader] + '. ' + \
SCardGetErrorMessage(hresult))
sw1 = (response[-2] + 256) % 256
sw2 = (response[-1] + 256) % 256
data = map(lambda x: (x + 256) % 256, response[:-2])
return data, sw1, sw2
def doControl(self, controlCode, bytes=[]):
"""Transmit a control command to the reader and return response.
controlCode: control command
bytes: command data to transmit (list of bytes)
return: response are the response bytes (if any)
"""
CardConnection.doControl(self, controlCode, bytes)
hresult, response = SCardControl(self.hcard, controlCode, bytes)
if hresult != 0:
raise SmartcardException(
'Failed to control ' + SCardGetErrorMessage(hresult))
data = map(lambda x: (x + 256) % 256, response)
return data
def doGetAttrib(self, attribId):
"""get an attribute
attribId: Identifier for the attribute to get
return: response are the attribute byte array
"""
CardConnection.doGetAttrib(self, attribId)
hresult, response = SCardGetAttrib(self.hcard, attribId)
if hresult != 0:
raise SmartcardException(
'Failed to getAttrib ' + SCardGetErrorMessage(hresult))
return response
if __name__ == '__main__':
"""Small sample illustrating the use of CardConnection."""
SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02]
DF_TELECOM = [0x7F, 0x10]
from smartcard.pcsc.PCSCReader import readers
cc = readers()[0].createConnection()
cc.connect()
print "%r %x %x" % cc.transmit(SELECT + DF_TELECOM)
print cc.control(0, [])
|