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