gWgdZddlmZmZddlmZmZmZmZddl m Z ddl Tddl Tde de fdZGd d ZGd d Zd S)zHRepresentation of the runtime state of an application like pySim-shell. )OptionalTuple)h2bi2his_hexHexstr)bertlv_parse_one)*clareturnc\|dz dvr|dzS|dzdvrd|dzzStd|z)z5Resolve the logical channel number from the CLA byte.)r )@z/Could not determine logical channel for CLA=%2X) ValueError)r s ;/home/jenkins/workspace/simtester-sanitize/pySim/runtime.pylchan_nr_from_clarsO ax?""Tz Tz\!!C$J FL M MMcbeZdZdZddZdZdd efd Zd ed d fd Z d efdZ d e d fdZ dS) RuntimeStatez5Represent the runtime state of a session with a card.cardCardBaseprofile CardProfilec0t||_||_||_i|_t d||jd<i|_d|_|j|jj |jj |jj D]e}|}| |jr?td|jd|d|jD]}|j|f|jdd|}|D](}|jr|j|j)|jjD]}|j|d |_|d S) zo Args: card : pysim.cards.Card instance profile : CardProfile instance )rrF)r sel_ctrlz Detected z Add-on ""MFTN)CardMFmfrrlchan RuntimeLchanidentity adm_verifiedset_apdu_parameterr r!addonsprobeprint files_in_mfadd_fileselect_match_applicationsadfadd_application_dfconserve_writereset)selfrr addon_clsaddonfappsas r__init__zRuntimeState.__init__)s )))   $Q-- 1  ! $$  4<+@ % B B B, ( (IIKKE{{49%% (T\\\555IJJJ*((AG$$Q'''' 1 T"""'')) 2 2Au 2**15111)  A G  Q    " rc  |jj}|sgS|j}g}|rg}t d|D]U}|D]P}|j|vrEt d|jd|d||||QVt|t|z }|D]}t d|znt dtt|t|z tD]}} |j |j\}} ||_ | dkr4t d|jd|j||g#ttf$rYzwxYw|S) zEmatch the applications from the profile with applications on the cardz AIDs on card: : z (EF.DIR)z unknown: %s (EF.DIR)z"warning: EF.DIR seems to be empty!)key9000)r applicationsr read_aidsr-aidnameappendsetsortedstrselect_adf_by_aid selected_adf SwMatchError ProtocolError) r6 apps_profile aids_card apps_taken aids_takenr;r9 aids_unknown_datasws rr1z RuntimeState._match_applicationsVs|0  II''))   8J / " " " - -%--AuzzAFFFAAA>???"))!,,,"))!,,, - y>>C OO;L! 3 3-12222 3 6 7 7 7L))C OO;EEE  A !I77>> r$%!<<Eqvvvquu5666%%a((( -0    sA#E77F  F Nr ct|jD](}d|j|j_|dkr |j|=)d|_t |j}|r|jd|_|jd d|d|jd_ ||j d<|S)zPerform physical card reset and obtain ATR. Args: cmd_app : Command Application State (for unregistering old file commands) NrFr#ATR) listr&keyssccscpr)rrr5r0rKr()r6cmd_applchan_nratrs rr5zRuntimeState.resets TZ__..// % %H+/DJx $ (1}} 8$$!$)//##$$  * JqMGM 1 T7+++%) 1 "" e rr\r'c||jvrtd|zt|||j|<|j|S)zAdd a logical channel to the runtime state. You shouldn't call this directly but always go through RuntimeLchan.add_lchan().z'Cannot create already-existing lchan %d)r&rXrr'r6r\s r add_lchanzRuntimeState.add_lchansR tz(( ( (FQRR R+Hd;; 8z(##rcP||jvr |j|=dSdS)NTF)r&rXr_s r del_lchanzRuntimeState.del_lchans- tz(( ( ( 8$45rctt|}||jvr |j|SdSN)rr&rX)r6r r\s rget_lchan_by_clazRuntimeState.get_lchan_by_clas8$S)) tz(( ( (:h' '4r)rrrrrd) __name__ __module__ __qualname____doc__r<r1rr5intr`rbrrerrrr&s??++++Z,,,\V,$#$.$$$$#x'?rrcLeZdZdZdedefdZdeddfdZdefdZ de fdZ de fd Z de fd Zdeefd Zdeefd Zdeefd ZdeefdZdeefdZdefdZdeefdZde defdZde fdZd4de fdZd5deefdZd4defdZd4de fdZdZ de fdZ!de fdZ"d6d!ed"efd#Z#de$ee ffd$Z%d7d%e d"efd&Z&d'efd(Z'd7d)efd*Z(d7d)ede$ee ffd+Z)d)ed%e fd,Z*d)ed'efd-Z+d7d.efd/Z,d0Z-d.ed%e fd1Z.d4d2Z/d4d3Z0dS)8r'z=Represent the runtime state of a logical channel with a card.r\rsc||_||_|jjj||_|jj|_d|_d|_ d|_ dSrd) r\rmr_scc fork_lchanrYr% selected_filerKselected_file_fcpselected_file_fcp_hex)r6r\rms rr<zRuntimeLchan.__init__sX  7<$//99"WZ !%%)"""rr c|j|}|jdkr%||_|j|_|S)zAdd a new logical channel from the current logical channel. Just affects internal state, doesn't actually open a channel with the UICC.r)rmr`r\get_cwdrqrK)r6r\ new_lchans rr`zRuntimeLchan.add_lchansGG%%h// =A  &*llnnI #%)%6I "rc(|jddS)Nfile_descriptorfile_descriptor_byte)rrr6s rselected_file_descriptor_bytez*RuntimeLchan.selected_file_descriptor_bytes%&789OPPrc6|dS)N shareabler{rzs rselected_file_shareablez$RuntimeLchan.selected_file_shareable1133K@@rc6|dS)N structurer~rzs rselected_file_structurez$RuntimeLchan.selected_file_structurerrc6|dS)N file_typer~rzs rselected_file_typezRuntimeLchan.selected_file_typerrcB|jddS)Nrx num_of_recrrgetrzs rselected_file_num_of_recz%RuntimeLchan.selected_file_num_of_rec%&78<<\JJJrcB|jddS)Nrx record_lenrrzs rselected_file_record_lenz%RuntimeLchan.selected_file_record_lenrrc6|jdS)N file_sizerrzs rselected_file_sizezRuntimeLchan.selected_file_sizes%))+666rcB|jddS)Nproprietary_informationreserved_file_sizerrzs r selected_file_reserved_file_sizez-RuntimeLchan.selected_file_reserved_file_sizes %&?@DDEYZZZrcB|jddS)Nrmaximum_file_sizerrzs rselected_file_maximum_file_sizez,RuntimeLchan.selected_file_maximum_file_sizes %&?@DDEXYYYrc\t|jtr|jS|jjS)z\Obtain the current working directory. Returns: CardDF instance ) isinstancerqCardDFparentrzs rruzRuntimeLchan.get_cwds. d(& 1 1 -% %%, ,rc||j}|j|kr)t|tr|S|j}|j|k)dS)zoObtain the currently selected application DF (if any). Returns: CardADF() instance or NoneN)rqrrCardADF)r6nodes rget_application_dfzRuntimeLchan.get_application_dfsM !kT!!$((  ;DkT!!trrEcd|vr'|d}|ddkrd|d<n|g}|}|D]2}|}d}|D]}||kr ||}n|dS3|S)zObtain the file object from the file system tree by its name without actually selecting the file. Returns: CardFile() instance or None/rr#N)splitruget_selectables)r6rEpathlistfilep selectables selectables rget_file_by_namezRuntimeLchan.get_file_by_names $;;zz#H{b  " vH ||~~  A..00KD)   ??&z2DE# |tt rrTcd}|}|r.|j}|r%t|dr||}|p|jj|S)zInterpret a given status word relative to the currently selected application or the underlying card profile. Args: sw : Status word as string of 4 hex digits Returns: Tuple of two strings N interpret_sw)r applicationhasattrrrmr)r6rTresr2apps rrzRuntimeLchan.interpret_sw st%%''  +/C +wsN33 +&&r**6dgo222666rNfidc t|ddstd|z|| |j|\}}nn#t $ra}||||j}|s|t|jd|dd|d|d}~wwxYw|j |}|dd d d kr6t|dd t|zd }n|dd ddkr6t|ddt|zd}n5t!|ddt|zd}|j |g||||dS)zqBlindly try to select a file and automatically add a matching file object if the file actually exists.rzNCannot select unknown file by name %s, only hexadecimal 4 digit FID is allowedr?rz - NrxryrdfzDF.z)dedicated file, manually added at runtime)rsfidrEdescr transparentzEF.z*elementary file, manually added at runtime)rrunregister_cmdsrY select_filerL _select_postr sw_actual RuntimeErrorrqdecode_select_responserrIupper TransparentEF LinFixedEF add_files) r6rr[data_swswmk select_respr9s r probe_filezRuntimeLchan.probe_file5s'c1a   h`cffhh h W%%% U(..s33KT33 U U U   g & & &!!#-00A   qtttQqTTJKKQT T  U(??EE ( )*@ A+ NRV V V3TC8H8H0HGIIIAA,-.DEkRVccc!c53s88>>CSCS;S'SUUU3TC@P@P8P$PRRR $$aS))) '1d+++++sA C"AB>>Crc|rZ||_t|tr||_|r'||_|j||_nd|_d|_||dSrd)rqrrrKrsrrr register_cmds)r6r[rselect_resp_datas rrzRuntimeLchan._select_post^s  .!%D $(( )$(! .-=*)-);)R)RSc)d)d&&-1*)-& 7#####rctt|ts|jr|jjdkr|jjD]Q}t|dtr4|djdkr#||dj |nR|j |}|std|j d|| ||j }|j}|D]} t|tr/|jj|j|j\}}n"|j|j\}}|}l#t*$r} ||||| d} ~ wwxYw||||dS)zSelect a file (EF, DF, ADF, MF, ...). Args: file : CardFile [or derived class] instance cmd_app : Command Application State (for unregistering old file commands) FrTzCannot determine path from z to )rYN)rrrKhas_fsrmr%ritemsr0rErqbuild_select_path_torrrsrrJrDrYrrrLr) r6rr[r inter_pathrqrr9rrs rrzRuntimeLchan.select_fileos$(( T-> 4CTC[_dCdCd#gj88::@@BB   jmW55*Q-:NRV:V:VKK 1 2G<<<E'<"&',"@"@DH"@"U"UKT33"&("6"6qu"="=KT3 !    !!'=$???   '1d+++++s A(E66 FFFcJ|j}d|vrs|d}|ddkrd|d< |D]}||||jS#t$r}||||d}~wwxYw|j}t|r|} ||vr||||n| ||n*#t$r}||||d}~wwxYw|jS)zSelect a file (EF, DF, ADF, MF, ...). Args: name : Name of file to select cmd_app : Command Application State (for unregistering old file commands) rrrr#N) rqrr0rr Exceptionrrrlowerr)r6rEr[ prev_sel_filerreselss rr0zRuntimeLchan.selectsb*  $;;zz#H{b  "  !,,AKK7++++--     888 !1133 $<< ::<DDcn|j\}}|j|S)z5Request STATUS (current selected file FCP) from card.)rYstatusrqr)r6rrs rrzRuntimeLchan.statuss.hoo'' s!88>>>rcD|j}||S)z9Get the related CardFile object for a specified filename.)rqr)r6rErs rget_file_for_filenamez"RuntimeLchan.get_file_for_filenames !1133Dzrc|j}||}|j|j\}}||fS)z(Request ACTIVATE FILE of specified file.)rqrrY activate_filer)r6rErr9rrTs rrzRuntimeLchan.activate_filesC!1133 J8))!%00bRxrrlengthoffsetct|jts)td|jd|jjj|j|jj||S)aRead [part of] a transparent EF binary data. Args: length : Amount of data to read (None: as much as possible) offset : Offset into the file from which to read 'length' bytes Returns: binary data read from the file #Only works with TransparentEF, but  is ) rrqr TypeError __class____mro__rY read_binaryr)r6rrs rrzRuntimeLchan.read_binarysq$,m<< t)TM_M_M_MQM_MiMqMqstt tx##D$6$:FFKKKrcl|\}}|j|}||fS)a+Read [part of] a transparent EF binary data and decode it. Args: length : Amount of data to read (None: as much as possible) offset : Offset into the file from which to read 'length' bytes Returns: abstract decode data read from the file )rrq decode_hex)r6rrTdec_datas rread_binary_deczRuntimeLchan.read_binary_decs9%%'' r%0066"~rdata_hexct|jts)td|jd|jjj|j|jj|||j j S)zUpdate transparent EF binary data. Args: data_hex : hex string of data to be written offset : Offset into the file from which to write 'data_hex' rrconserve) rrqrrrrrY update_binaryrrmr4)r6rrs rrzRuntimeLchan.update_binarys}$,m<< t)TM_M_M_MQM_MiMqMqstt tx%%d&8&rs $#"""""""222222222222(((((( N3 N3 N N N NHHHHHHHHVE2E2E2E2E2E2E2E2E2E2r