@ iSodZddlmZmZddlmZmZmZmZddl m Z ddl Tddl Tddl mZejdZded efd ZGd d ZGd dZdS)zHRepresentation of the runtime state of an application like pySim-shell. )OptionalTuple)h2bi2his_hexHexstr)bertlv_parse_one)*) PySimLoggerRUNTIMEclareturnc\|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 CardProfilect||_||_||_i|_t d||jd<i|_d|_|j|jj |jj |jd d|jj D]p}|}| |jrJtd|jd|d|jD]}|j|q|jd d|}|D](}|jr|j|j)|jjD]}|j|d |_|d S) zo Args: card : pysim.cards.Card instance profile : CardProfile instance )r rF)r sel_ctrlMFz Detected z Add-on ""TN)CardMFmfrr lchan RuntimeLchanidentity adm_verifiedset_apdu_parameterr r#selectaddonsprobeloginfo files_in_mfadd_file_match_applicationsadfadd_application_dfconserve_writereset)selfrr addon_clsaddonfappsas r__init__zRuntimeState.__init__,s)))   $Q-- 1  ! $$  4<+@ % B B B 1 T""", ( (IIKKE{{49%% ( eeeLMMM*((AG$$Q'''' 1 T"""'')) 2 2Au 2**15111)  A G  Q    " rc |jj}|sgS|j}g}|rg}td|D]`}|D][}|j|vrPtd|jd|d||||\at|t|z }|D]}td|z nt dtt|t|z tD]} |j |j\}} ||_| dkr?td|jd|j||r#tt f$rYwxYw|S) zEmatch the applications from the profile with applications on the cardz AIDs on card: : z (EF.DIR)z unknown: %s (EF.DIR)zEF.DIR seems to be empty!)key9000)r applicationsr read_aidsr0r1aidnameappendsetwarnsortedstrselect_adf_by_aid selected_adf SwMatchError ProtocolError) r9 apps_profile aids_card apps_taken aids_takenr>r< aids_unknown_datasws rr4z RuntimeState._match_applications]s|0  II''))   2J HH_ % % % - -%--Auzzqvvvqqq!ABBB"))!,,,"))!,,, - y>>C OO;L! 6 60145555 6 HH0 1 1 1L))C OO;EEE  A !I77>> r$%!<<HHH!&&&!%%8999%%a((( -0    s?A.F..GGNrct|jD](}d|j|j_|dkr |j|=)d|_|j}|r|jd|_|jdd|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+rr8r-rOr*)r9cmd_applchan_nratrs rr8zRuntimeState.resets TZ__..// % %H+/DJx $ (1}} 8$$!ioo  * 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(r\rr)r9r`s r add_lchanzRuntimeState.add_lchansR tz(( ( (FQRR R+Hd;; 8z(##rcP||jvr |j|=dSdS)NTF)r(r\rcs r del_lchanzRuntimeState.del_lchans- tz(( ( ( 8$45rctt|}||jvr |j|SdSN)rr(r\)r9r r`s rget_lchan_by_clazRuntimeState.get_lchan_by_clas8$S)) tz(( ( (:h' '4r)rrr r!rh) __name__ __module__ __qualname____doc__r?r4rr8intrdrfrrirrrr)s??////b,,,\V,$#$.$$$$#x'?rrcXeZdZdZdedefdZdeddfdZdefdZ de fdZ de fd Z de fd Zdeefd Zdeefd Zdeefd ZdeefdZdeefdZdefdZdeefdZde defdZde fdZd6de fdZd7deefdZd6defdZd6de fdZdZ de fdZ!de fdZ"d8d!ed"efd#Z#de$ee ffd$Z%d%Z&d&Z'd9d'e d"efd(Z(d)efd*Z)d9d+efd,Z*d9d+ede$ee ffd-Z+d+ed'e fd.Z,d+ed)efd/Z-d9d0efd1Z.d2Z/d0ed'e fd3Z0d6d4Z1d6d5Z2dS):r)z=Represent the runtime state of a logical channel with a card.r`rsc||_||_|jjj||_|jj|_d|_d|_ d|_ dSrh) r`rqr_scc fork_lchanr]r' selected_filerOselected_file_fcpselected_file_fcp_hex)r9r`rqs rr?zRuntimeLchan.__init__sX  7<$//99"WZ !%%)"""rrc|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)rqrdr`get_cwdrurO)r9r` new_lchans rrdzRuntimeLchan.add_lchansGG%%h// =A  &*llnnI #%)%6I "rc(|jddS)Nfile_descriptorfile_descriptor_byte)rvr9s rselected_file_descriptor_bytez*RuntimeLchan.selected_file_descriptor_bytes%&789OPPrc6|dS)N shareablerr~s rselected_file_shareablez$RuntimeLchan.selected_file_shareable1133K@@rc6|dS)N structurerr~s rselected_file_structurez$RuntimeLchan.selected_file_structurerrc6|dS)N file_typerr~s rselected_file_typezRuntimeLchan.selected_file_typerrcB|jddS)Nr| num_of_recrvgetr~s rselected_file_num_of_recz%RuntimeLchan.selected_file_num_of_rec%&78<<\JJJrcB|jddS)Nr| record_lenrr~s rselected_file_record_lenz%RuntimeLchan.selected_file_record_lenrrc6|jdS)N file_sizerr~s rselected_file_sizezRuntimeLchan.selected_file_sizes%))+666rcB|jddS)Nproprietary_informationreserved_file_sizerr~s r selected_file_reserved_file_sizez-RuntimeLchan.selected_file_reserved_file_sizes %&?@DDEYZZZrcB|jddS)Nrmaximum_file_sizerr~s 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 ) isinstanceruCardDFparentr~s rryzRuntimeLchan.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)rurrCardADF)r9nodes rget_application_dfzRuntimeLchan.get_application_dfsM !kT!!$((  ;DkT!!trrHcd|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)splitryget_selectables)r9rHpathlistfilep selectables selectables rget_file_by_namezRuntimeLchan.get_file_by_names $;;zz#H{b  " vH ||~~  A..00KD)   ??&z2DE# |tt rrXcd}|}|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 applicationhasattrrrqr )r9rXresr5apps 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 allowedrBrz - Nr|r}rdfzDF.z)dedicated file, manually added at runtime)rsfidrHdescr transparentzEF.z*elementary file, manually added at runtime)rrunregister_cmdsr] select_filerP _select_postr sw_actual RuntimeErrorrudecode_select_responserrMupper TransparentEF LinFixedEF add_files) r9rr_data_swswmk select_respr<s r probe_filezRuntimeLchan.probe_file<s'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|_||dSrh)rurrrOrwrrv register_cmds)r9r_rselect_resp_datas rrzRuntimeLchan._select_postes  .!%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 )r]N)rrrOhas_fsrqr'ritemsr-rHrubuild_select_path_torrrwrrNrGr]rrrPr) r9rr_r inter_pathrurr<rrs rrzRuntimeLchan.select_filevs$(( 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) rurr-rv Exceptionrrrlowerr)r9rHr_ prev_sel_filerreselss rr-zRuntimeLchan.selectsb*  $;;zz#H{b  "  !,,AKK7++++--     888 !1133 $<< ::<DDcn|j\}}|j|S)z5Request STATUS (current selected file FCP) from card.)r]statusrur)r9rrs rrzRuntimeLchan.statuss.hoo'' s!88>>>rcD|j}||S)z9Get the related CardFile object for a specified filename.)rur)r9rHrs rget_file_for_filenamez"RuntimeLchan.get_file_for_filenames !1133Dzrc|j}||}|j|j\}}||fS)z(Request ACTIVATE FILE of specified file.)rurr] activate_filer)r9rHrr<rrXs 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 ) rrur TypeError __class____mro__r] read_binaryr)r9rrs 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 )rru decode_hex)r9rrXdec_datas rread_binary_deczRuntimeLchan.read_binary_decs9%%'' r%0066"~rc2|j}|sdS|didid}|sdS|dkr|dS|dkr)|didSdS) z Determine the writable size (file or record) using the cached FCP parameters of the currently selected file. Return None in case the writeable size cannot be determined (no FCP available, FCP lacks size information). Nr|r}rrr linear_fixedrr)r9fcprs r__get_writeable_sizez!RuntimeLchan.__get_writeable_sizes $ 4GG-r22667MrRRVVWbcc  4  % %77;'' ' . ( (77,b1155lCC C4rcF|}|sdSt|jtrd}nt|jtrd}nd}||krt d|||||z fz||kr't d|||||z |fzdSdS)zb Guard against unsuccessful writes caused by attempts to write data that exceeds the file limits. Nrrecordobjectz1Data length (%u) exceeds %s size (%u) by %u byteszXData length (%u) less than %s size (%u), leaving %u unwritten bytes at the end of the %s)!_RuntimeLchan__get_writeable_sizerrurrrr0rK)r9data_lenwriteable_sizewriteable_names r__check_writeable_sizez#RuntimeLchan.__check_writeable_sizes2244  F d(- 8 8 &#NN *J 7 7 &%NN%N n $ $O%~~xR`G`abcc c  & & HHoQY@Y[ijk l l l l l' &rdata_hexc<t|jts)td|jd|jjj|t|dz|z|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) rrurrrr#_RuntimeLchan__check_writeable_sizelenr] update_binaryrrqr7)r9rrs rrzRuntimeLchan.update_binary.s$,m<< t)TM_M_M_MQM_MiMqMqstt t ##CMMQ$6$?@@@x%%d&8&r1s/$#"""""""222222222222((((((!!!!!!koi   N3 N3 N N N NLLLLLLLL^p2p2p2p2p2p2p2p2p2p2r