jwA dZddlmZmZmZddlmZddlmZm Z ddl m Z ddl Z ddl Z ddlZddlZddlZddlZe jeZgZGddZGd d e jZGd d eZGd deZefdefdZefdeedededeeeffdZefdedededefdZdej fdZ!dej"fdZ#dS)aObtaining card parameters (mostly key data) from external source. This module contains a base class and a concrete implementation of obtaining card key material (or other card-individual parameters) from an external data source. This is used e.g. to keep PIN/PUK data in some file on disk, avoiding the need of manually entering the related card-individual data on every operation with pySim-shell. )ListDictOptional)AES)h2bb2h) PySimLoggerNceZdZdZgdgdgdgdgddZdZed ed efd Zed ed efdZ d efdZ de de d e fdZ de de d e fdZ edejfdZedejd efdZdS)CardKeyFieldCryptora A Card key field encryption class that may be used by Card key provider implementations to add support for a column-based encryption to protect sensitive material (cryptographic key material, ADM keys, etc.). The sensitive material is encrypted using a "key-encryption key", occasionally also known as "transport key" before it is stored into a file or database (see also GSMA FS.28). The "transport key" is then used to decrypt the key material on demand. )UICC_SCP02_KIC1UICC_SCP02_KID1UICC_SCP02_KIK1)UICC_SCP03_KIC1UICC_SCP03_KID1UICC_SCP03_KIK1)SCP03_ENC_ISDRSCP03_MAC_ISDRSCP03_DEK_ISDR)SCP03_ENC_ISDASCP03_MAC_ISDASCP03_DEK_ISDA)SCP03_ENC_ECASDSCP03_MAC_ECASDSCP03_DEK_ECASD) UICC_SCP02 UICC_SCP03 SCP03_ISDR SCP03_ISDA SCP03_ECASDs################dreturnc>d|DS)Nc>i|]\}}||Supper).0kvs M/home/jenkins/jenkins/workspace/simtester-sanitize/pySim/card_key_provider.py z.Gs&555CAaAGGIIa555items)r s r*__dict_keys_to_upperz(CardKeyFieldCryptor.__dict_keys_to_upperEs5517799555 5r,transport_keys crypt_groupscri}|D]\}}||vr||D]}|||<|||< |S)zPApply a single transport key to multiple fields/columns, if the name is a group.r-)r0r1new_dictnamekeyfields r*__process_transport_keysz,CardKeyFieldCryptor.__process_transport_keysIsi'--// % %ID#|##)$/**E&)HUOO*"%r,c||||j|_|jD]%\}}t d|d|&dS)ab Create new field encryptor/decryptor object and set transport keys, usually one for each column. In some cases it is also possible to use a single key for multiple columns (see also __CRYPT_GROUPS) Args: transport_keys : a dict indexed by field name, whose values are hex-encoded AES keys for the respective field (column) of the CSV. This is done so that different fields (columns) can use different transport keys, which is strongly recommended by GSMA FS.28 zEncrypting/decrypting field z using AES key N),_CardKeyFieldCryptor__process_transport_keys(_CardKeyFieldCryptor__dict_keys_to_upper"_CardKeyFieldCryptor__CRYPT_GROUPSr0r.logdebug)selfr0r4r5s r*__init__zCardKeyFieldCryptor.__init__Us#;;Dr@rAciphers r* decrypt_fieldz!CardKeyFieldCryptor.decrypt_fielde{!!T%888 T01A1A1C1CDEEs|UYU^__6>>#m"4"455666r, plaintext_valc8||jvr|Stjt |j|tj|j}t|t |S)a Encrypt a single field. The encryption is only applied if we have a transport key is known under the provided field name, otherwise the field is treated as non sensitive and passed through as it is. Args: field_name : name of the field to decrypt (used to identify which key to use) encrypted_val : encrypted field value Returns: plaintext field value ) r&r0rrCrrDrErencrypt)r>r@rJrGs r* encrypt_fieldz!CardKeyFieldCryptor.encrypt_fieldvrIr, arg_parserc|ddgddd|ddgdtjddS)Nz --column-keyzFIELD:AES_KEY_HEXappendzper-column AES transport key column_key)metavardefaultactionhelpdestz--csv-column-key) add_argumentargparseSUPPRESSrNs r*argparse_add_argsz%CardKeyFieldCryptor.argparse_add_argsst8KUW`h%C,  X X X  2rmr5rns r*getzCardKeyProvider.getr,rNcdS)z Add the commandline arguments relevant for this card key provider. Args: arg_parser : argument parser group Nr$rZs r*r[z!CardKeyProvider.argparse_add_argsrqr,c*t|jS)N)typerb)r>s r*__str__zCardKeyProvider.__str__sDzz""r,N)rbrcrdreabcabstractmethodrrhrrprfrXrir[rur$r,r*rlrlsAA  $s)  #  c  d38n       h&=   \ #####r,rlc |eZdZdZdedefdZdeedededeeeffd Z e d e j fd Z d S) CardKeyProviderCsvzSCard key provider implementation that allows to query against a specified CSV file. csv_filename field_cryptorctd|zt|d|_|jst d|z||_||_dS)z Args: csv_filename : file name (path) of CSV file containing card-individual key/data field_cryptor : (see class CardKeyFieldCryptor) z*Using CSV file as card key data source: %srzCould not open CSV file '%s'N)r<infoopencsv_file RuntimeErrorrzcrypt)r>rzr{s r*r?zCardKeyProviderCsv.__init__s_ = LMMM\3// } N= LMM M(" r,rmr5rnr!c |jdtj|j}|st d|jzd|jD|_||jvrdSi}|D]h}|||krZ|D]W}||vr7|||j |||i=t d|jd|di|ikrdS|S)Nrz+Could not open DictReader for CSV-File '%s'c6g|]}|Sr$r%)r'r6s r* z*CardKeyProviderCsv.get..s BBB5BBBr,z CSV-File 'z' lacks column '') rseekcsv DictReaderrrz fieldnamesupdaterrH)r>rmr5rncr return_dictrowfs r*rpzCardKeyProviderCsv.gets  1 ^DM * * bLtO``aa aBBBMBBB bm # #4  g gC3x5  ggACxx#**Atz/G/G3q6/R/R+STTTT*lPTPaPaPacdcdcd+efff "  4r,rNc8|dddddS)Nz--csvFILEz~/.osmocom/pysim/card_data.csvzRead card data from CSV filerRrSrUrWrZs r*r[z$CardKeyProviderCsv.argparse_add_argss8(H%C  E E E E Er,Nrbrcrdrerhr r?rrrprfrXrir[r$r,r*ryrys]] #S #9L # # # #$s)#cd38n*Eh&=EEE\EEEr,ryc |eZdZdZdedefdZdeedededeeeffd Z e d e j fd Z d S) CardKeyProviderPgsqlzdCard key provider implementation that allows to query against a specified PostgreSQL database table.config_filenamer{c $ddl}td|zt|d5}t j|tj}td|dz|d}|d }|td | |d|d |d |d |_ |d|_ tdt|j z||_ ddddS#1swxYwYdS)z Args: config_filename : file name (path) of CSV file containing card-individual key/data field_cryptor : (see class CardKeyFieldCryptor) rNz.Using SQL database as card key data source: %sr})LoaderzCard key database name: %sdb_namedb_usersreaderz1user for role 'reader' not set up in config file.r4passhost)dbnameuserpasswordr table_nameszCard key database tables: %s)psycopg2r<r~ryamlload FullLoaderrp ValueErrorconnectconntablesrhr)r>rr{rcfgconfigrrs r*r?zCardKeyProviderPgsql.__init__s  AOSTTT /3 ' ' '3Ys4?;;;F HH1FJJy4I4II J J Jzz*--H<<))D| !TUUU (( 90E0E.2hhv.>.>26((62B2B.4jj.@.@)BBDI!**]33DK HH3c$+6F6FF G G G&DJ ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' 'sEFF  F rmr5rnr!c ddl}ddlm}m}d}|jD]}|j|j} | d|f| } | gkrt d|z| f| vr|d ||d } |ddD]>} | |d || z } ?| |d || || z } | | |f| }| |rn|dSt!t#||} | D]3}|j|| || |<4| S) Nr) IdentifierSQLzISELECT column_name FROM information_schema.columns where table_name = %s;zrmr5rnrrr db_resulttcur cols_resultqueryrresultr(s r*rpzCardKeyProviderPgsql.getsI00000000   A I   )""$$C KKcfgei j j j,,..Kb   Z]^^___ ~[00C $$++JJvay7H7H,I,IJJEABBZ C CV++JJqwwyy,A,ABBB SS:;;BB::aggiiCXCXBL*SYY[[BYBY[[ [E KKx ( ( ( I IIKKK    4c&),,-- C CA 00FJJqMMBBF1II r,rNc8|dddddS)Nz--pgsqlrz$~/.osmocom/pysim/card_data_pgsql.cfgz5Read card data from PostgreSQL database (config file)rrrZs r*r[z&CardKeyProviderPgsql.argparse_add_args)s8 6(N%\  ^ ^ ^ ^ ^r,Nrr$r,r*rrsnn''.Gs ( ( (Aaggii ( ( (r,z@Provider list contains element which is not a card data providerz!Searching for card key data (key=z, value=z , provider=)zFound card data: %sz"Unable to find card key data (key=z , fields=)r&rrlrr<r=rhrp)rmr5rnrprs r*card_key_provider_getr;s ))++C ( ( ( ( (F !_-- a_`` ` SVSVSVX]X]X]_bcd_e_e_e_efgggvsE**   II+s6{{; < < <MMM  *UXUXUXZ_Z_Z_adekalalalalm n nnr,r6c|g}t|||t}||S)aQuery all registered card data providers for a single field. Args: field : name valid field such as 'ADM1', 'PIN1', ... which is to be obtained key : look-up key to identify card data, such as 'ICCID' value : value for look-up key to identify card data provider_list : override the list of providers from the global default Returns: dictionary of {field, value} strings for the requested field )rcard_key_providersrpr&)r6r5rnrrmrs r*card_key_provider_get_fieldrTs9WF "637I J JF ::ekkmm $ $$r,rNc|d}t|t|t|dS)zFAdd card key provider commandline options to the given argument parserzCard Key Provider OptionsN)add_argument_groupryr[rr )rNcard_key_groups r*#card_key_provider_argparse_add_argsrdsX223NOON((888**>:::)).99999r,r\c\t|}t|}tjtj|jr?tttj|j|tjtj|j rAtttj|j |dSdS)zOInitialize card key provider depending on the user provided commandline optionsN) r raospathisfile expanduserrrrypgsqlr)r\r0card_key_field_cryptors r*card_key_provider_initrks(AA$GGN0@@ w~~bg((2233m"#5bg6H6H6R6RTj#k#klll w~~bg((4455q"#78J8J4:8V8VXn#o#opppppqqr,)$retypingrrrCryptodome.Cipherr osmocom.utilsrr pySim.logr rrvrloggingrrXrprbr<rr ABCrlryrrlistrhrrrirrjrr$r,r*rs  :('''''''''!!!!!!""""""""!!!!!!  kohoooooooob#####cg###<)E)E)E)E)E)E)E)EVD^D^D^D^D^?D^D^D^LI[ # # # # # #Rdoo$s)o#ocohlmprumuhvoooo2Qc%%s%%S%gj%%%% :H4K::::q!3qqqqqqr,