U
    ¸~Hjfk  ã                   @  sþ   d Z ddlmZ ddlZddlZddlZddlZddlmZ ddl	m
Z
 ddlmZ ddlmZmZmZmZmZ ddlmZ dd	lmZ dd
lmZ edƒrÖddlmZmZmZmZmZmZ ddl m!Z!m"Z"m#Z#m$Z$ ndZ%dddœdd„Z&G dd„ deƒZ'dS )z-
Tests for L{twisted.conch.scripts.ckeygen}.
é    )ÚannotationsN)ÚStringIO)ÚCallable)ÚNoReturn)ÚprivateECDSA_opensshÚprivateEd25519_openssh_newÚprivateRSA_opensshÚprivateRSA_openssh_encryptedÚpublicRSA_openssh)ÚFilePath)ÚrequireModule)ÚTestCaseZcryptography)Ú_getKeyOrDefaultÚ_saveKeyÚchangePassPhraseÚdisplayPublicKeyÚenumrepresentationÚprintFingerprint)ÚBadFingerPrintFormatÚBadKeyErrorÚFingerprintFormatsÚKeyz7cryptography required for twisted.conch.scripts.ckeygenÚstrzCallable[[object], str])ÚpassphrasesÚreturnc                    s    t | ƒ‰ dddœ‡ fdd„}|S )a@  
    Return a callable to patch C{getpass.getpass}.  Yields a passphrase each
    time called. Use case is to provide an old, then new passphrase(s) as if
    requested interactively.

    @param passphrases: The list of passphrases returned, one per each call.

    @return: A callable to patch C{getpass.getpass}.
    Úobjectr   )Ú_r   c                   s   t ˆ ƒS ©N)Únext©r   ©ZpassphrasesIter© úC/tmp/pip-unpacked-wheel-ewod1tgb/twisted/conch/test/test_ckeygen.pyÚfakeGetpass<   s    z makeGetpass.<locals>.fakeGetpass)Úiter)r   r#   r!   r    r"   ÚmakeGetpass0   s    
r%   c                   @  sH  e Zd ZdZddœdd„ZdXddddd	œd
d„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Z	ddœdd„Z
ddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœd d!„Zddœd"d#„Zddœd$d%„Zddœd&d'„Zddœd(d)„Zddœd*d+„Zddœd,d-„Zddœd.d/„Zddœd0d1„Zddœd2d3„Zddœd4d5„Zddœd6d7„Zddœd8d9„Zddœd:d;„Zddœd<d=„Zddœd>d?„Zddœd@dA„Z ddœdBdC„Z!ddœdDdE„Z"ddœdFdG„Z#ddœdHdI„Z$ddœdJdK„Z%ddœdLdM„Z&ddœdNdO„Z'ddœdPdQ„Z(ddœdRdS„Z)ddœdTdU„Z*ddœdVdW„Z+dS )YÚKeyGenTestszN
    Tests for various functions used to implement the I{ckeygen} script.
    ÚNone)r   c                 C  s   t ƒ | _|  td| j¡ dS )zX
        Patch C{sys.stdout} so tests can make assertions about what's printed.
        ÚstdoutN)r   r(   ÚpatchÚsys©Úselfr!   r!   r"   ÚsetUpG   s    zKeyGenTests.setUpNr   z
str | None)ÚkeyTypeÚkeySizeÚprivateKeySubtyper   c                 C  sÀ   |   ¡ }dd|d|dg}|d k	r.| d|g¡ |d k	rD| d|g¡ t |¡ t |¡}t |d ¡}|dkr€|  | ¡ d	¡ n.|d
krš|  | ¡ d¡ n|  | ¡ | ¡ ¡ |  	| 
¡ ¡ d S )NÚckeygenú-tú-fz--no-passphrasez-bz--private-key-subtypeú.pubÚecdsaZECÚed25519ZEd25519)ÚmktempÚextendÚ
subprocessÚcallr   ZfromFileÚassertEqualÚtypeÚupperÚ
assertTrueZisPublic)r,   r.   r/   r0   ÚfilenameÚargsZprivKeyÚpubKeyr!   r!   r"   Ú_testrunN   s    

zKeyGenTests._testrunc                 C  sª   |   dd¡ | j dddd� |   d¡ | j ddd� |   d¡ |   dd¡ | j dddd� |   d¡ | j ddd� |   dd¡ | j dddd� |   d¡ | j ddd� d S )	Nr5   Z384Úv1)r0   r6   ZdsaZ2048Úrsa)rB   r+   r!   r!   r"   Útest_keygeneratione   s    



zKeyGenTests.test_keygenerationc              	   C  s8   |   ¡ }|  tj¡� t dddd|g¡ W 5 Q R X d S )Nr1   r2   Zfoor3   )r7   ÚassertRaisesr9   ÚCalledProcessErrorÚ
check_call©r,   r?   r!   r!   r"   Útest_runBadKeytypet   s    zKeyGenTests.test_runBadKeytypec                 C  s"   t ddiƒ}|  |d tj¡ dS )z˜
        L{enumrepresentation} takes a dictionary as input and returns a
        dictionary with its attributes changed to enum representation.
        Úformatúmd5-hexN)r   ÚassertIsr   ZMD5_HEX©r,   Úoptionsr!   r!   r"   Útest_enumrepresentationy   s    z#KeyGenTests.test_enumrepresentationc                 C  s"   t ddiƒ}|  |d tj¡ dS )zF
        Test for format L{FingerprintFormats.SHA256-BASE64}.
        rK   úsha256-base64N)r   rM   r   ZSHA256_BASE64rN   r!   r!   r"   Útest_enumrepresentationsha256�   s    z)KeyGenTests.test_enumrepresentationsha256c              	   C  s:   |   t¡�}tddiƒ W 5 Q R X |  d|jjd ¡ dS )z9
        Test for unsupported fingerprint format
        rK   ú
sha-base64ú*Unsupported fingerprint format: sha-base64r   N)rF   r   r   r;   Ú	exceptionr@   )r,   Úemr!   r!   r"   Ú test_enumrepresentationBadFormatˆ   s     
ÿz,KeyGenTests.test_enumrepresentationBadFormatc                 C  s:   |   ¡ }t|ƒ t¡ t|ddœƒ |  | j ¡ d¡ dS )z¹
        L{printFingerprint} writes a line to standard out giving the number of
        bits of the key, its fingerprint, and the basename of the file from it
        was read.
        rL   ©r?   rK   z:2048 85:25:04:32:58:55:96:9f:57:ee:fb:a8:1a:ea:69:da temp
N©r7   r   Ú
setContentr
   r   r;   r(   ÚgetvaluerI   r!   r!   r"   Útest_printFingerprint’   s    þz!KeyGenTests.test_printFingerprintc                 C  s:   |   ¡ }t|ƒ t¡ t|ddœƒ |  | j ¡ d¡ dS )zŽ
        L{printFigerprint} will print key fingerprint in
        L{FingerprintFormats.SHA256-BASE64} format if explicitly specified.
        rQ   rX   z72048 FBTCOoknq0mHy+kpfnY9tDdcAJuWtCpuQMaV3EsvbUI= temp
NrY   rI   r!   r!   r"   Útest_printFingerprintsha256    s    þz'KeyGenTests.test_printFingerprintsha256c              	   C  sR   |   ¡ }t|ƒ t¡ |  t¡�}t|ddœƒ W 5 Q R X |  d|jj	d ¡ dS )zx
        L{printFigerprint} raises C{keys.BadFingerprintFormat} when unsupported
        formats are requested.
        rS   rX   rT   r   N)
r7   r   rZ   r
   rF   r   r   r;   rU   r@   )r,   r?   rV   r!   r!   r"   Ú)test_printFingerprintBadFingerPrintFormat­   s     
ÿz5KeyGenTests.test_printFingerprintBadFingerPrintFormatc                 C  s>   |   ¡ }t|d ƒ t¡ t|ddœƒ |  | j ¡ d¡ dS )zn
        L{printFingerprint} checks if the filename with the  '.pub' suffix
        exists in ~/.ssh.
        r4   rL   rX   z>2048 85:25:04:32:58:55:96:9f:57:ee:fb:a8:1a:ea:69:da temp.pub
NrY   rI   r!   r!   r"   Ú#test_printFingerprintSuffixAppendedº   s    þz/KeyGenTests.test_printFingerprintSuffixAppendedc                 C  sš   t |  ¡ ƒ}| ¡  | d¡j}t t¡}t||dddœƒ |  	| j
 ¡ d||f ¡ |  	| | d¡ ¡ dd¡|¡ |  	t | d¡ ¡ ¡| ¡ ¡ dS )z–
        L{_saveKey} writes the private and public parts of a key to two
        different files and writes a report of this to standard out.
        Úid_rsaÚ
passphraserL   ©r?   ÚpassrK   úºYour identification has been saved in %s
Your public key has been saved in %s.pub
The key fingerprint in <FingerprintFormats=MD5_HEX> is:
85:25:04:32:58:55:96:9f:57:ee:fb:a8:1a:ea:69:da
Nú
id_rsa.pub©r   r7   ÚmakedirsÚchildÚpathr   Ú
fromStringr   r   r;   r(   r[   Ú
getContentÚpublic©r,   Úbaser?   Úkeyr!   r!   r"   Útest_saveKeyÇ   s&    
ýþ ÿ ÿzKeyGenTests.test_saveKeyc                 C  sš   t |  ¡ ƒ}| ¡  | d¡j}t t¡}t||dddœƒ |  	| j
 ¡ d||f ¡ |  	| | d¡ ¡ dd¡|¡ |  	t | d¡ ¡ ¡| ¡ ¡ dS )z³
        L{_saveKey} writes the private and public parts of a key to two
        different files and writes a report of this to standard out.
        Test with ECDSA key.
        Úid_ecdsara   rL   rb   zºYour identification has been saved in %s
Your public key has been saved in %s.pub
The key fingerprint in <FingerprintFormats=MD5_HEX> is:
1e:ab:83:a6:f2:04:22:99:7c:64:14:d2:ab:fa:f5:16
Nzid_ecdsa.pub)r   r7   rg   rh   ri   r   rj   r   r   r;   r(   r[   rk   rl   rm   r!   r!   r"   Útest_saveKeyECDSAß   s&    
ýþ ÿ ÿzKeyGenTests.test_saveKeyECDSAc                 C  sš   t |  ¡ ƒ}| ¡  | d¡j}t t¡}t||dddœƒ |  	| j
 ¡ d||f ¡ |  	| | d¡ ¡ dd¡|¡ |  	t | d¡ ¡ ¡| ¡ ¡ dS )zµ
        L{_saveKey} writes the private and public parts of a key to two
        different files and writes a report of this to standard out.
        Test with Ed25519 key.
        Ú
id_ed25519ra   rL   rb   zºYour identification has been saved in %s
Your public key has been saved in %s.pub
The key fingerprint in <FingerprintFormats=MD5_HEX> is:
ab:ee:c8:ed:e5:01:1b:45:b7:8d:b2:f0:8f:61:1c:14
Nzid_ed25519.pub)r   r7   rg   rh   ri   r   rj   r   r   r;   r(   r[   rk   rl   rm   r!   r!   r"   Útest_saveKeyEd25519ø   s&    
ýþþ ÿzKeyGenTests.test_saveKeyEd25519c                 C  sš   t |  ¡ ƒ}| ¡  | d¡j}t t¡}t||dddœƒ |  	| j
 ¡ d||f ¡ |  	| | d¡ ¡ dd¡|¡ |  	t | d¡ ¡ ¡| ¡ ¡ dS )zŠ
        L{_saveKey} will generate key fingerprint in
        L{FingerprintFormats.SHA256-BASE64} format if explicitly specified.
        r`   ra   rQ   rb   z½Your identification has been saved in %s
Your public key has been saved in %s.pub
The key fingerprint in <FingerprintFormats=SHA256_BASE64> is:
FBTCOoknq0mHy+kpfnY9tDdcAJuWtCpuQMaV3EsvbUI=
Nre   rf   rm   r!   r!   r"   Útest_saveKeysha256  s,    
 
ÿýþ ÿ ÿzKeyGenTests.test_saveKeysha256c              	   C  sj   t |  ¡ ƒ}| ¡  | d¡j}t t¡}|  t	¡�}t
||dddœƒ W 5 Q R X |  d|jjd ¡ dS )zq
        L{_saveKey} raises C{keys.BadFingerprintFormat} when unsupported
        formats are requested.
        r`   ra   rS   rb   rT   r   N)r   r7   rg   rh   ri   r   rj   r   rF   r   r   r;   rU   r@   )r,   rn   r?   ro   rV   r!   r!   r"   Ú test_saveKeyBadFingerPrintformat,  s    

þ 
ÿz,KeyGenTests.test_saveKeyBadFingerPrintformatc                 C  s`   t |  ¡ ƒ}| ¡  | d¡j}t t¡}t||dddœƒ |  	| | d¡ 
¡ dd¡|¡ dS )úq
        L{_saveKey} will choose an empty string for the passphrase if
        no-passphrase is C{True}.
        r`   TrL   ©r?   zno-passphraserK   Nó    )r   r7   rg   rh   ri   r   rj   r   r   r;   rk   rm   r!   r!   r"   Útest_saveKeyEmptyPassphrase>  s    
 
ÿ ÿz'KeyGenTests.test_saveKeyEmptyPassphrasec                 C  s^   t |  ¡ ƒ}| ¡  | d¡j}t t¡}t||dddœƒ |  	| | d¡ 
¡ d¡|¡ dS )rw   rq   TrL   rx   N)r   r7   rg   rh   ri   r   rj   r   r   r;   rk   rm   r!   r!   r"   Ú test_saveKeyECDSAEmptyPassphraseN  s    
 
ÿz,KeyGenTests.test_saveKeyECDSAEmptyPassphrasec                 C  s^   t |  ¡ ƒ}| ¡  | d¡j}t t¡}t||dddœƒ |  	| | d¡ 
¡ d¡|¡ dS )rw   rs   TrL   rx   N)r   r7   rg   rh   ri   r   rj   r   r   r;   rk   rm   r!   r!   r"   Ú"test_saveKeyEd25519EmptyPassphrase\  s    
 
ÿ ÿz.KeyGenTests.test_saveKeyEd25519EmptyPassphrasec                   s¦   t |  ¡ ƒ}| ¡  | d¡j‰g ‰ ddl}dddœ‡ fdd„}|  |jjj	d	‡fd
d„¡ t
 t¡}t|ddddœ|ƒ | d¡ ¡ }| |dd¡}|  ||¡ dS )zd
        When no path is specified, it will ask for the path used to store the
        key.
        Ú
custom_keyr   Nr   r   ©r@   r   c                    s   ˆ   d¡ dS ©NÚ ©Úappend©r@   ©Úinput_promptsr!   r"   Ú
mock_inputx  s    
z6KeyGenTests.test_saveKeyNoFilename.<locals>.mock_inputZ_inputSaveFilec                   s   ˆ S r   r!   r   )ÚkeyPathr!   r"   Ú<lambda>|  ry   z4KeyGenTests.test_saveKeyNoFilename.<locals>.<lambda>TrL   rx   ry   )r   r7   rg   rh   ri   Útwisted.conch.scripts.ckeygenr)   ZconchÚscriptsr1   r   rj   r   r   rk   r;   )r,   rn   Ztwistedr†   ro   ZpersistedKeyContentZpersistedKeyr!   )r…   r‡   r"   Útest_saveKeyNoFilenamel  s     

ýz"KeyGenTests.test_saveKeyNoFilenamec                 C  sp   dddœdd„}t |  ¡ ƒ}| ¡  | d¡j}|  tjddd	„ ¡ t t	¡}|d
ddœ}|  
tt|||¡ dS )zs
        When the specified file exists, it will ask the user for confirmation
        before overwriting.
        r   z	list[str]r~   c                  W  s   dgS )NÚnr!   rƒ   r!   r!   r"   r†   Ž  s    z6KeyGenTests.test_saveKeyFileExists.<locals>.mock_inputr}   Úexistsc                 S  s   dS )NTr!   r   r!   r!   r"   rˆ   •  ry   z4KeyGenTests.test_saveKeyFileExists.<locals>.<lambda>TrL   rx   N)r   r7   rg   rh   ri   r)   Úosr   rj   r   rF   Ú
SystemExitr   )r,   r†   rn   r‡   ro   rO   r!   r!   r"   Útest_saveKeyFileExistsˆ  s    
z"KeyGenTests.test_saveKeyFileExistsc                 C  s°   t |  ¡ ƒ}| ¡  | d¡j}t t¡}t||ddddœƒ |  	| j
 ¡ d||f ¡ | d¡ ¡ }|  	| |dd¡|¡ |  | d¡¡ |  	t | d	¡ ¡ ¡| ¡ ¡ dS )
zi
        L{_saveKey} can be told to write the new private key file in OpenSSH
        v1 format.
        r`   ra   rL   rC   )r?   rc   rK   úprivate-key-subtyperd   Nó$   -----BEGIN OPENSSH PRIVATE KEY-----
re   )r   r7   rg   rh   ri   r   rj   r   r   r;   r(   r[   rk   r>   Ú
startswithrl   )r,   rn   r?   ro   ÚprivateKeyContentr!   r!   r"   Útest_saveKeySubtypeV1š  s6    
üþ	ýþÿ ÿz!KeyGenTests.test_saveKeySubtypeV1c                 C  sX   |   ¡ }t t¡}t|ƒ t¡ td|iƒ | j 	¡  
d¡ d¡}|  || d¡¡ dS )zl
        L{displayPublicKey} prints out the public key associated with a given
        private key.
        r?   Ú
ÚasciiÚopensshN)r7   r   rj   r
   r   rZ   r   r   r(   r[   ÚstripÚencoder;   ÚtoString©r,   r?   rA   Z	displayedr!   r!   r"   Útest_displayPublicKey¼  s    
z!KeyGenTests.test_displayPublicKeyc                 C  sZ   |   ¡ }t t¡}t|ƒ t¡ t|ddœƒ | j 	¡  
d¡ d¡}|  || d¡¡ dS )z›
        L{displayPublicKey} prints out the public key associated with a given
        private key using the given passphrase when it's encrypted.
        Ú	encrypted©r?   rc   r–   r—   r˜   N)r7   r   rj   r
   r   rZ   r	   r   r(   r[   r™   rš   r;   r›   rœ   r!   r!   r"   Útest_displayPublicKeyEncryptedÈ  s    
z*KeyGenTests.test_displayPublicKeyEncryptedc                 C  sj   |   ¡ }t t¡}t|ƒ t¡ |  tddd„ ¡ t	d|iƒ | j
 ¡  d¡ d¡}|  || d¡¡ dS )	z›
        L{displayPublicKey} prints out the public key associated with a given
        private key, asking for the passphrase when it's encrypted.
        Úgetpassc                 S  s   dS )Nrž   r!   )Úxr!   r!   r"   rˆ   Ü  ry   zLKeyGenTests.test_displayPublicKeyEncryptedPassphrasePrompt.<locals>.<lambda>r?   r–   r—   r˜   N)r7   r   rj   r
   r   rZ   r	   r)   r¡   r   r(   r[   r™   rš   r;   r›   rœ   r!   r!   r"   Ú.test_displayPublicKeyEncryptedPassphrasePromptÔ  s    
z:KeyGenTests.test_displayPublicKeyEncryptedPassphrasePromptc                 C  s.   |   ¡ }t|ƒ t¡ |  tt|ddœ¡ dS )zŠ
        L{displayPublicKey} fails with a L{BadKeyError} when trying to decrypt
        an encrypted key with the wrong password.
        ÚwrongrŸ   N)r7   r   rZ   r	   rF   r   r   rI   r!   r!   r"   Ú$test_displayPublicKeyWrongPassphraseá  s      ÿz0KeyGenTests.test_displayPublicKeyWrongPassphrasec                 C  sl   t dddƒ}|  td|¡ |  ¡ }t|ƒ t¡ td|iƒ |  | j	 
¡  d¡d¡ |  tt|ƒ ¡ ¡ dS )zt
        L{changePassPhrase} allows a user to change the passphrase of a
        private key interactively.
        rž   Únewpassr¡   r?   r–   ú;Your identification has been saved with the new passphrase.N©r%   r)   r¡   r7   r   rZ   r	   r   r;   r(   r[   r™   ÚassertNotEqualrk   )r,   ÚoldNewConfirmr?   r!   r!   r"   Útest_changePassphraseì  s    þ 
ÿz!KeyGenTests.test_changePassphrasec                 C  sl   t ddƒ}|  td|¡ |  ¡ }t|ƒ t¡ t|ddœƒ |  | j	 
¡  d¡d¡ |  tt|ƒ ¡ ¡ dS )zž
        L{changePassPhrase} allows a user to change the passphrase of a
        private key, providing the old passphrase and prompting for new one.
        r¦   r¡   rž   rŸ   r–   r§   Nr¨   )r,   Z
newConfirmr?   r!   r!   r"   Útest_changePassphraseWithOld   s    
þ 
ÿz(KeyGenTests.test_changePassphraseWithOldc                 C  sV   |   ¡ }t|ƒ t¡ t|dddœƒ |  | j ¡  d¡d¡ |  	tt|ƒ 
¡ ¡ dS )z¢
        L{changePassPhrase} allows a user to change the passphrase of a private
        key by providing both old and new passphrases without prompting.
        rž   Ú
newencrypt)r?   rc   r¦   r–   r§   N)r7   r   rZ   r	   r   r;   r(   r[   r™   r©   rk   rI   r!   r!   r"   Útest_changePassphraseWithBoth  s    
ÿþ 
ÿz)KeyGenTests.test_changePassphraseWithBothc                 C  sR   |   ¡ }t|ƒ t¡ |  tt|ddœ¡}|  dt|ƒ¡ |  tt|ƒ 	¡ ¡ dS )zŽ
        L{changePassPhrase} exits if passed an invalid old passphrase when
        trying to change the passphrase of a private key.
        r¤   rŸ   z1Could not change passphrase: old passphrase errorN)
r7   r   rZ   r	   rF   r�   r   r;   r   rk   ©r,   r?   Úerrorr!   r!   r"   Ú$test_changePassphraseWrongPassphrase'  s      ÿ ÿz0KeyGenTests.test_changePassphraseWrongPassphrasec                 C  sb   |   tdtdƒ¡ |  ¡ }t|ƒ t¡ |  tt	d|i¡}|  
dt|ƒ¡ |  
tt|ƒ ¡ ¡ dS )zƒ
        L{changePassPhrase} exits if no passphrase is specified for the
        C{getpass} call and the key is encrypted.
        r¡   r€   r?   zMCould not change passphrase: Passphrase must be provided for an encrypted keyN)r)   r¡   r%   r7   r   rZ   r	   rF   r�   r   r;   r   rk   r¯   r!   r!   r"   Ú!test_changePassphraseEmptyGetPass6  s    ýz-KeyGenTests.test_changePassphraseEmptyGetPassc                 C  sT   |   ¡ }t|ƒ d¡ |  ttd|i¡}d}|  |t|ƒ¡ |  dt|ƒ ¡ ¡ dS )zc
        L{changePassPhrase} exits if the file specified points to an invalid
        key.
        s   foobarr?   z?Could not change passphrase: cannot guess the type of b'foobar'N)	r7   r   rZ   rF   r�   r   r;   r   rk   )r,   r?   r°   Úexpectedr!   r!   r"   Útest_changePassphraseBadKeyF  s    z'KeyGenTests.test_changePassphraseBadKeyc                 C  sr   |   ¡ }t|ƒ t¡ ddddœdd„}|  td|¡ |  tt|ddœ¡}|  	d	t
|ƒ¡ |  	tt|ƒ ¡ ¡ d
S )zŸ
        L{changePassPhrase} doesn't modify the key file if an unexpected error
        happens when trying to create the key with the new passphrase.
        r   r   ©r@   Úkwargsr   c                  _  s   t dƒ‚d S )NZoops)ÚRuntimeError©r@   r¶   r!   r!   r"   r›   [  s    z>KeyGenTests.test_changePassphraseCreateError.<locals>.toStringr›   r­   ©r?   r¦   z!Could not change passphrase: oopsN©r7   r   rZ   r   r)   r   rF   r�   r   r;   r   rk   )r,   r?   r›   r°   r!   r!   r"   Ú test_changePassphraseCreateErrorS  s    ýz,KeyGenTests.test_changePassphraseCreateErrorc                 C  sv   |   ¡ }t|ƒ t¡ ddddœdd„}|  td|¡ |  tt|ddœ¡}d	}|  	|t
|ƒ¡ |  	tt|ƒ ¡ ¡ d
S )zq
        L{changePassPhrase} doesn't modify the key file if C{toString} returns
        an empty string.
        r   r   rµ   c                  _  s   dS r   r!   r¸   r!   r!   r"   r›   r  s    zCKeyGenTests.test_changePassphraseEmptyStringError.<locals>.toStringr›   r­   r¹   z9Could not change passphrase: cannot guess the type of b''Nrº   )r,   r?   r›   r°   r³   r!   r!   r"   Ú%test_changePassphraseEmptyStringErrorj  s    ýz1KeyGenTests.test_changePassphraseEmptyStringErrorc                 C  sR   |   ¡ }t|ƒ t¡ |  tt|ddœ¡}|  dt|ƒ¡ |  tt|ƒ 	¡ ¡ dS )z†
        L{changePassPhrase} exits when trying to change the passphrase on a
        public key, and doesn't change the file.
        rc   r¹   z.Could not change passphrase: key not encryptedN)
r7   r   rZ   r
   rF   r�   r   r;   r   rk   r¯   r!   r!   r"   Útest_changePassphrasePublicKey‚  s      ÿz*KeyGenTests.test_changePassphrasePublicKeyc                 C  s‚   t dddƒ}|  td|¡ |  ¡ }t|ƒ t¡ t|ddœƒ |  | j	 
¡  d¡d¡ t|ƒ ¡ }|  t|¡ |  | d¡¡ d	S )
zq
        L{changePassPhrase} can be told to write the new private key file in
        OpenSSH v1 format.
        rž   r¦   r¡   rC   )r?   r‘   r–   r§   r’   N)r%   r)   r¡   r7   r   rZ   r	   r   r;   r(   r[   r™   rk   r©   r>   r“   )r,   rª   r?   r”   r!   r!   r"   Útest_changePassphraseSubtypeV1�  s    þÿz*KeyGenTests.test_changePassphraseSubtypeV1c                   sv   g ‰ dddœ‡ fdd„}ddi}t ||ƒ}|  |d d¡ |  | tj dd	¡¡¡ |  d
tˆ ƒ¡ |  dgˆ ¡ dS )zg
        L{options} will default to "~/.ssh/id_rsa" if the user doesn't
        specify a key.
        r   r   r~   c                    s   ˆ   d¡ dS r   r�   rƒ   r„   r!   r"   r†   ¬  s    
z5KeyGenTests.test_useDefaultForKey.<locals>.mock_inputr?   r€   z.sshr`   é   N)r   r;   r>   ÚendswithrŽ   ri   ÚjoinÚlen)r,   r†   rO   r?   r!   r„   r"   Útest_useDefaultForKey¥  s    
þz!KeyGenTests.test_useDefaultForKeyc                 C  s,   ddi}|   tt|¡}|  d|jd ¡ dS )z‹
        Ensure FileNotFoundError is handled, whether the user has supplied
        a bad path, or has no key at the default path.
        r?   ú/foo/barú+could not be opened, please specify a file.r   N)rF   r�   r   ÚassertInr@   ©r,   rO   Úexcr!   r!   r"   Ú'test_displayPublicKeyHandleFileNotFound¾  s    z3KeyGenTests.test_displayPublicKeyHandleFileNotFoundc                 C  s,   ddi}|   tt|¡}|  d|jd ¡ dS )úN
        Ensure FileNotFoundError is handled for an invalid filename.
        r?   rÄ   rÅ   r   N)rF   r�   r   rÆ   r@   rÇ   r!   r!   r"   Ú'test_changePassPhraseHandleFileNotFoundÇ  s    z3KeyGenTests.test_changePassPhraseHandleFileNotFoundc                 C  s.   dddœ}|   tt|¡}|  d|jd ¡ dS )rÊ   rÄ   rL   rX   rÅ   r   N)rF   r�   r   rÆ   r@   rÇ   r!   r!   r"   Ú'test_printFingerprintHandleFileNotFoundÏ  s    
z3KeyGenTests.test_printFingerprintHandleFileNotFound)NN),Ú__name__Ú
__module__Ú__qualname__Ú__doc__r-   rB   rE   rJ   rP   rR   rW   r\   r]   r^   r_   rp   rr   rt   ru   rv   rz   r{   r|   r‹   r�   r•   r�   r    r£   r¥   r«   r¬   r®   r±   r²   r´   r»   r¼   r½   r¾   rÃ   rÉ   rË   rÌ   r!   r!   r!   r"   r&   B   sV   
  ü
"	r&   )(rÐ   Ú
__future__r   r¡   rŽ   r9   r*   Úior   Útypingr   Ztyping_extensionsr   Ztwisted.conch.test.keydatar   r   r   r	   r
   Ztwisted.python.filepathr   Ztwisted.python.reflectr   Ztwisted.trial.unittestr   r‰   r   r   r   r   r   r   Ztwisted.conch.ssh.keysr   r   r   r   Úskipr%   r&   r!   r!   r!   r"   Ú<module>   s$    