o
    +keN                     @   s6  d dl Z d dlZd dlZd dlZd dlmZmZ d dlZddl	m
Z
mZmZ ddl	mZmZmZmZmZmZmZmZ ddl	mZmZ ddl	mZmZmZmZ ddl	mZ dd	l	mZ dd
lmZ ddlmZ  ddl!mZ ddl!m"Z" ddl!m#Z# ddl!m$Z$ ddl!m%Z% G dd dZ&G dd dZ'G dd dZ(dS )    N)hexlify	unhexlify   )
PassphrasePasswordRetriesExceeded
bin_to_hex)PlaintextKeyPassphraseKeyAuthenticatedKeyRepoKey
KeyfileKeyBlake2KeyfileKeyBlake2RepoKeyBlake2AuthenticatedKey)ID_HMAC_SHA_256ID_BLAKE2b_256)TAMRequiredError
TAMInvalidTAMUnsupportedSuiteErrorUnsupportedManifestError)ArchiveTAMInvalid)identify_key)bytes_to_long)IntegrityError)Location)
StableDict)get_security_dir)msgpackc                	   @   s  e Zd ZG dd dZd ZeedddZ	edZ
d Zed	Zed
Zejdd Zejeeeeeeeefddd ZG dd dZdd Zdd Zdd Zdd Zdd Z dd Z!dd Z"d d! Z#d"d# Z$d$d% Z%d&d' Z&d(d) Z'd*d+ Z(d,d- Z)d.d/ Z*d0S )1TestKeyc                   @   s   e Zd Zee d ZdS )zTestKey.MockArgs   N)__name__
__module____qualname__r   tempfilemkstemplocation r&   r&   6usr/lib/python3.10/site-packages/borg/testsuite/key.pyMockArgs   s    r(   aU  
        BORG_KEY 0000000000000000000000000000000000000000000000000000000000000000
        hqppdGVyYXRpb25zzgABhqCkaGFzaNoAIMyonNI+7Cjv0qHi0AOBM6bLGxACJhfgzVD2oq
        bIS9SFqWFsZ29yaXRobaZzaGEyNTakc2FsdNoAINNK5qqJc1JWSUjACwFEWGTdM7Nd0a5l
        1uBGPEb+9XM9p3ZlcnNpb24BpGRhdGHaANAYDT5yfPpU099oBJwMomsxouKyx/OG4QIXK2
        hQCG2L2L/9PUu4WIuKvGrsXoP7syemujNfcZws5jLp2UPva4PkQhQsrF1RYDEMLh2eF9Ol
        rwtkThq1tnh7KjWMG9Ijt7/aoQtq0zDYP/xaFF8XXSJxiyP5zjH5+spB6RL0oQHvbsliSh
        /cXJq7jrqmrJ1phd6dg4SHAM/i+hubadZoS6m25OQzYAW09wZD/phG8OVa698Z5ed3HTaT
        SmrtgJL3EoOKgUI9d6BLE4dJdBqntifoz\W z
        0055f161493fcfc16276e8c31493c4641e1eb19a79d0326fad0291e5a9c98e5933
        00000000000003e8d21eaf9b86c297a8cd56432e1915bb
        Z@c3fbf14bc001ebcc3cd86e696c13482ed071740927cd7cbe1b01b4bfcee49314ay  
        BORG_KEY 0000000000000000000000000000000000000000000000000000000000000000
        hqlhbGdvcml0aG2mc2hhMjU2pGRhdGHaAZBu680Do3CmfWzeMCwe48KJi3Vps9mEDy7MKF
        TastsEhiAd1RQMuxfZpklkLeddMMWk+aPtFiURRFb02JLXV5cKRC1o2ZDdiNa0nao+o6+i
        gUjjsea9TAu25t3vxh8uQWs5BuKRLBRr0nUgrSd0IYMUgn+iVbLJRzCCssvxsklkwQxN3F
        Y+MvBnn8kUXSeoSoQ2l0fBHzq94Y7LMOm/owMam5URnE8/UEc6ZXBrbyX4EXxDtUqJcs+D
        i451thtlGdigDLpvf9nyK66mjiCpPCTCgtlzq0Pe1jcdhnsUYLg+qWzXZ7e2opEZoC6XxS
        3DIuBOxG3Odqj9IKB+6/kl94vz98awPWFSpYcLZVWu7sIP38ZkUK+ad5MHTo/LvTuZdFnd
        iqKzZIDUJl3Zl1WGmP/0xVOmfIlznkCZy4d3SMuujwIcqQ5kDvwDRPpdhBBk+UWQY5vFXk
        kR1NBNLSTyhAzu3fiUmFl0qZ+UWPRkGAEBy/NuoEibrWwab8BX97cATyvnmOqYkU9PT0C6
        l2l9E4bPpGhhc2jaACDnIa8KgKv84/b5sjaMgSZeIVkuKSLJy2NN8zoH8lnd36ppdGVyYX
        Rpb25zzgABhqCkc2FsdNoAIEJLlLh7q74j3q53856H5GgzA1HH+aW5bA/as544+PGkp3Zl
        cnNpb24BZd04fdf9475cf2323c0ba7a99ddc011064f2e7d039f539f2e4480e6f5fc6ff9993d604040404040404098c8cee1c6db8c28947Z@d8bc68e961c79f99be39061589e5179b2113cd9226e07b08ddd4a1fef7ce93fbc                 C   s   | dt| |S )NZBORG_KEYS_DIR)setenvstr)selfrequestmonkeypatchtmpdirr&   r&   r'   keys_dirF   s   zTestKey.keys_dir)paramsc                 C   s"   | dd |j|  |  S NBORG_PASSPHRASEtest)r*   paramcreateMockRepositoryr(   )r,   r-   r.   r&   r&   r'   keyK   s   zTestKey.keyc                   @   sP   e Zd ZG dd dZe ZedZeeZdd Z	dd Z
dd	 Zd
d ZdS )zTestKey.MockRepositoryc                   @   s   e Zd Zd ZZdd ZdS )z TestKey.MockRepository._Locationz/some/placec                 C      | j S N)	processedr,   r&   r&   r'   canonical_path]      z/TestKey.MockRepository._Location.canonical_pathN)r    r!   r"   rawr;   r=   r&   r&   r&   r'   	_LocationZ   s    r@       c                 C      d S r:   r&   r<   r&   r&   r'   get_free_nonced      z%TestKey.MockRepository.get_free_noncec                 C   rB   r:   r&   )r,   Znext_unreservedZstart_noncer&   r&   r'   commit_nonce_reservationg   rD   z/TestKey.MockRepository.commit_nonce_reservationc                 C   s
   || _ d S r:   Zkey_data)r,   datar&   r&   r'   save_keyj   s   
zTestKey.MockRepository.save_keyc                 C   r9   r:   rF   r<   r&   r&   r'   load_keym   r>   zTestKey.MockRepository.load_keyN)r    r!   r"   r@   Z	_locationbytesidr   id_strrC   rE   rH   rI   r&   r&   r&   r'   r7   Y   s    r7   c                 C   sJ   t d d }d}t||dksJ ||||||ks#J d S )N   foos@   2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae)r   r6   r   id_hashdecryptencrypt)r,   r8   chunkr&   r&   r'   test_plaintextp   s   $zTestKey.test_plaintextc           	      C   s,  | dd t|  |  }|j dksJ |d}|j|dks(J |d}||ks3J |	d ||	d |ksAJ |j|dksKJ |j|}t
|  |}|j ||jt|tj  ksmJ t|j|j|jhdks{J |jdksJ d}||	||||ksJ d S )Nr3   r4   r      ABCr      rM   )r*   r   r6   r7   r(   ciphernext_ivrP   
extract_ivrO   detectblock_countlenZPAYLOAD_OVERHEADid_keyenc_keyenc_hmac_key
chunk_seedrN   )	r,   r.   r0   r8   manifest	manifest2ivkey2rQ   r&   r&   r'   test_keyfilev   s    

($zTestKey.test_keyfilec                 C   s   | dd |  }ttjt|jdd}|d W d    n1 s'w   Y  t	
||  }|d}|j|dksCJ |d |dksMJ d S )Nr3   r4   ZnoncewZ0000000000002000rS   i    )r*   r7   openospathjoinr   rL   writer   r6   r(   rP   rU   rW   rO   )r,   r.   r0   
repositoryfdr8   rG   r&   r&   r'   &test_keyfile_nonce_rollback_protection   s   
z.TestKey.test_keyfile_nonce_rollback_protectionc                 C   s   | d}|dt| |dd | rJ t|  |  }| s)J d}||}|	|}t
|  |}||||ksGJ |  tt t
|  | W d    d S 1 sdw   Y  d S )NkeyfileBORG_KEY_FILEr3   ZtestkfrS   )rh   r*   r+   existsr   r6   r7   r(   rN   rP   rX   rO   removepytestraisesFileNotFoundError)r,   r/   r.   rm   r8   rQ   Zchunk_idZchunk_cdatar&   r&   r'   test_keyfile_kfenv   s   


"zTestKey.test_keyfile_kfenvc                 C   v   | dd}|| j W d    n1 sw   Y  |dd t|  | j}|	| j
| jdks9J d S Nrm   rd   r3   
passphrase   payload)rh   re   ri   keyfile2_key_filer*   r   rX   r7   keyfile2_cdatarO   keyfile2_idr,   r.   r0   rk   r8   r&   r&   r'   test_keyfile2      zTestKey.test_keyfile2c                 C   s   | d}|d}|| j W d    n1 sw   Y  |dt| |dd t|  | j	}|
| j| j	dksCJ d S )Nrm   rd   rn   r3   rw   rx   )rh   re   ri   ry   r*   r+   r   rX   r7   rz   rO   r{   )r,   r/   r.   rm   rk   r8   r&   r&   r'   test_keyfile2_kfenv   s   
zTestKey.test_keyfile2_kfenvc                 C   ru   rv   )rh   re   ri   keyfile_blake2_key_filer*   r   rX   r7   keyfile_blake2_cdatarO   keyfile_blake2_idr|   r&   r&   r'   test_keyfile_blake2   r~   zTestKey.test_keyfile_blake2c           	      C   s  | dd t|  d }|j dksJ t|jdks J t|jdks)J t|j	dks2J |j
dks9J |d}|j|dksHJ |d}||ksSJ |d ||d |ksaJ |j|d	kskJ |j|}t|  |}|j ||jt| ksJ |j|jksJ |j|jksJ |j	|j	ksJ |j
|j
ksJ d
}t||dksJ ||||||ksJ d S )Nr3   r4   r   s@   793b0717f9d8fb01c751a487e9b827897ceea62409870600013fbc6b4d8d7ca6s@   b885a05d329a086627412a6142aaeb9f6c54ab7950f996dd65587251f6bc0901s@   2ff3654c6daf7381dbbe718d2b20b4f1ea1e34caa6cc65f6bb3ac376b93fed2ai#rS   r   rM   s@   818217cf07d37efad3860766dcdf1d21e401650fed2d76ed1d797d3aae925990)r*   r	   r6   r7   rU   rV   r   r[   r]   r\   r^   rP   rW   rO   rX   rY   rZ   rN   )	r,   r0   r.   r8   r_   r`   ra   rb   rQ   r&   r&   r'   test_passphrase   s.   

"$zTestKey.test_passphrasec                 C   sT   t |}||  dN  < tt |d| W d    d S 1 s#w   Y  d S )Nr       )	bytearrayrq   rr   IntegrityErrorBaserO   )r,   r8   rG   offsetr&   r&   r'   _corrupt_byte   s
   "zTestKey._corrupt_bytec                 C   s   | dd}|| j W d    n1 sw   Y  |dd t|  | j}| j}t	t
|D ]	}| ||| q6tt t| j}t||}d|d< ||| W d    d S 1 sgw   Y  d S )Nrm   rd   r3   rw   r      )rh   re   ri   ry   r*   r   rX   r7   rz   rangerZ   r   rq   rr   r   r   rN   rO   )r,   r.   r0   rk   r8   rG   irK   r&   r&   r'   test_decrypt_integrity   s   
"zTestKey.test_decrypt_integrityc                 C   sR   |j }d}||}t|}||jksJ |||}|d |}||ks'J d S )NrM   )rj   rP   r   	__class__rX   rO   )r,   r8   rj   	plaintext	encryptedZidentified_key_classZ
loaded_keyZ	decryptedr&   r&   r'   test_roundtrip   s   
zTestKey.test_roundtripc                 C   s>   d}| |}|jd |dd|ksJ |d ||ksJ d S )N	   123456789F)
decompress)rP   rO   )r,   r8   r   r   r&   r&   r'   test_decrypt_decompress   s   
zTestKey.test_decrypt_decompressc                 C   s   d}| |}||| t|}|d  dN  < tt ||| W d    n1 s/w   Y  |d }tt ||| W d    d S 1 sOw   Y  d S )Nr   r   r      1)rN   Z	assert_idr   rq   rr   r   )r,   r8   r   rK   Z
id_changedZplaintext_changedr&   r&   r'   test_assert_id   s   
"zTestKey.test_assert_idc                 C   d   | dd t|  |  }tjtju sJ t|jdks!J d}|	|}|d| ks0J d S )Nr3   r4   rA   r   s     )
r*   r
   r6   r7   r(   rN   r   rZ   r[   rP   r,   r.   r8   r   Zauthenticatedr&   r&   r'   test_authenticated_encrypt     
z"TestKey.test_authenticated_encryptc                 C   r   )Nr3   r4      r   s     )
r*   r   r6   r7   r(   rN   r   rZ   r[   rP   r   r&   r&   r'   !test_blake2_authenticated_encrypt  r   z)TestKey.test_blake2_authenticated_encryptN)+r    r!   r"   r(   stripry   r   resubrz   r{   r   rJ   fromhexr   r   rq   fixturer0   r   r
   r   r   r   r   r   r8   r7   rR   rc   rl   rt   r}   r   r   r   r   r   r   r   r   r   r   r&   r&   r&   r'   r      sR    


	



	

r   c                   @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
TestPassphrasec                 C   s   | tddd  |dd t  | \}}d|vsJ d|vs%J |dd t }| \}}d|vs;J d|v sAJ |d	ksGJ | tdd
d  t  | \}}d|vs`J d|v sfJ d S )Ngetpassc                 S      dS )N	   12aöäür&   promptr&   r&   r'   <lambda>      zATestPassphrase.test_passphrase_new_verification.<locals>.<lambda>ZBORG_DISPLAY_PASSPHRASEnoZ12yesZ313261c3b6c3a4c3bcr   c                 S   r   )N1234/@=r&   r   r&   r&   r'   r   *  r   r   )setattrr   r*   r   new
readouterr)r,   capsysr.   outerrrw   r&   r&   r'    test_passphrase_new_verification  s"   z/TestPassphrase.test_passphrase_new_verificationc                 C   sp   | dd |tddd  tt tjdd W d    n1 s%w   Y  | \}}d|v s6J d S )Nr3   Fr   c                 S   r   )Nr)   r&   r   r&   r&   r'   r   2  r   z:TestPassphrase.test_passphrase_new_empty.<locals>.<lambda>)Zallow_emptyzmust not be blank)	delenvr   r   rq   rr   r   r   r   r   )r,   r   r.   r   r   r&   r&   r'   test_passphrase_new_empty0  s   z(TestPassphrase.test_passphrase_new_emptyc                    sf   | dd ttd |td fdd tt t	  W d    d S 1 s,w   Y  d S )Nr3   F   r   c                    s   t t S r:   )r+   nextr   Zascending_numbersr&   r'   r   ;  s    z<TestPassphrase.test_passphrase_new_retries.<locals>.<lambda>)
r   iterr   r   r   rq   rr   r   r   r   r,   r.   r&   r   r'   test_passphrase_new_retries8  s   
"z*TestPassphrase.test_passphrase_new_retriesc                 C   s   dt tdvs
J d S )NZsecret)reprr   r<   r&   r&   r'   test_passphrase_repr?  s   z#TestPassphrase.test_passphrase_reprN)r    r!   r"   r   r   r   r   r&   r&   r&   r'   r     s
    r   c                   @   s(  e Zd Zejdd Zdd Zdd Zdd Zd	d
 Z	dd Z
ejdi efddiefdefdeffdd Zejdi efddiefdefdeffdd Zejjdi edfedi fdedfeddffg dddd Zdd Zdd Zejd d!d"d# Zejd d!d$d% ZdS )&TestTAMc                 C   s    | dd tt t S r2   )r*   r   r6   r   r7   r(   r   r&   r&   r'   r8   D  s   zTestTAM.keyc                 C   sx   d}t t || W d    n1 sw   Y  d}t tj || W d    d S 1 s5w   Y  d S )Ns
   foobars   )rq   rr   r   unpack_and_verify_manifestr   ZUnpackExceptionr,   r8   blobr&   r&   r'   test_unpack_futureI  s   "zTestTAM.test_unpack_futurec                 C   sx   t i }tt || W d    n1 sw   Y  tt || W d    d S 1 s5w   Y  d S r:   )r   packbrq   rr   r   r   unpack_and_verify_archiver   r&   r&   r'   test_missing_when_requiredR  s   
"z"TestTAM.test_missing_when_requiredc                 C   sZ   t i }d|_||\}}|i ksJ |rJ ||\}}}|i ks'J |r+J d S )NFr   r   Ztam_requiredr   r   r,   r8   r   unpackedverified_r&   r&   r'   test_missingY  s   
zTestTAM.test_missingc                 C   s   t dddii}tt || W d    n1 sw   Y  tt || W d    d S 1 s9w   Y  d S )NtamtypeHMAC_VOLLBIT)r   r   rq   rr   r   r   r   r   r&   r&   r'   test_unknown_type_when_requiredc  s   "z'TestTAM.test_unknown_type_when_requiredc                 C   sb   t dddii}d|_||\}}|i ksJ |rJ ||\}}}|i ks+J |r/J d S )Nr   r   r   Fr   r   r&   r&   r'   test_unknown_typen  s   zTestTAM.test_unknown_typeztam, excr      Ni  c                 C   H   t d|i}t| || W d    d S 1 sw   Y  d S Nr   )r   r   rq   rr   r   r,   r8   r   excr   r&   r&   r'   test_invalid_manifest|     "zTestTAM.test_invalid_manifestc                 C   r   r   )r   r   rq   rr   r   r   r&   r&   r'   test_invalid_archive  r   zTestTAM.test_invalid_archivez
hmac, salt@   )zed-b64zb64-edzn-b64zb64-n)Zidsc                 C   s   dd||di}|d }|d u r|d= |d u r|d= t |}tt || W d    n1 s4w   Y  tt || W d    d S 1 sOw   Y  d S )Nr   ZHKDF_HMAC_SHA512)r   hmacsaltr   r   )r   r   rq   rr   r   r   r   r   )r,   r8   r   r   rG   r   r   r&   r&   r'   test_wrong_types  s$   
"zTestTAM.test_wrong_typesc                 C   sx   ddi}|j |dd}|dsJ t|}|d d dks!J ||\}}|s,J |d	 d
ks4J d|vs:J d S )Nfoobar   manifestcontext      tam   type   HKDF_HMAC_SHA512rM      bar)pack_and_authenticate_metadata
startswithr   unpackbr   )r,   r8   rG   r   r   r   r&   r&   r'   test_round_trip_manifest  s   
z TestTAM.test_round_trip_manifestc                 C   sz   ddi}|j |dd}|dsJ t|}|d d dks!J ||\}}}|s-J |d	 d
ks5J d|vs;J d S )Nr   r      archiver   r   r   r   r   rM   r   )r   r   r   r   r   )r,   r8   rG   r   r   r   r   r&   r&   r'   test_round_trip_archive  s   
zTestTAM.test_round_trip_archivewhich)s   hmacs   saltc                 C      ddi}|j |dd}|dsJ tj|td}t|d | dks%J |d | d	d
 td
 |d |< t|d | dksCJ t|}t	t
 || W d    d S 1 s^w   Y  d S )Nr   r   r   r   r   object_hookr   r   r   rA   )r   r   r   r   r   rZ   rJ   r   rq   rr   r   r   r,   r8   r   rG   r   r   r&   r&   r'   test_tampered_manifest     $
"zTestTAM.test_tampered_manifestc                 C   r   )Nr   r   r   r   r   r   r   r   r   rA   )r   r   r   r   r   rZ   rJ   r   rq   rr   r   r   r   r&   r&   r'   test_tampered_archive  r   zTestTAM.test_tampered_archive)r    r!   r"   rq   r   r8   r   r   r   r   r   ZmarkZparametrizer   r   r   r   r   rJ   r   r   r   r   r   r&   r&   r&   r'   r   C  sJ    
	










r   ))r   os.pathrf   r   r#   binasciir   r   rq   Z
crypto.keyr   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   Zcrypto.low_levelr   r   r   helpersr   r   r   r   r   r   r   r&   r&   r&   r'   <module>   s0    (  )