jdZddlmZmZmZmZmZmZmZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlmZmZddlmZddlmZmZmZmZmZmZmZmZddlmZddlm Z m!Z!m"Z"dd l#m$Z$m%Z%dd l&m'Z'dd l(m)Z)dd l*m+Z+dd l,m-Z-ee.ee.ee.dffZ/ee.ee.fZ0e-j1e2Z3GddZ4Gdde4Z5Gdde5Z6Gdde5Z7GddZ8Gdde4Z9Gdde9Z:Gdde9Z;Gdd e;Z<Gd!d"e:Z=Gd#d$e9Z>d%e?d&e@fd'ZAGd(d)ZBGd*d+e jCZDGd,d-ZEdS).aRepresentation of the ISO7816-4 filesystem model. The File (and its derived classes) represent the structure / hierarchy of the ISO7816-4 smart card file system with the MF, DF, EF and ADF entries, further sub-divided into the EF sub-types Transparent, Linear Fixed, etc. The classes are intended to represent the *specification* of the filesystem, not the actual contents / runtime state of interacting with a given smart card. )castOptionalIterableListDictTupleUnionN) CommandSetwith_default_category)toBytes)h2bb2his_hexauto_int auto_uint8 auto_uint16 is_hexstr JsonEncoder)bertlv_parse_one) filter_dictparse_constructbuild_construct)sw_match decomposeATR)js_path_modify)SimCardCommands) SwMatchError) PySimLogger.ceZdZdZgdZdgZ d'dedededed ed d ed d eefdZ dZ de deefdZ d(de defdZ d(de deefdZdedfdZdddeedfdZdedfdZdgfdedeedffdZdgfdeedeedffdZgfdeedffdZgfdeefdZd efd!Zd"Zd#eefd$Zed%e fd&ZdS))CardFilezBase class for all objects in the smart card filesystem. Serve as a common ancestor to all other file types; rarely used directly. ).../MF3f00NfidsfidnamedescparentCardDFprofile CardProfileservicecTt|ts|td|r|}||_||_||_||_||_|jr,|j|kr!|jr|j |||_ ||_ g|_ dS)a Args: fid : File Identifier (4 hex digits) sfid : Short File Identifier (2 hex digits, optional) name : Brief name of the file, like EF_ICCID desc : Description of the file parent : Parent CardFile object within filesystem hierarchy profile : Card profile that this file should be part of service : Service (SST/UST/IST) associated with the file Nzfid is mandatory) isinstanceCardADF ValueErrorlowerr&r'r(r)r*add_filer,r.shell_commands)selfr&r'r(r)r*r,r.s F/home/jenkins/jenkins/workspace/simtester-sanitize/pySim/filesystem.py__init__zCardFile.__init__As$(( 1S[/00 0  ))++C    ; '4;$..48. K  & & &   c,|jr|jS|jSNr(r&r6s r7__str__zCardFile.__str__as 9 9 8Or9 prefer_namereturnc0|r|jr|jS|jSr;r<r6r?s r7 _path_elementzCardFile._path_elementgs"  49 9 8Or9TcRd||S)zReturn fully qualified path to file as string. Args: prefer_name : Preferably build path of names; fall-back to FIDs as required r#)joinfully_qualified_pathrBs r7fully_qualified_path_strz!CardFile.fully_qualified_path_strms$ xx11+>>???r9c|jr&|j|kr|j|}ng}||}|r|||S)zReturn fully qualified path to file as list of FID or name strings. Args: prefer_name : Preferably build path of names; fall-back to FIDs as required )r*rFrCappend)r6r?retelems r7rFzCardFile.fully_qualified_pathush ; 4;$..+22;??CCC!!+..   JJt    r9c|jr%|j|kr|j}ng}|r|||S)zLReturn fully qualified path to file as list of CardFile instance references.)r*fully_qualified_path_fobjrI)r6rJs r7rMz"CardFile.fully_qualified_path_fobjsQ ; 4;$..+7799CCC   JJt    r9targetcd}||kr|gS|}|}g}||D]}||t dt |dz D]L}||}||kr<||dzdD]} || ||ddccSMdS)zTBuild the relative sequence of files we need to traverse to get from us to 'target'.cttdt|D])}t||tr ||dcS*|S)Nr)reversedrangelenr0r1) inter_pathis r7 clip_pathz0CardFile.build_select_path_to..clip_paths^eAs:7788 * *jmW55*%abb>)))* r9rN)get_mfrMreverserIrRrS) r6rNrV cur_fqpath target_fqpathrTcerUtete2s r7build_select_path_tozCardFile.build_select_path_tos*     V]]__ $ $8O3355 88::   5 5B   b ! ! !1c-00233 5 5"1%88,QqSTT2//"))#....$9Z^4444444  5tr9CardMFc|jdS|}|jr$|j|kr|j}|jr |j|ktt|S)z(Return the MF (root) of the file system.N)r*rr`)r6nodes r7rXzCardFile.get_mfsY ; 4k dkT11;Dk dkT11FD!!!r9aliasci}|r|||i|jr&|gksd|vr||j|i|jr&|gksd|vr||j|i|S)amReturn a dict of {'identifier': self} tuples. Args: alias : Add an alias with given name to 'self' flags : Specify which selectables to return 'FIDS' and/or 'NAMES'; If not specified, all selectables will be returned. Returns: dict containing reference to 'self' for all identifiers. FIDSFNAMES)updater&r(r6rcflagsselss r7_get_self_selectableszCardFile._get_self_selectabless  ' KK & & & 8 *"% KK4( ) ) ) 9 +%2++U):): KKD) * * * r9ci}|jr |j|kr|S|r|||ji|jjr0|gksd|vr&||jj|ji|jjr0|gksd|vr&||jj|ji||jd||S)Nrerf)r*rgr&r(_get_parent_selectablesrhs r7rmz CardFile._get_parent_selectabless{ dkT11K  . KK , - - - ;? 8 v KK$+6 7 7 7 ;  9"E0A0A KK)4;7 8 8 8 DK77eDDEEE r9ci}|gksd|vr|d|}|gksd|vr)||d||gksd|vrh|}|rR|||||||S)aReturn a dict of {'identifier': File} that is selectable from the current file. Args: flags : Specify which selectables to return 'FIDS' and/or 'NAMES'; If not specified, all selectables will be returned. Returns: dict containing all selectable items. Key is identifier (string), value a reference to a CardFile (or derived class) instance. SELFr"PARENTr!r$)ri)rkrgrmrXget_app_selectables)r6rirjmfs r7get_selectableszCardFile.get_selectabless B;;&E//--c599D B;;(e++ KK44T5AA B B B B;;$%--B A B4454AABBB B222??@@@ r9c||}t|}||S)aAReturn a dict of {'identifier': File} that is selectable from the current file. Args: flags : Specify which selectables to return 'FIDS' and/or 'NAMES'; If not specified, all selectables will be returned. Returns: list containing all selectable names. )rslistkeyssort)r6rirjsel_keyss r7get_selectable_nameszCardFile.get_selectable_namess>##E** $$ r9data_hexcH|jr|j|SdS)zxDecode the response to a SELECT command. Args: data_hex: Hex string of the select response N)r*decode_select_response)r6rzs r7r|zCardFile.decode_select_responses1 ; @;55h?? ? @ @r9cb|jr|jS|jr|jSdS)zGet the profile associated with this file. If this file does not have any profile assigned, try to find a file above (usually the MF) in the filesystem hierarchy that has a profile assigned N)r,r* get_profiler=s r7r~zCardFile.get_profiles; < <  ; -;**,, ,tr9servicesc,|jdSt|jtr |j|vSt|jtr|jD] }||vrdS dSt|jtr|jD] }||vrdS dSt d)z[Assuming the provided list of activated services, should this file exist and be activated?.NTFz0self.service must be either int or list or tuple)r.r0intrutupler2)r6rss r7should_exist_for_servicesz"CardFile.should_exist_for_servicess < 4 dlC ( ( ,<8+ + dlD ) ) \  ==44!5 dlE * * \ ! !H}} 55%4KLLLr9as_jsonc0dt|jzS)a Export file contents in the form of commandline script. This method is meant to be overloaded by a subclass in case any exportable contents are present. The generated script may contain multiple command lines separated by line breaks ("\n"), where the last commandline shall have no line break at the end (e.g. "update_record 1 112233\nupdate_record 1 445566"). Naturally this export method will always refer to the currently selected file of the presented lchan. z# %s has no exportable contentsstr selected_filerlchans r7exportzCardFile.export2s13u7J3K3KKKr9)NNNNNNN)T)__name__ __module__ __qualname____doc__RESERVED_NAMES RESERVED_FIDSrrCardFileServicer8r>boolrCrGrrFrMr_rXrrkrmrsryr|r~rr staticmethodrr9r7r r :s,++NHMX\W[6:!!C!c!!RU!!(+!=Em=T!"?3!!!!@ (3- @@D@C@@@@   S    4 +;:(4 CS:T<"*""""26R3DjDY&>B  Xc] PTUXZdUdPe    %'4Z+@2*,  S     @s @ @ @ @   M$s)MMMM*LLLL\LLLr9r c&eZdZdZedGddeZfdZfdZdZ dZ dd e d e fd Z dd ee d e fdZgfdeffd Zdeedee fdZdeedee fdZdedee fdZxZS)r+zWDF (Dedicated File) in the smart card filesystem. Those are basically sub-directories.zDF/ADF CommandsceZdZdS)CardDF.ShellCommandsN)rrrrr9r7 ShellCommandsrAs r9rc t|tsd|vrtdtjdi|i|_|g|_i|_dS)Nr&zfid is mandatory for all DFr) r0r1 TypeErrorsuperr8childrenrr5files_by_servicer6kwargs __class__s r7r8zCardDF.__init__Esx$(( ?F"" =>>>""6""" #11334 "r9cJdtzS)NzDF(%s)rr>r6rs r7r>zCardDF.__str__O577??,,--r9c|jsdSt|jtr5|j|jg|dSt|jt r:|jD]0}|j|g|1dSt|jtr:|jD]0}|j|g|1dSt)z;Add a child (DF/EF) to the files_by_services of the parent.N) r.r0rr setdefaultrIrurr2)r6childr.s r7_add_file_serviceszCardDF._add_file_servicesRs}  F emS ) )   ! , ,U]B ? ? F Fu M M M M M  t , ,  = L L%00"==DDUKKKK L L  u - -  = L L%00"==DDUKKKK L L r9c|jrdS|jD].}t|tr|rdS/dS)NT)r.rvaluesr0r+ _has_service)r6cs r7rzCardDF._has_serviceasd < 4%%''  A!V$$ >>## 44  r9Frignore_existingc:t|tstdt|jddst d|jz|jtjvrt d|jz|jtjvrt d|jz|j|j vr|rdSt d|jd || |j rt d |j d || |jr|rdSt d |jd |||j |j<||_ ||t|tr|j D]}||t|trT|j D]:}t|tr#|rt d ;dSdS) zAdd a child (DF/EF) to this DF. Args: child: The new DF/EF to be added ignore_existing: Ignore, if file with given FID already exists. Old one will be kept. zExpected a File instance)minlenmaxlenzFile name %s is not a valid fidzFile name %s is a reserved namezFile fid %s is a reserved fidNzFile with given fid z already exists in zFile with given sfid zFile with given name z1TODO: implement recursive service -> file mapping)r0r rrr&r2r(rrrlookup_file_by_sfidr'lookup_file_by_namer*rr+rr)r6rrrgcs r7r4zCardDF.add_fileisa %** 8677 7ei!444 N>%)LMM M :0 0 0>%*MNN N 9. . .< JKK K 9 % % *AFDDQSS S  # #EJ / / U*BG***ddSUU U  # #EJ / / U *BG***ddSUU U#( ei   &&& eV $ $ f^**,, f f''***a((fj//11ff%b&11f!00f&01d&e&e e f f f fr9rc<|D]}|||dS)zAdd a list of child (DF/EF) to this DF Args: children: List of new DF/EFs to be added ignore_existing: Ignore, if file[s] with given FID already exists. Old one[s] will be kept. N)r4)r6rrrs r7 add_fileszCardDF.add_filess4 2 2E MM% 1 1 1 1 2 2r9r@cJt|}|gksd|vr6|d|jD|gksd|vr6|d|jD|S)Return a dict of {'identifier': File} that is selectable from the current DF. Args: flags : Specify which selectables to return 'FIDS' and/or 'NAMES'; If not specified, all selectables will be returned. Returns: dict containing all selectable items. Key is identifier (string), value a reference to a CardFile (or derived class) instance. rec,i|]}|j |j|Srr&.0xs r7 z*CardDF.get_selectables..s#KKKaQUKKKKr9rfc,i|]}|j |j|Srr(rs r7rz*CardDF.get_selectables..s#MMMqafMMMMr9)rrsrgrrr6rirjrs r7rszCardDF.get_selectablessww&&u-- B;;&E// KKKK4=+?+?+A+AKKK L L L B;;(e++ KKMMDM,@,@,B,BMMM N N N r9r(cr|dS|jD]}|jr|j|kr|cSdS)z.Find a file with given name within current DF.N)rrr()r6r(rUs r7rzCardDF.lookup_file_by_namesL <4%%''  Av !&D..tr9r'c|dS|jD]+}|jtt |kr|cS,dS)z7Find a file with given short file ID within current DF.N)rrr'rr)r6r'rUs r7rzCardDF.lookup_file_by_sfidsU <4%%''  AvSYY''(tr9r&c2||jvr |j|SdS)z1Find a file with given file ID within current DF.N)r)r6r&s r7lookup_file_by_fidzCardDF.lookup_file_by_fids! $-  =% %tr9F)rrrrr r rr8r>rrr rr4rrdictrsrrrrr __classcell__rs@r7r+r+>saa,--       .- #####.....      &f&fh&f&f&f&f&fP22(8"42t2222%'4$ (8:L (8:Lchx.@r9r+cveZdZdZfdZdZd dZdZgfdeffd Z gfdefd Z d e e de fd ZxZS)r`z-MF (Master File) in the smart card filesystemc |dd|dd|dd||d<tjdi|i|_dS) Nr&r%r(r$r)zMaster File (directory root)r*r)rrr8 applicationsrs r7r8zCardMF.__init__s{%(((&$'''&"@AAAx""6"""r9cd|jzS)NzMF(%s)rr=s r7r>zCardMF.__str__s48$$r9appr1ct|tstd|j|jvrt d|jz||j|j<||_dS)zAdd an Application to the MFzExpected an ADF instancezAID %s already existsN)r0r1raidrr2r*)r6rs r7add_application_dfzCardMF.add_application_dfsc#w'' 8677 7 7d' ' '4@AA A%(#'" r9cNt|jS)z#Get list of completions (AID names))rurrr=s r7 get_app_nameszCardMF.get_app_namessD%,,..///r9r@ct|}||||S)r)rrsrgrqrs r7rszCardMF.get_selectablessAww&&u-- D,,U33444 r9c i}|gksd|vr6|d|jD|gksd|vr6|d|jD|S)zGet applications by AID + nameAIDSci|] }|j| Sr)rrs r7rz.CardMF.get_app_selectables..sFFFaFFFr9ANAMESc,i|]}|j |j|Srrrs r7rz.CardMF.get_app_selectables..s#IIIq!&IIIIr9)rgrr)r6rirjs r7rqzCardMF.get_app_selectabless B;;&E// KKFF4+<+C+C+E+EFFF G G G B;;(e++ KKIID$5$<$<$>$>III K K K r9rzcd|s|S|}|r||S|S)a\Decode the response to a SELECT command. This is the fall-back method which automatically defers to the standard decoding method defined by the card profile. When no profile is set, then no decoding is performed. Specific derived classes (usually ADF) can overload this method to install specific decoding. )r~r|)r6rzr,s r7r|zCardMF.decode_select_responsesC O""$$  11(;; ;Or9)rr1)rrrrr8r>rrrrsrqrrobjectr|rrs@r7r`r`s77%%%000%'  4      )+tx}r9r`c\eZdZdZd dedeffd ZdZdefdZe d efd Z xZ S) r1z=ADF (Application Dedicated File) in the smart card filesystemFrhas_fsc tjdi|d|_||_||_|}|r||dSdS)Nr)rr8 applicationr3rrrXr)r6rrrrrrs r7r8zCardADF.__init__sw""6"""99;; [[]]  (  ! !$ ' ' ' ' ' ( (r9c2d|jr|jn|jzS)NzADF(%s)r(rr=s r7r>zCardADF.__str__s@DIIAAr9r?c0|jr |r|jS|jSr;rrBs r7rCzCardADF._path_elements" 9  9 8Or9rct|jtstd|jj||S)zb Export application specific parameters that are not part of the UICC filesystem. z.currently selected file is not of type CardADF)r0rr1rrrrs r7rzCardADF.export%sE %-w77 NLMM M".55guEEEr9r) rrrrrrr8r>rCrrrrs@r7r1r1sGG((C(((((((BBB FFFF\FFFFFr9r1cReZdZdZdZededefdZd dZde fdZ d Z dS) JsonEditoraContext manager for editing a JSON-encoded EF value in an external editor. Writes the current JSON value (plus encode/decode examples as //-comments) to a temporary file, opens the user's editor, then reads the result back (stripping comment lines) and returns it as the context variable:: with JsonEditor(self._cmd, orig_json, ef) as edited_json: if edited_json != orig_json: ...write back... c>||_||_||_d|_dSr;)_cmd _orig_json_ef_file)r6cmd orig_jsonefs r7r8zJsonEditor.__init__:s" # r9textr@cddd|DS)z5Strip //-comment lines from text before JSON parsing. c3hK|]-}|d)|V.dS)z//N)lstrip startswith)rlines r7 z-JsonEditor._strip_comments..Ds>bb$4;;==C[C[\`CaCabbbbbbbr9)rE splitlines)rs r7_strip_commentszJsonEditor._strip_comments@s/yybb$//*;*;bbbbbbr9Ncg}dD]<}tt|j|d}|r||=|sdS|j}|g}|jr0|d|jd|jr|d|j| dd |d| d |D]}t|d kr5|d |d |d } } }| d| d|dn)|d |d } }| d|dtj | dtD]} | d| ddS)a6Append encode/decode test vectors as //-comment lines to an open file. The examples are taken from _test_de_encode and _test_decode class attributes (same source as the auto-generated filesystem documentation). The comment block is intentionally ignored on read-back by _strip_comments.)_test_de_encode _test_decodeN()z- z //  rz// Examples (ignored on save): rrWz // record z: z // file: rindentclsz// )getattrtyperextendrGr&rIupperr)writerErSjsondumpsrr) r6 text_filevectorsattrvrpartstencoded record_nrdecodedrs r7_append_examples_as_commentsz'JsonEditor._append_examples_as_commentsFs 7 " "DTXd33A "q!!!  F X,,../ 6 0 LL.RV\\^^... / / / 7 ) LLbg ( ( (5#((5//555666:;;; 0 0A1vv{{./dAaD!A$G EY E E' E E EFFFF#$Q41 7G 7 7 7888 71+FFFQQSS 0 0d//// 0 0 0r9ctjdddd|_tj|j|jdt ||j|j |j |jj  t|jj d 5}tj ||cd d d S#1swxYwYnc#tj$rQ}|j d ||j d }|d vr |jcYd }~SYd }~nd }~wwxYw)a%Write JSON + examples to a temp file, run the editor, return parsed result. On JSONDecodeError the user is offered the option to re-open the file and fix the mistake interactively. The temp file is removed by __exit__() on success, or when the user declines to retry.pysim_z.jsonwF)prefixsuffixmodedeleterrTrNzInvalid JSON: z&Re-open file for editing? [y]es/[n]o: )yyes)tempfileNamedTemporaryFilerr dumprrrcloser run_editorr(openloadsrreadJSONDecodeErrorperror read_input)r6feanswers r7 __enter__zJsonEditor.__enter__ds 069%III  $/4:a[IIII ))$*555  + I  1 1 1 +$*/3//F1:d&:&:16688&D&DEEFFFFFFFFFFFFFFFFF' + + +   !5!!5!5666--.VWW--?******.---- + +sCD 89C>1 D >DD DD E*AE%E*%E*cBtj|jjdSr;)osunlinkrr()r6argss r7__exit__zJsonEditor.__exit__zs $*/"""""r9)r@N) rrrrr8rrrrrr.r3rr9r7rr/s   ccccccc\c 0000<+6++++,#####r9rc@eZdZdZfdZfdZgfdeffd ZxZS)CardEFz,EF (Entry File) in the smart card filesystemc D||d<tjdi|dS)Nr&rrr8)r6r&rrs r7r8zCardEF.__init__s/u ""6"""""r9cJdtzS)NzEF(%s)rrs r7r>zCardEF.__str__rr9r@cht|}|gksd|vr=|fdjjD|gksd|vr=|fdjjD|S)rrec:i|]}|j |k|j|Srrrrr6s r7rz*CardEF.get_selectables..s0```aAE`VW[_V_V_V_V_V_r9rfc:i|]}|j |k|j|Srrr;s r7rz*CardEF.get_selectables..s0bbbqQVbXY]aXaXaXaXaXar9)rrsrgr*rrrs` r7rszCardEF.get_selectablessww&&u-- B;;&E// KK````4;+?+F+F+H+H``` a a a B;;(e++ KKbbbbDK,@,G,G,I,Ibbb c c c r9) rrrrr8r>rrsrrs@r7r5r5~s66#####.....%'4r9r5c *eZdZdZedGddeZ ddeded ed ed ed e f fd Z de de fdZ dede fdZddeedeefdZdde deede fdZdde deedefdZedefdZxZS) TransparentEFzTransparent EF (Entry File) in the smart card filesystem. A Transparent EF is a binary file with no formal structure. This is contrary to Record based EFs which have [fixed size] records that can be individually read/updated.zTransparent EF CommandscZeZdZdZejZedddedede j ed Z ejZ e d e d d e de de j e dZejZeddde j edZejZed e d d edede j edZejZedededde j edZdZdS)TransparentEF.ShellCommandsz,Shell commands specific for transparent EFs. --oneline store_true.No JSON pretty-printing, dump as a single lineactionhelpHEXSTR$Hex-string of encoded data to decoderrFc|jjj|j}|j||jdSzHDecode command-line provided hex-string as if it was read from the file.N)rrr decode_hexrG poutput_jsononeliner6optsdatas r7 do_decode_hexz)TransparentEF.ShellCommands.do_decode_hexs@9?0;;DKHHD I " "4 6 6 6 6 6r9z--offsetrzByte offset for start of readrdefaultrFz--lengthzNumber of bytes to readc|jj|j|j\}}|j|dS)z&Read binary data from a transparent EFN)rr read_binarylengthoffsetpoutputr6rPrQ_sws r7do_read_binaryz*TransparentEF.ShellCommands.do_read_binarysA)/55dk4;OOKT3 I  d # # # # #r9c|jj\}}|j||jdS)z(Read + decode data from a transparent EFN)rrread_binary_decrMrNrZs r7do_read_binary_decodedz2TransparentEF.ShellCommands.do_read_binary_decodeds=)/99;;KT3 I " "4 6 6 6 6 6r9DATA Data bytes (hex format) to writec|jj|j|j\}}|r|j|dSdS)z'Update (Write) data of a transparent EFN)rr update_binaryr`rXrYrZs r7do_update_binaryz,TransparentEF.ShellCommands.do_update_binarysS)/77 4;OOKT3 ( !!$''''' ( (r9 --json-pathz1JSON path to modify specific element of file only$Abstract data (JSON format) to writerFcd|jrO|jj\}}t ||jt j|jnt j|j}|jj|\}}|r|j |dSdS)z0Encode + Update (Write) data of a transparent EFN) json_pathrrr^rr r&r`update_binary_decrMr6rP data_jsonr[rQs r7do_update_binary_decodedz4TransparentEF.ShellCommands.do_update_binary_decodeds~ 2#'9?#B#B#D#D Cy$.#z$)446666!Jty11 )/;;IFFKT3 - &&t,,,,, - -r9c|jj\}}|jjj}t |j||5}||kr|jdn>|jj|\}}|r|j|ddddS#1swxYwYdS)z=Edit the JSON representation of the EF contents in an editor.!Data not modified, skipping writeN)rrr^rrrYrjrM)r6_optsrr[r edited_jsonrQs r7do_edit_binary_decodedz2TransparentEF.ShellCommands.do_edit_binary_decodeds#y>>@@ Y.BDIy"55 5)++I%%&IJJJJ"&)/"C"CK"P"PKT35 ..t444  5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5s A B66B:=B:N)rrrrargparseArgumentParserdec_hex_parser add_argumentrcmd2with_argparserrRread_bin_parserrr\read_bin_dec_parserr_upd_bin_parserrdupd_bin_dec_parserrrmrrrr9r7rr@s::0022##K )Y $ [ [ [##H9Ci#jjj  ^ , , 7 7 - , 7 2(133$$ [!:Y % [ [ [$$ [/H % J J J  _ - - $ $ . - $ 6h577((\.^ ) ` ` `  0 1 1 7 7 2 1 7 1022## [!:Y $ [ [ [##FAc#ddd  ^ , , ( ( - , ( 5X466'' C-` ( b b b''5['\\\  / 0 0 - - 1 0 - 5 5 5 5 5r9rNrWNr&r'r(r)r*sizec tjd|||||d|d|_d|_||_|g|_dSas Args: fid : File Identifier (4 hex digits) sfid : Short File Identifier (2 hex digits, optional) name : Brief name of the file, like EF_ICCID desc : Description of the file parent : Parent CardFile object within filesystem hierarchy size : tuple of (minimum_size, recommended_size) r&r'r(r)r*Nr)rr8 _construct_tlvr~rr5 r6r&r'r(r)r*r~rrs r7r8zTransparentEF.__init__sb [St$T&[[TZ[[[  #11334r9 raw_bin_datar@ct|dd}t|r ||St|dd}t|r|t|S|jrt |j|S|jr]t j|jr|n|j}||| Sd| iS)aDecode raw (binary) data into abstract representation. A derived class would typically provide a _decode_bin() or _decode_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed). Args: raw_bin_data : binary encoded data Returns: abstract_data; dict representing the decoded data _decode_binN _decode_hexraw) rcallablerrrrinspectisclassfrom_tlvto_dicthex)r6rmethodrs r7 decode_binzTransparentEF.decode_bins}d33 F   (6,'' '}d33 F   -6#l++,, , ? B"4?LAA A 9 &ty99H tyA JJ| $ $ $99;; |''))**r9 raw_hex_datact|dd}t|r ||St|}t|dd}t|r ||S|jrt |j|S|jr]t j|jr|n|j}||| Sd| iS)aDecode raw (hex string) data into abstract representation. A derived class would typically provide a _decode_bin() or _decode_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed). Args: raw_hex_data : hex-encoded data Returns: abstract_data; dict representing the decoded data rNrr rrr rrrrrrrrr6rrrrs r7rLzTransparentEF.decode_hexs}d33 F   (6,'' '<(( }d33 F   (6,'' ' ? B"4?LAA A 9 &ty99H tyA JJ| $ $ $99;; |''))**r9 total_lenc||S|jdS|jd |jdS|jd |jdSdS)z'Get the size (total length) of the fileNrWr)r~r6rs r7 __get_sizezTransparentEF.__get_size6sT    9 4 9Q< #9Q<  9Q< #9Q< tr9 abstract_dataclt|dd}t|r ||||St|dd}t|r-t||||S|jr+t |j|d||iS|jr]tj|jr|n|j}| || Std|z)a Encode abstract representation into raw (binary) data. A derived class would typically provide an _encode_bin() or _encode_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed). Args: abstract_data : dict representing the decoded data total_len : expected total length of the encoded data (file size) Returns: binary encoded data _encode_binNr _encode_hexr0%s encoder not yet implemented. Patches welcome.) rr_TransparentEF__get_sizer rrrrr from_dictto_tlvNotImplementedErrorr6rrrrs r7 encode_binzTransparentEF.encode_binIs1}d33 F   Q6-T__Y5O5OPPP P}d33 F   Vvvm9S9STTTUU U ? o"4?MKRVRaRabkRlRlCmnn n 9 &ty99H tyA KK & & &88:: ! > EGG Gr9c t|dd}t|r ||||St|dd}t|r/||||}t|S|jr8tt |j|d||iS|jrjtj|jr|n|j}| |t| Std|z)aEncode abstract representation into raw (hex string) data. A derived class would typically provide an _encode_bin() or _encode_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed). Args: abstract_data : dict representing the decoded data total_len : expected total length of the encoded data (file size) Returns: hex string encoded data rNrrrr) rrrrrrrrrrrr)r6rrrrrs r7 encode_hexzTransparentEF.encode_hexesC}d33 F   Q6-T__Y5O5OPPP P}d33 F   %!6-T__Y=W=WXXXL|$$ $ ? rt TXTcTcdmTnTnGoppqq q 9 #&ty99H tyA KK & & &qxxzz?? "! > EGG Gr9rc|dkr$td|zd}|r<|}|dtj|dt zz }n/|}|dt|dzz }|S)z Export the file contents of a TransparentEF. This method returns a shell command string (See also ShellCommand definition in this class) that can be used to write the file contents back. transparentzTselected file has structure type '%s', expecting a file with structure 'transparent'zupdate_binary_decoded '%s' rrzupdate_binary %s ) selected_file_structurer2r^r r rrVrstrip)rr export_strresults r7rzTransparentEF.exports  ( ( * *m ; ;s"::<<=>> >  B**,,F 9DJvayVar>s__ 455L5L5L5L5L5 L5L565L5\im'55C5s5535_e5555555"+y+T++++4+s+t++++6HSMXc]&GGG#GR[GGGG8GGG#GRUGGGG:""""\"""""r9r>cLeZdZdZedGddeZ dded ed ed ed ee d e de ffd Z ddede defdZdede defdZd dee dee fdZd dede dee defdZd dede dee defdZede fdZxZS)! LinFixedEFzLinear Fixed EF (Entry File) in the smart card filesystem. Linear Fixed EFs are record oriented files. They consist of a number of fixed-size records. The records can be individually read/updated.zLinear Fixed EF CommandsceZdZdZejZedddedede j ed Z ejZ e d e d d e de de j e dZejZedddede de j edZejZe j edZejZeddde j edZejZede dedede j edZejZededede dedde j edZejZede de j edZdS) LinFixedEF.ShellCommandsz-Shell commands specific for Linear Fixed EFs.rArBrCrDrGrHrIc|jjj|j}|j||jdSrK)rrrdecode_record_hexrGrMrNrOs r7rRz&LinFixedEF.ShellCommands.do_decode_hexs@9?0BB4;OOD I " "4 6 6 6 6 6r9z--countrWz4Number of records to be read, beginning at record_nrrS RECORD_NRzNumber of record to be readct|jD]r}|j|z}|jj|\}}t |dkrt|}nd}|jd||fzsdS)z6Read one or multiple records from a record-oriented EFr(empty)%03d %sN) rRcountrrr read_recordrSrrY)r6rPrrecnrrQr[recstrs r7do_read_recordz'LinFixedEF.ShellCommands.do_read_records4:&& ? ?*"io99%@@ st99q== YYFF&F !!)ufo"=>>>> ? ?r9c|jj|j\}}|j||jdS)z0Read + decode a record from a record-oriented EFN)rrread_record_decrrMrNrZs r7do_read_record_decodedz/LinFixedEF.ShellCommands.do_read_record_decodedsA)/99$.IIKT3 I " "4 6 6 6 6 6r9c:|jj}tdd|zD]h}|jj|\}}t |dkrt |}nd}|jd||fzidS)z*Read all records from a record-oriented EFrWrrrN)rrselected_file_num_of_recrRrrSrrY)r6rp num_of_recrrQr[rs r7do_read_recordsz(LinFixedEF.ShellCommands.do_read_recordssAACCJq!j.11 ? ?"io99%@@ st99q== YYFF&F !!)ufo"=>>>>  ? ?r9c |jj}g}tdd|zD]9}|jj|\}}||:|j||jdS)z3Read + decode all records from a record-oriented EFrWN)rrrrRrrIrMrN)r6rPr data_listrrQr[s r7do_read_records_decodedz0LinFixedEF.ShellCommands.do_read_records_decodedsAACCJIq!j.11 ' '"io==eDD s  &&&& I " "9dl ; ; ; ; ;r9r`rac|jj|j|j\}}|r|j|dSdS)z+Update (write) data to a record-oriented EFN)rr update_recordrr`rYrZs r7do_update_recordz)LinFixedEF.ShellCommands.do_update_recordsS)/77 RRKT3 ( !!$''''' ( (r9rez3JSON path to modify specific element of record onlyrQrfrgc||jrU|jj|j\}}t ||jt j|jnt j|j}|jj |j|\}}|r|j |dSdS)z4Encode + Update (write) data to a record-oriented EFN) rirrrrrr r&rQupdate_record_decrYrks r7do_update_record_decodedz1LinFixedEF.ShellCommands.do_update_record_decodeds~ 2#'9?#B#B4>#R#R Cy$.#z$)446666!Jty11 )/;; ++KT3 ( !!$''''' ( (r9zNumber of record to be editedc|jj|j\}}|jjj}t |j||5}||kr|jdnD|jj|j|\}}|r|j|ddddS#1swxYwYdS)z8Edit the JSON representation of one record in an editor.roN) rrrrrrrYrrM)r6rPrr[rrqrQs r7do_edit_record_decodedz/LinFixedEF.ShellCommands.do_edit_record_decoded s  $y>>t~NN Y.BDIy"55 5)++I%%&IJJJJ"&)/"C"C #5#5KT35 ..t444 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5sA&CC CN)rrrrrsrtrurvrrwrxrRread_rec_parserrrread_rec_dec_parserrread_recs_parserrread_recs_dec_parserrupd_rec_parserrupd_rec_dec_parserrredit_rec_dec_parserrrr9r7rrs;;0022##K )Y $ [ [ [##H9Ci#jjj  ^ , , 7 7 - , 7 2(133$$ J8n % p p p$$ j/L % N N N  _ - - ? ? . - ?6h577((\.^ ) ` ` `(( j/L ) N N N  0 1 1 7 7 2 1 7 38244  - . . ? ? / . ? 7x688))+l/_ * a a a  1 2 2 < < 3 2 <1022## j/L $ N N N##FAc#ddd  ^ , , ( ( - , ( 5X466'' C-b ( d d d'' j/L ( N N N''5['\\\  / 0 0 ( ( 1 0 (6h577(( j/N ) P P P  0 1 1 5 5 2 1 5 5 5r9rNr}Fr&r'r(r)r*rec_lenleftpadc tjd|||||d|||_||_|g|_d|_d|_dS)a Args: fid : File Identifier (4 hex digits) sfid : Short File Identifier (2 hex digits, optional) name : Brief name of the file, like EF_ICCID desc : Description of the file parent : Parent CardFile object within filesystem hierarchy rec_len : Tuple of (minimum_length, recommended_length) leftpad: On write, data must be padded from the left to fit physical record length rNr)rr8rrrr5rr) r6r&r'r(r)r*rrrrs r7r8zLinFixedEF.__init__sg [St$T&[[TZ[[[  #11334 r9rWrrr@ct|dd}t|r |||St|}t|dd}t|r |||S|jrt |j|S|jr]t j|jr|n|j}||| Sd| iS)aDecode raw (hex string) data into abstract representation. A derived class would typically provide a _decode_record_bin() or _decode_record_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed). Args: raw_hex_data : hex-encoded data record_nr : record number (1 for first record, ...) Returns: abstract_data; dict representing the decoded data _decode_record_hexNr_decode_record_binrr)r6rrrrrs r7rzLinFixedEF.decode_record_hex+s3T:: F   =6,)<<< <<(( 3T:: F   =6,)<<< < ? B"4?LAA A 9 &ty99H tyA JJ| $ $ $99;; |''))**r9rct|dd}t|r |||St|}t|dd}t|r |||S|jrt |j|S|jr]t j|jr|n|j}||| Sd|iS)aDecode raw (binary) data into abstract representation. A derived class would typically provide a _decode_record_bin() or _decode_record_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed). Args: raw_bin_data : binary encoded data record_nr : record number (1 for first record, ...) Returns: abstract_data; dict representing the decoded data rNrrr) rrrrrrrrrr)r6rrrrrs r7decode_record_binzLinFixedEF.decode_record_binGs3T:: F   =6,)<<< <<(( 3T:: F   =6,)<<< < ? B"4?LAA A 9 &ty99H tyA JJ| $ $ $99;; |$$r9rc||S|jdS|jd |jdS|jd |jdSdS)0Get the length (total length) of the file recordNrWrrrs r7 __get_rec_lenzLinFixedEF.__get_rec_lencsT    < 4 <? &<? " <? &<? "tr9rc t|dd}t|r!|||||St|dd}t|r0|||||}t|S|jr8tt |j|d||iS|jrjtj|jr|n|j}| |t| Std|z)aeEncode abstract representation into raw (hex string) data. A derived class would typically provide an _encode_record_bin() or _encode_record_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed). Args: abstract_data : dict representing the decoded data record_nr : record number (1 for first record, ...) total_len : expected total length of the encoded data (record length) Returns: hex string encoded data _encode_record_hexNrr_encode_record_binrr) rr_LinFixedEF__get_rec_lenrrrrrrrrr)r6rrrrrrs r7encode_record_hexzLinFixedEF.encode_record_hexvsP3T:: F   i6-9$J\J\]fJgJghhh h3T:: F   %!6-9RVRdRdenRoRopppL|$$ $ ? ut TXTfTfgpTqTqGrsstt t 9 #&ty99H tyA KK & & &qxxzz?? "! > EGG Gr9c pt|dd}t|r!|||||St|dd}t|r.t|||||S|jr+t |j|d||iS|jr]tj|jr|n|j}| || Std|z)a]Encode abstract representation into raw (binary) data. A derived class would typically provide an _encode_record_bin() or _encode_record_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed). Args: abstract_data : dict representing the decoded data record_nr : record number (1 for first record, ...) total_len : expected total length of the encoded data (record length) Returns: binary encoded data rNrrrr) rrrr rrrrrrrr)r6rrrrrs r7encode_record_binzLinFixedEF.encode_record_bins=3T:: F   i6-9$J\J\]fJgJghhh h3T:: F   nvvmydN`N`ajNkNklllmm m ? p"4?MKPTPbPbclPmPmCnoo o 9 &ty99H tyA KK & & &88:: ! > EGG Gr9rcb|dkr<|dkr$td|zd}|}|rtd|dzD]u}|r?||}|d|t j|dtfzz }C||}|d |t|dfzz }vnd} |r?||}|d|t j|dtfzz }n2||}|d |t|dfzz }|#t$r}|j d krYd }~nYd }~nd }~wwxYw|dz}| S) z Export the file contents of a LinFixedEF (or a CyclicEF). This method returns a shell command string (See also ShellCommand definition in this class) that can be used to write the file contents back. linear_fixedcycliczaselected file has structure type '%s', expecting a file with structure 'linear_fixed' or 'cyclic'rrWzupdate_record_decoded %d '%s' rrzupdate_record %d %s T9402N) rr2rrRrr r rrrr sw_actualr)rrrrrrr,s r7rzLinFixedEF.exports&  ( ( * *n < <A^A^A`A`dlAlAlA"::<<=>> > 3355  1j1n-- R RR"22155F#D4:V\]^V_epKqKqKqGr#rsJJ"..q11F#:aVAY=P#PQJJ  RA  V!&!6!6q!9!9"'HAtzZ`abZcitOuOuOuKv'vw !&!2!21!5!5"'>!SPQ^^AT'TU G ${f,,-,,,,E "!!!s;A3E00 F: FF)NNNNr}F)rWr;)rrrrr r rrrr+rrr8rrrrrrrrrrrrs@r7rrs?? 566y5y5y5y5y5 y5y576y5vRV]bCs3!&);?VZ&++c+c+$++++8%i%C%D%%%%8x} &GGtGGPXY\P]GilGGGG<GGtGGQYZ]Q^GjsGGGG:-"-"-"-"\-"-"-"-"-"r9rc BeZdZdZ d dededededed ef fd ZxZS) CyclicEFz3Cyclic EF (Entry File) in the smart card filesystemNr}r&r'r(r)r*rc Htjd||||||d|dS)N)r&r'r(r)r*rrr7) r6r&r'r(r)r*rrrs r7r8zCyclicEF.__init__s7lSt$T&Zalleklllllr9r) rrrrrr+rr8rrs@r7rrs==im!*mmCmsmm3m_emmmmmmmmmmmr9rceZdZdZ ddededededed eed effd Z d ed e fdZ de d e fdZ ddeed eefdZdde deed efdZdde deed e fdZde fdZd efdZxZS) TransRecEFaTransparent EF (Entry File) containing fixed-size records. These are the real odd-balls and mostly look like mistakes in the specification: Specified as 'transparent' EF, but actually containing several fixed-length records inside. We add a special class for those, so the user only has to provide encoder/decoder functions for a record, while this class takes care of split / merge of records. Nr}r&rr'r(r)r*r~c Vtjd||||||d|||_dS)a Args: fid : File Identifier (4 hex digits) sfid : Short File Identifier (2 hex digits, optional) name : Brief name of the file, like EF_ICCID desc : Description of the file parent : Parent CardFile object within filesystem hierarchy rec_len : Length of the fixed-length records within transparent EF size : tuple of (minimum_size, recommended_size) )r&r'r(r)r*r~Nr)rr8r) r6r&rr'r(r)r*r~rrs r7r8zTransRecEF.__init__s> fSt$T&W[ff_efff r9rr@c,t|dz|krd|iSt|dd}t|r ||St |}t|dd}t|r ||S|jrt |j|S|jr]tj |jr|n|j}| || Sd|iS)aDecode raw (hex string) data into abstract representation. A derived class would typically provide a _decode_record_bin() or _decode_record_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed). Args: raw_hex_data : hex-encoded data Returns: abstract_data; dict representing the decoded data rrrNr) rS_TransRecEF__get_rec_lenrrr rrrrrrrrs r7rzTransRecEF.decode_record_hexs |   !D$6$6$8$8 8 8<( (3T:: F   (6,'' '<(( 3T:: F   (6,'' ' ? B"4?LAA A 9 &ty99H tyA JJ| $ $ $99;; |$$r9rc@t||krdt|iSt|dd}t |r ||St|}t|dd}t |r ||S|jrt |j|S|jr]tj |jr|n|j}| || Sd|iS)aDecode raw (binary) data into abstract representation. A derived class would typically provide a _decode_record_bin() or _decode_record_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed). Args: raw_bin_data : binary encoded data Returns: abstract_data; dict representing the decoded data rrNr) rSrrrrrrrrrrr)r6rrrrs r7rzTransRecEF.decode_record_bin&s |  t1133 3 33|,,- -3T:: F   (6,'' '<(( 3T:: F   (6,'' ' ? B"4?LAA A 9 &ty99H tyA JJ| $ $ $99;; |$$r9rc*||S|jr|jSdS)rNrrs r7rzTransRecEF.__get_rec_lenFs)    < < tr9rc t|dd}t|r ||||St|dd}t|r-t||||S|jrEtt t |j|d||iS|jrjtj |jr|n|j}| |t| Std|z)a%Encode abstract representation into raw (hex string) data. A derived class would typically provide an _encode_record_bin() or _encode_record_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed). Args: abstract_data : dict representing the decoded data total_len : expected total length of the encoded data (record length) Returns: hex string encoded data rNrrrr) rrrrrrrrrrrrrrs r7rzTransRecEF.encode_record_hexSsb3T:: F   T6-T5G5G 5R5RSSS S3T:: F   Yvvm9K9KI9V9VWWWXX X ? b{?4?M4?@R@RS\@]@]3^$`$`aabb b 9 #&ty99H tyA KK & & &qxxzz?? "! > EGG Gr9c t|dd}t|r ||||St|dd}t|r-t||||S|jr8t t |j|d||iS|jr]tj |jr|n|j}| || Std|z)aEncode abstract representation into raw (binary) data. A derived class would typically provide an _encode_record_bin() or _encode_record_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed). Args: abstract_data : dict representing the decoded data total_len : expected total length of the encoded data (record length) Returns: binary encoded data rNrrrr) rrrr rrrrrrrrrrs r7rzTransRecEF.encode_record_binpsM3T:: F   T6-T5G5G 5R5RSSS S3T:: F   Yvvm9K9KI9V9VWWWXX X ? ]t 0;D EGG Gr9cfdtdtjD}fd|DS)Nc4g|]}||jzSrr)rrUrr6s r7 z*TransRecEF._decode_bin..s?FFFq4</0FFFr9rc:g|]}|Sr)rr;s r7rz*TransRecEF._decode_bin..s':::a&&q)):::r9)rRrSr)r6rchunkss`` r7rzTransRecEF._decode_binsiFFFFF C $5$5t|DDFFF::::6::::r9c Nfd|D}d|S)Nc fg|]-}|dd.S)rNr)rget)rrrr6s r7rz*TransRecEF._encode_bin..s<nnn[\$(( ;PT8U8U(VVnnnr9r9)rE)r6rrrs` ` r7rzTransRecEF._encode_bins3nnnnn`mnnnxxr9rr;)rrrrrrrr+rr8rrrrrrrrbytesrrrs@r7rrs`d?H  C # S s Y\ !&) 8<       %c %d % % % %D%i%D%%%%@  x}     GGtG GY\GGGG:GGtG GYbGGGG:; ;;;;  e        r9rc eZdZdZedGddeZ ddeded ed ed ed e f fd Z e de fdZ xZS)BerTlvEFaVBER-TLV EF (Entry File) in the smart card filesystem. A BER-TLV EF is a binary file with a BER (Basic Encoding Rules) TLV structure NOTE: We currently don't really support those, this class is simply a wrapper around TransparentEF as a place-holder, so we can already define EFs of BER-TLV type without fully supporting them.zBER-TLV EF CommandsceZdZdZejZedede j edZ dZ ejZ e dede ded e j e d ZejZedede j ed Zd Zd S)BerTlvEF.ShellCommandsz(Shell commands specific for BER-TLV EFs.TAGz BER-TLV Tag of value to retrieverIc|jj|j\}}|j|dS)z&Retrieve (Read) data from a BER-TLV EFN)rr retrieve_datarrYrZs r7do_retrieve_dataz'BerTlvEF.ShellCommands.do_retrieve_datas=)/77AAKT3 I  d # # # # #r9cv|jj}|j|dS)z)List tags available in a given BER-TLV EFN)rr retrieve_tagsrY)r6rptagss r7do_retrieve_tagsz'BerTlvEF.ShellCommands.do_retrieve_tagss39?0022D I  d # # # # #r9zBER-TLV Tag of value to setrQrac|jj|j|j\}}|r|j|dSdS)z0Set (Write) data for a given tag in a BER-TLV EFN)rrset_datarrQrYrZs r7 do_set_dataz"BerTlvEF.ShellCommands.do_set_datasS)/2248TYGGKT3 ( !!$''''' ( (r9c|jj|jd\}}|r|j|dSdS)z+Delete data for a given tag in a BER-TLV EFN)rrrrrYrZs r7do_delete_dataz%BerTlvEF.ShellCommands.do_delete_datasQ)/2248TBBKT3 ( !!$''''' ( (r9c|jj}|D]"}|jj|d#dS)z!Delete all data from a BER-TLV EFN)rrrr)r6rPrtags r7 do_delete_allz$BerTlvEF.ShellCommands.do_delete_allsM9?0022D 4 4 ((d3333 4 4r9N)rrrrrsrtretrieve_data_parserrvrrwrxrrset_data_parserrrdel_data_parserrrrr9r7rr s{666x688)) 'I * K K K  1 2 2 $ $ 3 2 $  $ $ $ 2(133$$ 'D % F F F$$V)Bd$eee  _ - - ( ( . - ( 2(133$$ 'D % F F F  _ - - ( ( . - (  4 4 4 4 4r9rNr}r&r'r(r)r*r~c tjd|||||d|d|_||_|g|_dSr)rr8rr~rr5rs r7r8zBerTlvEF.__init__s[ [St$T&[[TZ[[[ #11334r9rc|dkr$td|z|rtdd}|}|gkr|dz }n]|dz }|D]U}||}t t |d\}}}} |d|t|fzz }V|S) z Export the file contents of a BerTlvEF. This method returns a shell command string (See also ShellCommand definition in this class) that can be used to write the file contents back. ber_tlvzPselected file has structure type '%s', expecting a file with structure 'ber_tlv'z6BerTlvEF encoder not yet implemented. Patches welcome.rz# empty file, no tagsz delete_all rzset_data 0x%02x %s ) rr2rrrrr rr) rrrrrrrlval remainders r7rzBerTlvEF.exports  ( ( * *i 7 7o"::<<=>> >  `%&^__ _ ""$$ 2:: 1 1JJ . (J G G,,Q//+;Cq NN+K+K(ai5CHH EF !!!r9r)rrrrr r rrr+rr8rrrrrs@r7r r s++011-4-4-4-4-4 -4-421-4^im'55C5s5535_e5555555 """"\"""""r9r sw_dataswc|D]G\}}||vr |||fcS|D]\}}t||r||fccSHdS)zInterpret a given status word. Args: sw_data : Hierarchical dict of status word matches sw : status word to match (string of 4 hex digits) Returns: tuple of two strings (class_string, description) N)itemsr)r'r( class_strswdictpatterndescrs r7 interpret_swr/s%]]__** 6 <<vbz* * * *$llnn * *NGUG$$ *!5)))))) * * 4r9c\eZdZdZd deededefdZdZ dZ e d e fd Z dS) CardApplicationzqA card application is represented by an ADF (with contained hierarchy) and optionally some SW definitions.Nadfrr(c|r|}||_||_|pi|_|jr!|p |jj|_||j_dS||_dS)zc Args: adf : ADF name sw : Dict of status word conversions N)r3r(r2r(rr)r6r(r2rr(s r7r8zCardApplication.__init__sg  ))++C ( 8 *dhlDH#'DH DHHHr9cd|jzS)NzAPP(%s)rr=s r7r>zCardApplication.__str__&sDI&&r9c,t|j|S)zInterpret a given status word within the application. Args: sw : Status word as string of 4 hex digits Returns: Tuple of two strings )r/r()r6r(s r7r/zCardApplication.interpret_sw)sDGR(((r9rc0dt|jzS)z Export application specific parameters, in the form of commandline script. (see also comment in the export method of class "CardFile") z# %s has no exportable featuresrrs r7rzCardApplication.export4s 13u7J3K3KKKr9)NNN)rrrrrr1rrr8r>r/rrrrr9r7r1r1s(7"3QU$''' ) ) )LLLL\LLLr9r1ceZdZdZgZeejd dZede de fdZ e de ddfdZ d S) CardModelzA specific card model, typically having some additional vendor-specific files. All you need to do is to define a sub-class with a list of ATRs or an overridden match method.rs RuntimeStatecdS)z/Add model specific files to given RuntimeState.Nr)rr9s r7rzCardModel.add_filesDsr9sccr@cN|}|jD]+}||kr#td|jdS,t |d}|jD]@}t |d}||kr#td|jdSAdS)z&Test if given card matches this model.zDetected CardModel: %sThbF)get_atr_atrsloginforr)rr<card_atratr card_atr_hbatr_hbs r7matchzCardModel.matchIs;;==9  Ch13<@@@tt#8,,T2 9  C!#&&t,F$$13<@@@tt%ur9ctD],}||r||-dS)zCheck if any of the CardModel sub-classes 'match' the currently inserted card (by ATR or overriding the 'match' method). If so, call their 'add_files' method.N)r8__subclasses__rGr)r<r9ms r7apply_matching_modelszCardModel.apply_matching_modelsZsK ))++  Awws||  B  r9N)r9r:)rrrrr@ classmethodabcabstractmethodrrrrGrrKrr9r7r8r8>s E>>>[>D[  ?    \   r9r8ceZdZdZdeeeeeeffdZdefdZ defdZ ddde fdZ d Z d Zd Zdd Zddde fd ZdS)Pathz%Representation of a file-system path.pct|tr|d}n6t|r't|dtr d|D}d|D|_dS)Nr#rcg|]}d|zS)z%04xrrs r7rz!Path.__init__..ks'''!'''r9c6g|]}|Sr)rrs r7rz!Path.__init__..ms ***1QWWYY***r9)r0rsplitrSrru)r6rQs r7r8z Path.__init__fst a   ( AA VV ( 1Q4-- (''Q'''A***** r9r@c6d|jS)Nr#)rErur=s r7r>z Path.__str__osxx """r9c&dt|zS)NzPath(%s))rr=s r7__repr__z Path.__repr__rsSYY''r9otherc"|j|jkSr;rur6rYs r7__eq__z Path.__eq__usyEJ&&r9c|j|Sr;r[)r6rUs r7 __getitem__zPath.__getitem__xsy|r9c*t|jSr;rSrur=s r7__len__z Path.__len__{s49~~r9ct|tr |j|z}n0t|tr|j|jz}n |j|gz}t|Sr;)r0rurP)r6ar$s r7__add__z Path.__add__~s[ a    A AA 4   AF"AA QCAAwwr9ct|jr+|jddvrt|jddS|S)z?Return a path relative to MF, i.e. without initial explicit MF.r)r$3F00rWN)rSrurPr=s r7relative_to_mfzPath.relative_to_mfs? ty>> 'diln<< !"" && & r9ct|jt|jkrdS|jdt|j|jkrdSdS)z6Is this instance a parent of the given other instance?FNTrar\s r7 is_parentzPath.is_parentsL ty>>S__ , ,5 :os49~~o &$) 3 34ur9N)r@rP)rrrrr rrrr8r>rXrr]r_rbrerhrjrr9r7rPrPds//+%T#YS 9:++++#####(#(((('F't'''' v$r9rP)Frtypingrrrrrrr rsr r rMrr0rwr r smartcard.utilr osmocom.utilsr rrrrrrr osmocom.tlvrosmocom.constructrrr pySim.utilsrrpySim.jsonpathrpySim.commandsrpySim.exceptionsr pySim.logrrrrrrrAr r+r`r1rr5r>rrrr rrr/r1ABCr8rPrr9r7rvs2FEEEEEEEEEEEEEEEEE  22222222""""""eeeeeeeeeeeeeeeeeeee((((((KKKKKKKKKK........))))))******))))))!!!!!! T#Yc3h78 S(3-  kohALALALALALALALALHEEEEEXEEEPFFFFFVFFFRFFFFFfFFF@L#L#L#L#L#L#L#L#^X:x"x"x"x"x"Fx"x"x"vI"I"I"I"I"I"I"I"X mmmmmzmmmj j j j j j j j Za"a"a"a"a"va"a"a"H$C(*L*L*L*L*L*L*L*L\# # # # # # # # L//////////r9