+
    JV-jb  ã                   ó¤   € ^ RI t ^ RIHu Ht ^ RIHt ^ RIt ! R R]P                  4      t	R R lt
Rt ! R R	]P                  4      tR
 tR tR# )é    N)ÚFileSystemKeyMaterialStorec                   ó6   a € ] tR t^t o RtR tR tR tRtV t	R# )ÚInMemoryKmsClientzJThis is a mock class implementation of KmsClient, built for testing
only.
c                óf   € \         P                  P                  V 4       VP                  V n        R# )z%Create an InMemoryKmsClient instance.N)ÚpeÚ	KmsClientÚ__init__Úcustom_kms_confÚmaster_keys_map)ÚselfÚconfigs   &&Úq/Volumes/fast/ai/experiments/ui-tars-smoke/.venv/lib/python3.14/site-packages/pyarrow/tests/parquet/encryption.pyr	   ÚInMemoryKmsClient.__init__   s"   € ä
�‰×Ñ˜dÔ#Ø%×5Ñ5ˆÖó    c                óš   € V P                   V,          P                  R4      pRP                  W1.4      p\        P                  ! V4      pV# )zXNot a secure cipher - the wrapped key
is just the master key concatenated with key bytesúutf-8r   )r   ÚencodeÚjoinÚbase64Ú	b64encode)r   Ú	key_bytesÚmaster_key_identifierÚmaster_key_bytesÚwrapped_keyÚresults   &&&   r   Úwrap_keyÚInMemoryKmsClient.wrap_key!   sK   € ð  ×/Ñ/Ð0EÕF×MÑMØóÐà—h‘hÐ 0Ð<Ó=ˆÜ×!Ò! +Ó.ˆØˆr   c                óö   € W P                   9  d   \        RV4      hV P                   V,          p\        P                  ! V4      pVR,          pVR,          pW5P	                  R4      8X  d   V# \        RWV4      h)z?Not a secure cipher - just extract the key from
the wrapped keyzUnknown master key:Né   N:r   NNr   zIncorrect master key used)r   Ú
ValueErrorr   Ú	b64decodeÚdecode)r   r   r   Úexpected_master_keyÚdecoded_wrapped_keyr   Údecrypted_keys   &&&    r   Ú
unwrap_keyÚInMemoryKmsClient.unwrap_key*   s�   € ð !×(<Ñ(<Ô<ÜÐ1Ð3HÓIÐIØ"×2Ñ2Ð3HÕIÐÜ$×.Ò.¨{Ó;ÐØ.¨sÕ3ÐØ+¨CÕ0ˆØ×#:Ñ#:¸7Ó#CÔCØ Ð ÜÐ4Ø)ó:ð 	:r   )r   N)
Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r	   r   r&   Ú__static_attributes__Ú__classdictcell__©Ú__classdict__s   @r   r   r      s   ø‡ € ñò6ò
÷:ð :r   r   c                ó\   € V ^8„  d   QhR\         R\        \         \        \        3,          /# )é   r   Úreturn)ÚstrÚtupleÚintÚbytes)Úformats   "r   Ú__annotate__r9   9   s)   € ÷ 
Bñ 
B¤3ð 
B¬5´´c¼5°Õ+Añ 
Br   c                óè   € \         P                  ! R4      pVP                  V 4      ;p'       d9   VP                  4       w  r4p\	        V4      p\
        P                  ! V4      pW4V3# \        RV 4      h)z�Parses a wrapped key string into a tuple: (key id, version, key) given
input in the form: <key id>:v<version>:<bas64 encoded key>z(.+?):v([0-9]+?):(.+)zCannot parse wrapped key)ÚreÚcompileÚ	fullmatchÚgroupsr6   r   r!   r    )r   ÚptnÚmÚidÚversionÚb64keyÚkeys   &      r   Úparse_wrapped_keyrE   9   si   € ô �*Š*Ð,Ó
-€CØ�M‰M˜+Ó&Ð&€qÖ&ØŸh™h›jÑˆ�VÜ�g“,ˆÜ×Ò˜vÓ&ˆØ˜SÐ!Ð!äÐ3°[ÓAÐAr   Úmaster_key_versionc                   óv   a € ] tR t^It o RtV 3R lR lt]V 3R lR l4       tV 3R lR ltV 3R lR	 lt	R
t
V tR# )ÚMockVersioningKmsClientaA  This is a mock class implementation of KmsClient, built for testing
only.

During tests that involve CryptoFactory.rotate_master_keys, separate
instances of this client will be created when writing, rotating keys, and
reading back parquet data. To help unit tests verify that external key
material was stored correctly at each step, this client wraps keys with a
master_key_identifier and a version number. To ensure each client wraps
with the correct version, the current version is persisted in the
key_access_token attribute of the KmsConnectionConfig shared by all clients
c                ó   <€ V ^8„  d   QhRR/# )r2   r3   N© )r8   r0   s   "€r   r9   Ú$MockVersioningKmsClient.__annotate__V   s   ø€ ÷ 3ñ 3¨Tñ 3r   c                óP   € \         P                  P                  V 4       Wn        R # ©N)r   r   r	   Úconnection_config)r   rN   s   &&r   r	   Ú MockVersioningKmsClient.__init__V   s   € Ü
�‰×Ñ˜dÔ#Ø!2Ör   c                ó    <€ V ^8„  d   QhRS[ /# )r2   r3   )r6   )r8   r0   s   "€r   r9   rK   [   s   ø€ ÷ <ñ <¡Cñ <r   c                ó@   € \        V P                  P                  4      # rM   )r6   rN   Úkey_access_token)r   s   &r   rF   Ú*MockVersioningKmsClient.master_key_versionZ   s   € ä�4×)Ñ)×:Ñ:Ó;Ð;r   c                ó,   <€ V ^8„  d   QhRS[ RS[RS[/# )r2   r   r   r3   )r7   r4   )r8   r0   s   "€r   r9   rK   ^   s'   ø€ ÷ Nñ N¡%ð NÁð NÉñ Nr   c                ót   € \         P                  ! V4      P                  R 4      pV RV P                   RV 2# )r   z:vÚ:)r   r   r"   rF   )r   r   r   rC   s   &&& r   r   Ú MockVersioningKmsClient.wrap_key^   s<   € Ü×!Ò! )Ó,×3Ñ3°GÓ<ˆØ'Ð(¨¨4×+BÑ+BÐ*CÀ1ÀVÀHÐMÐMr   c                ó,   <€ V ^8„  d   QhRS[ RS[ RS[/# )r2   r   r   r3   )r4   r7   )r8   r0   s   "€r   r9   rK   b   s)   ø€ ÷ ñ áðñ $'ðñ ,1ñr   c                óF   € \        V4      w  r4pW28w  d   \        R W24      hV# )z"Mismatched master key identifiers:)rE   r    )r   r   r   Úkey_idÚ_rD   s   &&&   r   r&   Ú"MockVersioningKmsClient.unwrap_keyb   s0   € ô +¨;Ó7‰ˆ�3ØÔ*ÜÐAØ#ó<ð <àˆ
r   )rN   N)r(   r)   r*   r+   r,   r	   ÚpropertyrF   r   r&   r-   r.   r/   s   @r   rH   rH   I   s>   ø‡ € ñ
÷3ð 3ð ÷<ó ð<÷Nð N÷ö r   rH   c                óž   € \        V R4      ;_uu_ 4       pVP                  ^4      pVR8X  g   Q h RRR4       R#   + '       g   i     R# ; i)zŽVerify that the file is encrypted by looking at its first 4 bytes.
If it's the magic string PARE
then this is a parquet with encrypted footer.Úrbs   PAREN)ÚopenÚread)ÚpathÚfileÚ	magic_strs   &  r   Úverify_file_encryptedre   m   s=   € ô 
ˆd�D×	Ô	˜TØ—I‘I˜a“Lˆ	à˜GÔ#Ð#Ñ#÷ 
×	×	Ò	ús	   •;»A	c                ó²   € \         P                  ! V 4      p\        4       pVP                  4        F"  pVP	                  V4      pWBVP
                  &   K$  	  V# )z~Reads an external key material store given a parquet file path and
returns a dict mapping master_key_id to KeyMaterial objects)r   Úfor_fileÚdictÚget_key_id_setÚget_key_materialÚmaster_key_id)rb   ÚstoreÚkeysrA   Úkey_materials   &    r   Úread_external_keys_to_dictro   w   sS   € ô '×/Ò/°Ó5€EÜ‹6€DØ×"Ñ"Ö$ˆØ×-Ñ-¨bÓ1ˆØ+7ˆ\×'Ñ'Ó(ñ %ð €Kr   )r   Úpyarrow.parquet.encryptionÚparquetÚ
encryptionr   Úpyarrow._parquet_encryptionr   r;   r   r   rE   ÚMASTER_KEY_VERSIONrH   re   ro   rJ   r   r   Ú<module>ru      sP   ðó" ß 'Ð 'Ý BÛ 	ô:˜Ÿ™ô :õD
Bð *Ð ô!˜bŸl™lô !òH$ôr   