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:
hploetz 2007-05-30 16:47:43 +00:00
parent 758223149b
commit 10a9dab1ef
2 changed files with 43 additions and 19 deletions

View File

@ -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):

View File

@ -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,