@@ -57,7 +57,7 @@ class ISO7816(object):
5757    standard file tags available in "file_tags" class attribute dictionnary 
5858    """ 
5959
60-     dbg  =  0 
60+     dbg  =  1 
6161
6262    INS_dic  =  {
6363        0x04  : 'DEACTIVATE FILE' ,
@@ -193,7 +193,7 @@ def ATR_scan(self, smlist_file="/usr/share/pcsc/smartcard_list.txt"):
193193                  %  toHexString (ATR (self .ATR ).getHistoricalBytes ()))
194194            ATRcs  =  ATR (self .ATR ).getChecksum ()
195195            if  ATRcs  :
196-                 print ('checksum: 0x%X '  %  ATRcs )
196+                 print ('checksum: 0x%.2X '  %  ATRcs )
197197            else :
198198                print ('no ATR checksum' )
199199            print ('\n using pcsc_scan ATR list file: %s'  %  smlist_file )
@@ -712,16 +712,16 @@ def parse_file(self, Data=[]):
712712        parse_file(self, Data) -> Dict() 
713713         
714714        parses a list of bytes returned when selecting a file 
715-         interprets the content of some informative bytes  
716-         for file structure and parsing  method... 
715+         interprets the content of some informative bytes for file structure and   
716+         decoding  method... 
717717        """ 
718718        ber  =  BERTLV_parser ( Data  )
719719        if  self .dbg  >=  2 :
720-             log (3 , '(parse_file) BER structure:\n %s '  %  ber )
721-         if  len (ber ) >  1   and   self . dbg :
720+             log (3 , '(parse_file) BER structure:\n %r '  %  ber )
721+         if  self . dbg   and   len (ber ) >  1 :
722722            # TODO: implements recursive BER object parsing 
723-             log (1 , '(parse_file) contain more than 1 BER object: ' \
724-                 '%s \n not implemented'   %  ber )
723+             log (2 , '(parse_file) contain more than 1 BER object: %r : not implemented ' \
724+                      %  ber )
725725
726726        # for FCP control structure, precise parsing is done 
727727        # this structure seems to be the most used for (U)SIM cards 
@@ -741,14 +741,12 @@ def parse_file(self, Data=[]):
741741        fil  =  {}
742742        if  ber [0 ][0 ][2 ] ==  0x4 : 
743743            fil ['Control' ] =  'FMD' 
744-             if  self .dbg :
745-                 log (1 , '(parse_file) FMD file structure parsing ' \
746-                     'not implemented' )
744+             if  self .dbg  >=  2 :
745+                 log (2 , '(parse_file) FMD file structure parsing not implemented' )
747746        elif  ber [0 ][0 ][2 ] ==  0xF :
748747            fil ['Control' ] =  'FCI' 
749-             if  self .dbg :
750-                 log (1 , '(parse_file) FCI 0xF file structure parsing ' \
751-                     'not implemented' )
748+             if  self .dbg  >=  2 :
749+                 log (2 , '(parse_file) FCI 0xF file structure parsing not implemented' )
752750        else : 
753751            fil ['Control' ] =  ber [0 ][0 ]
754752            if  self .dbg :
@@ -762,8 +760,8 @@ def parse_FCP(self, Data=[]):
762760        parse_FCP(Data) -> Dict() 
763761         
764762        parses a list of bytes returned when selecting a file 
765-         interprets the content of some informative bytes  
766-         for file structure and parsing  method... 
763+         interprets the content of some informative bytes for file structure and   
764+         decoding  method... 
767765        """ 
768766        fil  =  {}
769767        # loop on the Data bytes to parse TLV'style attributes 
@@ -799,7 +797,7 @@ def parse_FCP(self, Data=[]):
799797                fil [self .file_tags [T ]] =  V  
800798                if  self .dbg  >=  2 :
801799                    log (3 , '(parse_FCP) parse_security_attribute not implemented ' \
802-                            'for tag 0x%X '  %  T )
800+                            'for tag 0x%.2X '  %  T )
803801                self .parse_security_attribute (V , fil )
804802            # file size or length 
805803            elif  T  in  (0x80 , 0x81 ):
@@ -1097,7 +1095,7 @@ def parse_FCI(self, Data=[]):
10971095                fil [self .file_tags [T ]] =  V  
10981096                if  self .dbg  >=  2 :
10991097                    log (3 , '(parse_FCI) parse_security_attribute not implemented ' \
1100-                            'for tag 0x%X '  %  T )
1098+                            'for tag 0x%.2X '  %  T )
11011099                self .parse_security_attribute (V , fil )
11021100            # file size or length 
11031101            elif  T  in  (0x80 , 0x81 ):
@@ -1578,7 +1576,7 @@ def __init__(self, reader=''):
15781576        initialized on the MF 
15791577        """ 
15801578        ISO7816 .__init__ (self , CLA = 0x00 , reader = reader )
1581-         self .AID  =  []
1579+         self .AID      =  []
15821580        self .AID_GP  =  {}
15831581        # 
15841582        if  self .dbg  >=  2 :
@@ -1658,15 +1656,16 @@ def parse_pin_status(Data, fil):
16581656        fil ['PIN Status' ] =  PIN_status 
16591657        return  fil 
16601658
1661-     def  get_AID (self ):
1659+     def  get_AID (self ,  backtoMF = False ):
16621660        """ 
16631661        checks EF_DIR at the MF level,  
16641662        and available AID (Application ID) referenced 
16651663         
16661664        puts it into self.AID 
16671665        """ 
1668-         #go back to MF and select EF_DIR 
1669-         #self.select(addr=[]) 
1666+         # go back to MF and select EF_DIR 
1667+         if  backtoMF :
1668+             self .select (addr = [])
16701669
16711670        # EF_DIR is at the MF level and contains Application ID: 
16721671        EF_DIR  =  self .select ([0x2F , 0x00 ], type = 'pmf' )
@@ -1681,9 +1680,20 @@ def get_AID(self):
16811680            if  (rec [0 ], rec [2 ]) ==  (0x61 , 0x4F ) and  len (rec ) >  6  \
16821681            and  rec [4 :4 + rec [3 ]] not  in   self .AID :
16831682                self .AID .append ( rec [4 :4 + rec [3 ]] )
1683+     
1684+     def  get_AID_GP (self ):
1685+         """ 
1686+         tries to select all AID addresses from AID_GP_app_code at the MF level 
16841687         
1685-         #for aid in self.AID: 
1686-         #    self.interpret_AID(aid) 
1688+         puts those to which there is a positive SW response into self.AID_GP 
1689+         """ 
1690+         for  aid  in  self .AID_GP_code .keys ():
1691+             aid  =  list (aid )
1692+             self .select_by_name (aid )
1693+             if  self .coms ()[2 ] ==  (0x90 , 0x00 ):
1694+                 # positive response, where we could read the data returned by 
1695+                 # the application 
1696+                 self .AID_GP [tuple (aid )] =  BERTLV_extract (self .coms ()[3 ])
16871697
16881698    @staticmethod  
16891699    def  interpret_AID (aid = []):
@@ -1692,47 +1702,58 @@ def interpret_AID(aid=[]):
16921702        """ 
16931703        if  len (aid ) <  11 :
16941704            return 
1695-         # check AID format 
1696-         aid_rid  =  tuple (aid [0 :5 ])
1697-         aid_app  =  tuple (aid [5 :7 ])
1698-         aid_country  =  tuple (aid [7 :9 ])
1699-         aid_provider  =  tuple (aid [9 :11 ])
1705+         aid  =  tuple (aid )
1706+         aid_rid , aid_app , aid_country  =  aid [0 :5 ], aid [5 :7 ], aid [7 :9 ]
1707+         aid  =  {
1708+             'rid'  : '%.2X %.2X %.2X %.2X %.2X'  %  aid_rid ,
1709+             'app'  : '%.2X %.2X'  %  aid_app ,
1710+             'country'  : '%.2X %.2X'  %  aid_country ,
1711+             'provider'  : '%.2X %.2X'  %  aid [9 :11 ],
1712+             'prop'  : ('%.2X '  *  len (aid [11 :])) %  aid [11 :]
1713+             }
17001714
1701-         # get AID application code, depending on SDO... 
1715+         # check for known AID format 
1716+         if  aid_rid  in  UICC .AID_RID .keys ():
1717+             aid ['rid' ] +=  ' (%s)'  %  UICC .AID_RID [aid_rid ]
17021718        if  aid_rid  ==  (0xA0 , 0x00 , 0x00 , 0x00 , 0x09 ) \
17031719        and  aid_app  in  UICC .AID_ETSI_app_code .keys (): 
1704-             aid_app   =  UICC .AID_ETSI_app_code [aid_app ]
1705-         if  aid_rid  ==  (0xA0 , 0x00 , 0x00 , 0x00 , 0x87 ) \
1720+             aid [ 'app' ]  +=   ' (%s)'   %  UICC .AID_ETSI_app_code [aid_app ]
1721+         elif  aid_rid  ==  (0xA0 , 0x00 , 0x00 , 0x00 , 0x87 ) \
17061722        and  aid_app  in  UICC .AID_3GPP_app_code .keys (): 
1707-             aid_app   =  UICC .AID_3GPP_app_code [aid_app ]
1708-         if  aid_rid  ==  (0xA0 , 0x00 , 0x00 , 0x03 , 0x43 ) \
1723+             aid [ 'app' ]  +=   ' (%s)'   %  UICC .AID_3GPP_app_code [aid_app ]
1724+         elif  aid_rid  ==  (0xA0 , 0x00 , 0x00 , 0x03 , 0x43 ) \
17091725        and  aid_app  in  UICC .AID_3GPP2_app_code .keys (): 
1710-             aid_app   =  UICC .AID_3GPP2_app_code [aid_app ]
1711-         if  aid_rid  ==  (0xA0 , 0x00 , 0x00 , 0x06 , 0x45 ) \
1726+             aid [ 'app' ]  +=   ' (%s)'   %  UICC .AID_3GPP2_app_code [aid_app ]
1727+         elif  aid_rid  ==  (0xA0 , 0x00 , 0x00 , 0x06 , 0x45 ) \
17121728        and  aid_app  in  UICC .AID_OneM2M_app_code .keys ():
1713-             aid_app  =  UICC .AID_OneM2M_app_code [aid_app ]
1714-         # get AID responsible SDO and country 
1715-         if  aid_rid  in  UICC .AID_RID .keys ():
1716-             aid_rid  =  UICC .AID_RID [aid_rid ]
1729+             aid ['app' ] +=  ' (%s)'  %  UICC .AID_OneM2M_app_code [aid_app ]
17171730        if  aid_country  in  UICC .AID_country_code .keys (): 
17181731            aid_country  =  UICC .AID_country_code [aid_country ]
1719-         
1720-         return ( '%s || % s || % s || % s || %s'   \
1721-             %  ( aid_rid ,  aid_app ,  aid_country ,  aid_provider ,  tuple ( aid [ 11 :]))) 
1732+         # 
1733+         return   'rid %(rid) s || app %(app) s || country %(country) s || '  \
1734+                 'provider %(provider)s || %(prop)s'   %   aid 
17221735
1723-     def  get_AID_GP (self ):
1736+     @staticmethod  
1737+     def  interpret_AID_GP (aid = []):
17241738        """ 
1725-         tries to select all AID addresses from AID_GP_app_code at the MF level 
1726-          
1727-         puts those to which there is a positive SW response into self.AID_GP 
1739+         returns a string with the interpretation of the GlobalPlatform AID provided 
17281740        """ 
1729-         for  aid  in  self .AID_GP_code .keys ():
1730-             aid  =  list (aid )
1731-             self .select_by_name (aid )
1732-             if  self .coms ()[2 ] ==  (0x90 , 0x00 ):
1733-                 # positive response, where we could read the data returned by 
1734-                 # the application 
1735-                 self .AID_GP [tuple (aid )] =  BERTLV_extract (self .coms ()[3 ])
1741+         for  code , interp  in  UICC .AID_GP_code .items ():
1742+             if  code  ==  aid [:len (code )]:
1743+                 if  len (aid ) >  len (code ):
1744+                     fstr  =  'GP || '  +  '%.2X '  *  len (code ) +  '('  +  interp  +  ')'  +  ' || '  +  '%.2X '  *  (len (aid )- len (code ))
1745+                     return  fstr  %  tuple (code  +  aid [len (code ):])
1746+                 else :
1747+                     fstr  =  'GP || '  +  '%.2X '  *  len (code ) +  '('  +  interp  +  ')' 
1748+                     return  fstr  %  code 
1749+     
1750+     def  print_AID (self ):
1751+         self .get_AID ()
1752+         for  aid  in  self .AID :
1753+             print (self .interpret_AID (aid ))
1754+         self .get_AID_GP ()
1755+         for  aid  in  self .AID_GP :
1756+             print (self .interpret_AID_GP (aid ))
17361757
17371758    def  get_ICCID (self ):
17381759        """ 
0 commit comments