Allow SELECT APPLICATION and READ BINARY with given Le
Add resolve_symbolic_name convenience function Add get_atr function Implement STOP_ATRS functionality to stop ISO_7816_4_Card from accepting all cards, blacklist contactless storage cards git-svn-id: svn+ssh://localhost/home/henryk/svn/cyberflex-shell/trunk@192 f711b948-2313-0410-aaa9-d29f33439f0b
This commit is contained in:
parent
758223149b
commit
10a9dab1ef
|
@ -35,6 +35,9 @@ class Card:
|
|||
## string and mask a binary mask. Alternatively mask may be None, then ATR must be a regex
|
||||
## to match on the ATRs hexlify representation
|
||||
ATRS = []
|
||||
## Note: A list of _not_ supported ATRs, overriding any possible match in ATRS. Matching
|
||||
## is done as for ATRS.
|
||||
STOP_ATRS = []
|
||||
## Note: a key in this dictionary may either be a two-byte string containing
|
||||
## a binary status word, or a four-byte string containing a hexadecimal
|
||||
## status word, possibly with ? characters marking variable nibbles.
|
||||
|
@ -243,19 +246,28 @@ class Card:
|
|||
if purpose is None: purpose = Card.PURPOSE_SUCCESS
|
||||
return self.match_statusword(self.STATUS_MAP[purpose], sw)
|
||||
|
||||
def get_atr(self):
|
||||
return self.card.status().get("ATR","")
|
||||
|
||||
def can_handle(cls, card):
|
||||
"""Determine whether this class can handle a given pycsc object."""
|
||||
ATR = card.status().get("ATR","")
|
||||
for (knownatr, mask) in cls.ATRS:
|
||||
if mask is None:
|
||||
if sre.match(knownatr, binascii.hexlify(ATR), sre.I):
|
||||
return True
|
||||
else:
|
||||
if len(knownatr) != len(ATR):
|
||||
continue
|
||||
if crypto_utils.andstring(knownatr, mask) == crypto_utils.andstring(ATR, mask):
|
||||
return True
|
||||
def match_list(atr, list):
|
||||
for (knownatr, mask) in list:
|
||||
if mask is None:
|
||||
if sre.match(knownatr, binascii.hexlify(atr), sre.I):
|
||||
return True
|
||||
else:
|
||||
if len(knownatr) != len(atr):
|
||||
continue
|
||||
if crypto_utils.andstring(knownatr, mask) == crypto_utils.andstring(atr, mask):
|
||||
return True
|
||||
return False
|
||||
|
||||
if not match_list(ATR, cls.STOP_ATRS) and match_list(ATR, cls.ATRS):
|
||||
return True
|
||||
return False
|
||||
|
||||
can_handle = classmethod(can_handle)
|
||||
|
||||
def get_prompt(self):
|
||||
|
|
|
@ -120,26 +120,33 @@ class ISO_7816_4_Card(Card):
|
|||
print utils.hexdump(result.data)
|
||||
print TLV_utils.decode(result.data,tags=self.TLV_OBJECTS)
|
||||
|
||||
def select_application(self, aid):
|
||||
def select_application(self, aid, le=0):
|
||||
result = self.send_apdu(
|
||||
C_APDU(self.APDU_SELECT_APPLICATION,
|
||||
data = aid, le = 0) ) ## FIXME With or without le
|
||||
data = aid, le = le) ) ## FIXME With or without le
|
||||
if self.check_sw(result.sw):
|
||||
Application.load_applications(self, aid)
|
||||
return result
|
||||
|
||||
def resolve_symbolic_aid(self, symbolic_name):
|
||||
"Returns symbolic_name, or if symbolic_name is a known symbolic_name then its corresponding aid."
|
||||
s = [a for a,b in self.APPLICATIONS.items()
|
||||
if (b[0] is not None and b[0].lower() == symbolic_name.lower())
|
||||
or (len(b) > 2 and symbolic_name.lower() in [c.lower() for c in b[2].get("alias", [])])
|
||||
]
|
||||
if len(s) > 0:
|
||||
aid = s[0]
|
||||
else:
|
||||
aid = binascii.a2b_hex("".join(symbolic_name.split()))
|
||||
|
||||
return aid
|
||||
|
||||
def cmd_selectapplication(self, application):
|
||||
"""Select an application on the card.
|
||||
application can be given either as hexadecimal aid or by symbolic name (if known)."""
|
||||
|
||||
s = [a for a,b in self.APPLICATIONS.items()
|
||||
if (b[0] is not None and b[0].lower() == application.lower())
|
||||
or (len(b) > 2 and application.lower() in [c.lower() for c in b[2].get("alias", [])])
|
||||
]
|
||||
if len(s) > 0:
|
||||
aid = s[0]
|
||||
else:
|
||||
aid = binascii.a2b_hex("".join(application.split()))
|
||||
aid = self.resolve_symbolic_aid(application)
|
||||
|
||||
result = self.select_application(aid)
|
||||
if len(result.data) > 0:
|
||||
print utils.hexdump(result.data)
|
||||
|
@ -150,6 +157,11 @@ class ISO_7816_4_Card(Card):
|
|||
(".*", None), ## For now we accept any card
|
||||
] )
|
||||
|
||||
STOP_ATRS = list(Card.STOP_ATRS)
|
||||
STOP_ATRS.extend( [
|
||||
("3b8f8001804f0ca000000306......00000000..", None) # Contactless storage cards (PC/SC spec part 3 section 3.1.3.2.3
|
||||
] )
|
||||
|
||||
COMMANDS = dict(Card.COMMANDS)
|
||||
COMMANDS.update( {
|
||||
"select_application": cmd_selectapplication,
|
||||
|
|
Loading…
Reference in New Issue