Skip to content
This repository was archived by the owner on Mar 27, 2026. It is now read-only.

Commit 2c0c59c

Browse files
committed
Add support for selecting apps using the old static AID method.
Ref #15
1 parent 53c8366 commit 2c0c59c

1 file changed

Lines changed: 42 additions & 2 deletions

File tree

emv/card.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,50 @@ def get_mf(self):
2525
""" Get the master file (MF). """
2626
return self.tp.exchange(SelectCommand(file_identifier=[0x3F, 0x00]))
2727

28+
def get_pse(self):
29+
""" Get the Payment System Environment (PSE) file """
30+
return self.tp.exchange(SelectCommand("1PAY.SYS.DDF01"))
31+
2832
def list_applications(self):
2933
""" List applications on the card """
30-
res = self.tp.exchange(SelectCommand("1PAY.SYS.DDF01"))
31-
sfi = res.data[Tag.FCI][Tag.FCI_PROP][Tag.SFI][0]
34+
try:
35+
return self._list_applications_sfi()
36+
except ErrorResponse:
37+
return self._list_applications_static_aid()
38+
39+
def _list_applications_static_aid(self):
40+
""" Try to find applications by trying to select a static application ID.
41+
This is an older method of app discovery which is still used by some cards.
42+
"""
43+
STATIC_AIDS = [
44+
[0xA0, 0x00, 0x00, 0x00, 0x25, 0x01], # Amex
45+
[0xA0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10], # Visa
46+
[0xA0, 0x00, 0x00, 0x00, 0x04, 0x10, 0x10], # Mastercard
47+
]
48+
apps = []
49+
for aid in STATIC_AIDS:
50+
try:
51+
res = self.tp.exchange(SelectCommand(aid))
52+
53+
# This is a bit of a hack, we transform this response into something which looks
54+
# like the result from the SFI method, so that callers of list_applications get a
55+
# consistent result.
56+
apps.append(TLV({
57+
Tag.ADF_NAME: res.data[Tag.FCI][Tag.DF],
58+
Tag.APP_LABEL: res.data[Tag.FCI][Tag.FCI_PROP][Tag.APP_LABEL]
59+
}))
60+
except ErrorResponse:
61+
continue
62+
return apps
63+
64+
def _list_applications_sfi(self):
65+
""" List applications on the card using the SFI method.
66+
67+
This fetches the SFI (short file identifier) from the PSE (Payment System Environment)
68+
file, and uses it to locate all the apps on the card.
69+
"""
70+
pse = self.get_pse()
71+
sfi = pse.data[Tag.FCI][Tag.FCI_PROP][Tag.SFI][0]
3272
apps = []
3373

3474
# Apps may be stored in different records, so iterate through records

0 commit comments

Comments
 (0)