Ë
    oj-m  ã                  ó  — 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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„Z% G d„ de«      Z&y)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)ÚTestCaseÚcryptography)Ú_getKeyOrDefaultÚ_saveKeyÚchangePassPhraseÚdisplayPublicKeyÚenumrepresentationÚprintFingerprint)ÚBadFingerPrintFormatÚBadKeyErrorÚFingerprintFormatsÚKeyz7cryptography required for twisted.conch.scripts.ckeygenc                 ó*   ‡— t        | «      Šdˆf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}.
    c                ó   •— t        ‰«      S ©N)Únext)Ú_ÚpassphrasesIters    €úA/usr/lib/python3/dist-packages/twisted/conch/test/test_ckeygen.pyÚfakeGetpassz makeGetpass.<locals>.fakeGetpass=   s   ø€ Ü�OÓ$Ð$ó    )r   ÚobjectÚreturnÚstr)Úiter)Úpassphrasesr!   r   s     @r    ÚmakeGetpassr(   1   s   ø€ ô ˜;Ó'€Oõ%ð Ðr"   c                  ód  — e Zd ZdZd+d„Z	 	 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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$d+d$„Z%d+d%„Z&d+d&„Z'd+d'„Z(d+d(„Z)d+d)„Z*d+d*„Z+y).ÚKeyGenTestszN
    Tests for various functions used to implement the I{ckeygen} script.
    c                ód   — t        «       | _        | j                  t        d| j                  «       y)zX
        Patch C{sys.stdout} so tests can make assertions about what's printed.
        ÚstdoutN)r   r,   ÚpatchÚsys©Úselfs    r    ÚsetUpzKeyGenTests.setUpH   s!   € ô “jˆŒØ�
‰
”3˜ $§+¡+Õ.r"   Nc                ó’  — | j                  «       }dd|d|dg}|�|j                  d|g«       |�|j                  d|g«       	 t        j                  |«       t        j                  |«      }t        j                  |d	z   «      }|d
k(  r!| j                  |j                  «       d«       nT|dk(  r!| j                  |j                  «       d«       n.| j                  |j                  «       |j                  «       «       | j                  |j                  «       «       y # t        $ r d|d<   t        j                  |«       Y Œìw xY w)NÚckeygenú-tú-fz--no-passphrasez-bz--private-key-subtypeÚckeygen3r   ú.pubÚecdsaÚECÚed25519ÚEd25519)ÚmktempÚextendÚ
subprocessÚcallÚFileNotFoundErrorr   ÚfromFileÚassertEqualÚtypeÚupperÚ
assertTrueÚisPublic)r0   ÚkeyTypeÚkeySizeÚprivateKeySubtypeÚfilenameÚargsÚprivKeyÚpubKeys           r    Ú_testrunzKeyGenTests._testrunO   s  € ð —;‘;“=ˆØ˜4 ¨$°Ð:KÐLˆØÐØ�K‰K˜˜w˜Ô(ØÐ(Ø�K‰KÐ0Ð2CÐDÔEð	"Ü�O‰O˜DÔ!ô —,‘,˜xÓ(ˆÜ—‘˜h¨Ñ/Ó0ˆØ�gÒØ×Ñ˜WŸ\™\›^¨TÕ2Ø˜	Ò!Ø×Ñ˜WŸ\™\›^¨YÕ7à×Ñ˜WŸ\™\›^¨W¯]©]«_Ô=Ø�‰˜Ÿ™Ó)Õ*øô !ò 	"Ø ˆD�‰GÜ�O‰O˜DÖ!ð	"ús   ÁD  Ä #EÅEc                óâ  — | j                  dd«       | j                  ddd¬«       | j                  d«       | j                  dd¬«       | j                  d«       | j                  dd«       | j                  ddd¬«       | j                  d«       | j                  dd¬«       | j                  dd«       | j                  ddd¬«       | j                  d«       | j                  dd¬«       y )	Nr8   Ú384Úv1)rI   r:   ÚdsaÚ2048Úrsa)rN   r/   s    r    Útest_keygenerationzKeyGenTests.test_keygenerationj   sÂ   € Ø�‰�g˜uÔ%Ø�‰�g˜u¸ˆÔ=Ø�‰�gÔØ�‰�g°ˆÔ6Ø�‰�iÔ Ø�‰�e˜VÔ$Ø�‰�e˜V°tˆÔ<Ø�‰�eÔØ�‰�e¨tˆÔ4Ø�‰�e˜VÔ$Ø�‰�e˜V°tˆÔ<Ø�‰�eÔØ�‰�e¨tˆÕ4r"   c           
     óz  — | j                  «       }| j                  t        j                  «      5  t	        t
        j                  d«      5 }	 t        j                  dddd|g|¬«       d d d «       d d d «       y # t        $ r t        j                  dddd|g|¬«       Y Œ8w xY w# 1 sw Y   Œ=xY w# 1 sw Y   y xY w)NÚrbr3   r4   Úfoor5   )Ústderrr6   )	r<   ÚassertRaisesr>   ÚCalledProcessErrorÚopenÚosÚdevnullÚ
check_callr@   )r0   rJ   r^   s      r    Útest_runBadKeytypezKeyGenTests.test_runBadKeytypey   s´   € Ø—;‘;“=ˆØ×Ñœz×<Ñ<Ó=ñ 		(Ü”b—j‘j $Ó'ð (¨7ð(Ü×)Ñ)Ø" D¨%°°xÐ@Ø&õ(÷(÷		(ð 		(øô )ò (Ü×)Ñ)Ø# T¨5°$¸ÐAØ&÷(ð(ú÷(ð (ú÷		(ð 		(úsA   °B1ÁB%ÁA:Á)B1Á:%B"ÂB%Â!B"Â"B%Â%B.	Â*B1Â1B:c                ód   — t        ddi«      }| j                  |d   t        j                  «       y)z˜
        L{enumrepresentation} takes a dictionary as input and returns a
        dictionary with its attributes changed to enum representation.
        Úformatúmd5-hexN)r   ÚassertIsr   ÚMD5_HEX©r0   Úoptionss     r    Útest_enumrepresentationz#KeyGenTests.test_enumrepresentation†   s-   € ô
 % h°	Ð%:Ó;ˆØ�‰�g˜hÑ'Ô);×)CÑ)CÕDr"   c                ód   — t        ddi«      }| j                  |d   t        j                  «       y)zF
        Test for format L{FingerprintFormats.SHA256-BASE64}.
        rb   úsha256-base64N)r   rd   r   ÚSHA256_BASE64rf   s     r    Útest_enumrepresentationsha256z)KeyGenTests.test_enumrepresentationsha256Ž   s-   € ô % h°Ð%@ÓAˆØ�‰�g˜hÑ'Ô);×)IÑ)IÕJr"   c                óÄ   — | j                  t        «      5 }t        ddi«       ddd«       | j                  dj                  j
                  d   «       y# 1 sw Y   Œ3xY w)z9
        Test for unsupported fingerprint format
        rb   ú
sha-base64Nú*Unsupported fingerprint format: sha-base64r   )rZ   r   r   rB   Ú	exceptionrK   )r0   Úems     r    Ú test_enumrepresentationBadFormatz,KeyGenTests.test_enumrepresentationBadFormat•   sY   € ð ×ÑÔ3Ó4ð 	9¸Ü ¨,Ð7Ô8÷	9à×ÑØ8¸"¿,¹,×:KÑ:KÈAÑ:Nõ	
÷	9ð 	9ús   –AÁAc                óÐ   — | j                  «       }t        |«      j                  t        «       t	        |ddœ«       | j                  | j                  j                  «       d«       y)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.
        rc   ©rJ   rb   z:2048 85:25:04:32:58:55:96:9f:57:ee:fb:a8:1a:ea:69:da temp
N©r<   r   Ú
setContentr   r   rB   r,   Úgetvalue©r0   rJ   s     r    Útest_printFingerprintz!KeyGenTests.test_printFingerprintŸ   sQ   € ð —;‘;“=ˆÜ�Ó×%Ñ%Ô&7Ô8Ü h¸)ÑDÔEØ×ÑØ�K‰K× Ñ Ó"ØIõ	
r"   c                óÐ   — | j                  «       }t        |«      j                  t        «       t	        |ddœ«       | j                  | j                  j                  «       d«       y)zŽ
        L{printFigerprint} will print key fingerprint in
        L{FingerprintFormats.SHA256-BASE64} format if explicitly specified.
        rj   rt   z72048 FBTCOoknq0mHy+kpfnY9tDdcAJuWtCpuQMaV3EsvbUI= temp
Nru   rx   s     r    Útest_printFingerprintsha256z'KeyGenTests.test_printFingerprintsha256­   sQ   € ð
 —;‘;“=ˆÜ�Ó×%Ñ%Ô&7Ô8Ü h¸/ÑJÔKØ×ÑØ�K‰K× Ñ Ó"ØFõ	
r"   c                ó"  — | j                  «       }t        |«      j                  t        «       | j	                  t
        «      5 }t        |ddœ«       ddd«       | j                  dj                  j                  d   «       y# 1 sw Y   Œ3xY w)zx
        L{printFigerprint} raises C{keys.BadFingerprintFormat} when unsupported
        formats are requested.
        rn   rt   Nro   r   )
r<   r   rv   r   rZ   r   r   rB   rp   rK   )r0   rJ   rq   s      r    Ú)test_printFingerprintBadFingerPrintFormatz5KeyGenTests.test_printFingerprintBadFingerPrintFormatº   s|   € ð
 —;‘;“=ˆÜ�Ó×%Ñ%Ô&7Ô8Ø×ÑÔ3Ó4ð 	M¸Ü¨(¸lÑKÔL÷	Mà×ÑØ8¸"¿,¹,×:KÑ:KÈAÑ:Nõ	
÷	Mð 	Mús   ÁBÂBc                óÖ   — | j                  «       }t        |dz   «      j                  t        «       t	        |ddœ«       | j                  | j                  j                  «       d«       y)zn
        L{printFingerprint} checks if the filename with the  '.pub' suffix
        exists in ~/.ssh.
        r7   rc   rt   z>2048 85:25:04:32:58:55:96:9f:57:ee:fb:a8:1a:ea:69:da temp.pub
Nru   rx   s     r    Ú#test_printFingerprintSuffixAppendedz/KeyGenTests.test_printFingerprintSuffixAppendedÇ   sV   € ð
 —;‘;“=ˆÜ�˜FÑ"Ó#×.Ñ.Ô/@ÔAÜ h¸)ÑDÔEØ×ÑØ�K‰K× Ñ Ó"ØMõ	
r"   c                ó`  — t        | j                  «       «      }|j                  «        |j                  d«      j                  }t        j                  t        «      }t        ||dddœ«       | j                  | j                  j                  «       d|›d|›d�«       | j                  |j                  |j                  d«      j                  «       dd«      |«       | j                  t        j                  |j                  d	«      j                  «       «      |j                  «       «       y)
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Ú
passphraserc   ©rJ   Úpassrb   ú&Your identification has been saved in ú#
Your public key has been saved in úm.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   r<   ÚmakedirsÚchildÚpathr   Ú
fromStringr	   r   rB   r,   rw   Ú
getContentÚpublic©r0   ÚbaserJ   Úkeys       r    Útest_saveKeyzKeyGenTests.test_saveKeyÔ   sé   € ô
 ˜Ÿ™›Ó&ˆØ�‰ŒØ—:‘:˜hÓ'×,Ñ,ˆÜ�n‰nÔ/Ó0ˆÜ� 8°\ÈYÑWÔXØ×ÑØ�K‰K× Ñ Ô"ò DLÊXðWô	
ð 	×ÑØ�N‰N˜4Ÿ:™: hÓ/×:Ñ:Ó<¸dÀLÓQÐSVô	
ð 	×ÑÜ�N‰N˜4Ÿ:™: lÓ3×>Ñ>Ó@ÓAÀ3Ç:Á:Ã<õ	
r"   c                ó`  — t        | j                  «       «      }|j                  «        |j                  d«      j                  }t        j                  t        «      }t        ||dddœ«       | j                  | j                  j                  «       d|›d|›d�«       | j                  |j                  |j                  d«      j                  «       dd«      |«       | j                  t        j                  |j                  d	«      j                  «       «      |j                  «       «       y)
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_ecdsar‚   rc   rƒ   r…   r†   zm.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   r<   rŠ   r‹   rŒ   r   r�   r   r   rB   r,   rw   rŽ   r�   r�   s       r    Útest_saveKeyECDSAzKeyGenTests.test_saveKeyECDSAì   sé   € ô ˜Ÿ™›Ó&ˆØ�‰ŒØ—:‘:˜jÓ)×.Ñ.ˆÜ�n‰nÔ1Ó2ˆÜ� 8°\ÈYÑWÔXØ×ÑØ�K‰K× Ñ Ô"ò DLÊXðWô	
ð 	×ÑØ�N‰N˜4Ÿ:™: jÓ1×<Ñ<Ó>ÀÀlÓSÐUXô	
ð 	×ÑÜ�N‰N˜4Ÿ:™: nÓ5×@Ñ@ÓBÓCÀSÇZÁZÃ\õ	
r"   c                ó`  — t        | j                  «       «      }|j                  «        |j                  d«      j                  }t        j                  t        «      }t        ||dddœ«       | j                  | j                  j                  «       d|›d|›d�«       | j                  |j                  |j                  d«      j                  «       dd«      |«       | j                  t        j                  |j                  d	«      j                  «       «      |j                  «       «       y)
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_ed25519r‚   rc   rƒ   r…   r†   zm.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   r<   rŠ   r‹   rŒ   r   r�   r   r   rB   r,   rw   rŽ   r�   r�   s       r    Útest_saveKeyEd25519zKeyGenTests.test_saveKeyEd25519  sê   € ô ˜Ÿ™›Ó&ˆØ�‰ŒØ—:‘:˜lÓ+×0Ñ0ˆÜ�n‰nÔ7Ó8ˆÜ� 8°\ÈYÑWÔXØ×ÑØ�K‰K× Ñ Ô"ò DLÊXðWô	
ð 	×ÑØ�N‰N˜4Ÿ:™: lÓ3×>Ñ>Ó@À$ÈÓUØô	
ð 	×ÑÜ�N‰N˜4Ÿ:™:Ð&6Ó7×BÑBÓDÓEÀsÇzÁzÃ|õ	
r"   c                ó`  — t        | j                  «       «      }|j                  «        |j                  d«      j                  }t        j                  t        «      }t        ||dddœ«       | j                  | j                  j                  «       d|›d|›d�«       | j                  |j                  |j                  d«      j                  «       dd«      |«       | j                  t        j                  |j                  d	«      j                  «       «      |j                  «       «       y)
zŠ
        L{_saveKey} will generate key fingerprint in
        L{FingerprintFormats.SHA256-BASE64} format if explicitly specified.
        r�   r‚   rj   rƒ   r…   r†   zp.pub
The key fingerprint in <FingerprintFormats=SHA256_BASE64> is:
FBTCOoknq0mHy+kpfnY9tDdcAJuWtCpuQMaV3EsvbUI=
Nrˆ   r‰   r�   s       r    Útest_saveKeysha256zKeyGenTests.test_saveKeysha256  sî   € ô
 ˜Ÿ™›Ó&ˆØ�‰ŒØ—:‘:˜hÓ'×,Ñ,ˆÜ�n‰nÔ/Ó0ˆÜØ˜h°ÈÑXô	
ð 	×ÑØ�K‰K× Ñ Ô"ò AIÊ(ðTô	
ð 	×ÑØ�N‰N˜4Ÿ:™: hÓ/×:Ñ:Ó<¸dÀLÓQÐSVô	
ð 	×ÑÜ�N‰N˜4Ÿ:™: lÓ3×>Ñ>Ó@ÓAÀ3Ç:Á:Ã<õ	
r"   c                ó„  — t        | j                  «       «      }|j                  «        |j                  d«      j                  }t        j                  t        «      }| j                  t        «      5 }t        ||dddœ«       ddd«       | j                  dj                  j                  d   «       y# 1 sw Y   Œ3xY w)zq
        L{_saveKey} raises C{keys.BadFingerprintFormat} when unsupported
        formats are requested.
        r�   r‚   rn   rƒ   Nro   r   )r   r<   rŠ   r‹   rŒ   r   r�   r	   rZ   r   r   rB   rp   rK   )r0   r‘   rJ   r’   rq   s        r    Ú test_saveKeyBadFingerPrintformatz,KeyGenTests.test_saveKeyBadFingerPrintformat9  sŸ   € ô
 ˜Ÿ™›Ó&ˆØ�‰ŒØ—:‘:˜hÓ'×,Ñ,ˆÜ�n‰nÔ/Ó0ˆØ×ÑÔ3Ó4ð 	¸ÜØØ%¨|À|ÑTô÷	ð
 	×ÑØ8¸"¿,¹,×:KÑ:KÈAÑ:Nõ	
÷	ð 	ús   Á3B6Â6B?c                ó^  — t        | j                  «       «      }|j                  «        |j                  d«      j                  }t        j                  t        «      }t        ||dddœ«       | j                  |j                  |j                  d«      j                  «       dd«      |«       y)úq
        L{_saveKey} will choose an empty string for the passphrase if
        no-passphrase is C{True}.
        r�   Trc   ©rJ   zno-passphraserb   Nr"   )r   r<   rŠ   r‹   rŒ   r   r�   r	   r   rB   rŽ   r�   s       r    Útest_saveKeyEmptyPassphrasez'KeyGenTests.test_saveKeyEmptyPassphraseK  sˆ   € ô
 ˜Ÿ™›Ó&ˆØ�‰ŒØ—:‘:˜hÓ'×,Ñ,ˆÜ�n‰nÔ/Ó0ˆÜØ˜h¸ÈÑSô	
ð 	×ÑØ�N‰N˜4Ÿ:™: hÓ/×:Ñ:Ó<¸dÀCÓHÈ#õ	
r"   c                ó\  — t        | j                  «       «      }|j                  «        |j                  d«      j                  }t        j                  t        «      }t        ||dddœ«       | j                  |j                  |j                  d«      j                  «       d«      |«       y)rŸ   r•   Trc   r    N)r   r<   rŠ   r‹   rŒ   r   r�   r   r   rB   rŽ   r�   s       r    Ú test_saveKeyECDSAEmptyPassphrasez,KeyGenTests.test_saveKeyECDSAEmptyPassphrase[  s„   € ô
 ˜Ÿ™›Ó&ˆØ�‰ŒØ—:‘:˜jÓ)×.Ñ.ˆÜ�n‰nÔ1Ó2ˆÜØ˜h¸ÈÑSô	
ð 	×Ñ˜Ÿ™¨¯
©
°:Ó(>×(IÑ(IÓ(KÈTÓRÐTWÕXr"   c                ó\  — t        | j                  «       «      }|j                  «        |j                  d«      j                  }t        j                  t        «      }t        ||dddœ«       | j                  |j                  |j                  d«      j                  «       d«      |«       y)rŸ   r˜   Trc   r    N)r   r<   rŠ   r‹   rŒ   r   r�   r   r   rB   rŽ   r�   s       r    Ú"test_saveKeyEd25519EmptyPassphrasez.KeyGenTests.test_saveKeyEd25519EmptyPassphrasei  s†   € ô
 ˜Ÿ™›Ó&ˆØ�‰ŒØ—:‘:˜lÓ+×0Ñ0ˆÜ�n‰nÔ7Ó8ˆÜØ˜h¸ÈÑSô	
ð 	×ÑØ�N‰N˜4Ÿ:™: lÓ3×>Ñ>Ó@À$ÓGÈõ	
r"   c                óì  ‡‡— t        | j                  «       «      }|j                  «        |j                  d«      j                  Šg Šddl}dˆfd„}| j                  |j                  j                  j                  dˆfd„«       t        j                  t        «      }t        |dddd	œ|«       |j                  d«      j                  «       }|j                  |dd
«      }| j                  ||«       y)zd
        When no path is specified, it will ask for the path used to store the
        key.
        Ú
custom_keyr   Nc                 ó(   •— ‰j                  d«       y©NÚ ©Úappend©rK   Úinput_promptss    €r    Ú
mock_inputz6KeyGenTests.test_saveKeyNoFilename.<locals>.mock_input…  ó   ø€ Ø× Ñ  Ô$Ør"   Ú_inputSaveFilec                ó   •— ‰S r   © )r   ÚkeyPaths    €r    ú<lambda>z4KeyGenTests.test_saveKeyNoFilename.<locals>.<lambda>‰  s   ø€ Èg€ r"   Trc   r    r"   ©rK   r#   r$   r%   )r   r<   rŠ   r‹   rŒ   Útwisted.conch.scripts.ckeygenr-   ÚconchÚscriptsr3   r   r�   r	   r   rŽ   rB   )	r0   r‘   Útwistedr¯   r’   ÚpersistedKeyContentÚpersistedKeyr®   r´   s	          @@r    Útest_saveKeyNoFilenamez"KeyGenTests.test_saveKeyNoFilenamey  sÇ   ù€ ô
 ˜Ÿ™›Ó&ˆØ�‰ŒØ—*‘*˜\Ó*×/Ñ/ˆØ#%ˆã,õ	ð 	�
‰
�7—=‘=×(Ñ(×0Ñ0Ð2BÓDUÔVÜ�n‰nÔ/Ó0ˆÜØØ°À	ÑJØô	
ð #Ÿj™j¨Ó6×AÑAÓCÐØ—~‘~Ð&9¸4ÀÓEˆØ×Ñ˜˜lÕ+r"   c                óP  — d	d„}t        | j                  «       «      }|j                  «        |j                  d«      j                  }| j                  t        j                  dd„ «       t        j                  t        «      }|dddœ}| j                  t        t        |||«       y)
zs
        When the specified file exists, it will ask the user for confirmation
        before overwriting.
        c                 ó   — dgS )NÚnr³   )rK   s    r    r¯   z6KeyGenTests.test_saveKeyFileExists.<locals>.mock_input›  s	   € Ø�5ˆLr"   r§   Úexistsc                 ó   — y)NTr³   )r   s    r    rµ   z4KeyGenTests.test_saveKeyFileExists.<locals>.<lambda>¢  ó   � r"   Trc   r    N)rK   r#   r$   z	list[str])r   r<   rŠ   r‹   rŒ   r-   r]   r   r�   r	   rZ   Ú
SystemExitr   )r0   r¯   r‘   r´   r’   rg   s         r    Útest_saveKeyFileExistsz"KeyGenTests.test_saveKeyFileExists•  s{   € ó	ô ˜Ÿ™›Ó&ˆØ�‰ŒØ—*‘*˜\Ó*×/Ñ/ˆà�
‰
”2—7‘7˜H¡nÔ5Ü�n‰nÔ/Ó0ˆØ&¸ÈÑSˆØ×Ñœ*¤h°°W¸jÕIr"   c                ó¦  — t        | j                  «       «      }|j                  «        |j                  d«      j                  }t        j                  t        «      }t        ||ddddœ«       | j                  | j                  j                  «       d|›d|›d�«       |j                  d«      j                  «       }| j                  |j                  |d	d«      |«       | j                  |j                  d
«      «       | j                  t        j                  |j                  d«      j                  «       «      |j                  «       «       y	)zi
        L{_saveKey} can be told to write the new private key file in OpenSSH
        v1 format.
        r�   r‚   rc   rQ   )rJ   r„   rb   úprivate-key-subtyper…   r†   r‡   Nó$   -----BEGIN OPENSSH PRIVATE KEY-----
rˆ   )r   r<   rŠ   r‹   rŒ   r   r�   r	   r   rB   r,   rw   rŽ   rE   Ú
startswithr�   )r0   r‘   rJ   r’   ÚprivateKeyContents        r    Útest_saveKeySubtypeV1z!KeyGenTests.test_saveKeySubtypeV1§  s  € ô
 ˜Ÿ™›Ó&ˆØ�‰ŒØ—:‘:˜hÓ'×,Ñ,ˆÜ�n‰nÔ/Ó0ˆÜØà$Ø$Ø#Ø'+ñ	ô	
ð 	×ÑØ�K‰K× Ñ Ô"ò DLÊXðWô	
ð !ŸJ™J xÓ0×;Ñ;Ó=ÐØ×Ñ˜Ÿ™Ð(9¸4ÀÓNÐPSÔTØ�‰Ø×(Ñ(Ð)QÓRô	
ð 	×ÑÜ�N‰N˜4Ÿ:™: lÓ3×>Ñ>Ó@ÓAÀ3Ç:Á:Ã<õ	
r"   c                ó^  — | j                  «       }t        j                  t        «      }t	        |«      j                  t        «       t        d|i«       | j                  j                  «       j                  d«      j                  d«      }| j                  ||j                  d«      «       y)zl
        L{displayPublicKey} prints out the public key associated with a given
        private key.
        rJ   ú
ÚasciiÚopensshN)r<   r   r�   r   r   rv   r	   r   r,   rw   ÚstripÚencoderB   ÚtoString©r0   rJ   rM   Ú	displayeds       r    Útest_displayPublicKeyz!KeyGenTests.test_displayPublicKeyÉ  s€   € ð
 —;‘;“=ˆÜ—‘Ô 1Ó2ˆÜ�Ó×%Ñ%Ô&8Ô9Ü˜* hÐ/Ô0Ø—K‘K×(Ñ(Ó*×0Ñ0°Ó6×=Ñ=¸gÓFˆ	Ø×Ñ˜ F§O¡O°IÓ$>Õ?r"   c                ó`  — | j                  «       }t        j                  t        «      }t	        |«      j                  t        «       t        |ddœ«       | j                  j                  «       j                  d«      j                  d«      }| j                  ||j                  d«      «       y)z›
        L{displayPublicKey} prints out the public key associated with a given
        private key using the given passphrase when it's encrypted.
        Ú	encrypted©rJ   r„   rÍ   rÎ   rÏ   N)r<   r   r�   r   r   rv   r
   r   r,   rw   rÐ   rÑ   rB   rÒ   rÓ   s       r    Útest_displayPublicKeyEncryptedz*KeyGenTests.test_displayPublicKeyEncryptedÕ  s€   € ð
 —;‘;“=ˆÜ—‘Ô 1Ó2ˆÜ�Ó×%Ñ%Ô&BÔCÜ h¸ÑDÔEØ—K‘K×(Ñ(Ó*×0Ñ0°Ó6×=Ñ=¸gÓFˆ	Ø×Ñ˜ F§O¡O°IÓ$>Õ?r"   c                óŽ  — | j                  «       }t        j                  t        «      }t	        |«      j                  t        «       | j                  t        dd„ «       t        d|i«       | j                  j                  «       j                  d«      j                  d«      }| j                  ||j                  d«      «       y)z›
        L{displayPublicKey} prints out the public key associated with a given
        private key, asking for the passphrase when it's encrypted.
        Úgetpassc                 ó   — y)Nr×   r³   )Úxs    r    rµ   zLKeyGenTests.test_displayPublicKeyEncryptedPassphrasePrompt.<locals>.<lambda>é  rÃ   r"   rJ   rÍ   rÎ   rÏ   N)r<   r   r�   r   r   rv   r
   r-   rÛ   r   r,   rw   rÐ   rÑ   rB   rÒ   rÓ   s       r    Ú.test_displayPublicKeyEncryptedPassphrasePromptz:KeyGenTests.test_displayPublicKeyEncryptedPassphrasePromptá  s‘   € ð
 —;‘;“=ˆÜ—‘Ô 1Ó2ˆÜ�Ó×%Ñ%Ô&BÔCØ�
‰
”7˜IÑ'<Ô=Ü˜* hÐ/Ô0Ø—K‘K×(Ñ(Ó*×0Ñ0°Ó6×=Ñ=¸gÓFˆ	Ø×Ñ˜ F§O¡O°IÓ$>Õ?r"   c                óœ   — | j                  «       }t        |«      j                  t        «       | j	                  t
        t        |ddœ«       y)zŠ
        L{displayPublicKey} fails with a L{BadKeyError} when trying to decrypt
        an encrypted key with the wrong password.
        ÚwrongrØ   N)r<   r   rv   r
   rZ   r   r   rx   s     r    Ú$test_displayPublicKeyWrongPassphrasez0KeyGenTests.test_displayPublicKeyWrongPassphraseî  s>   € ð
 —;‘;“=ˆÜ�Ó×%Ñ%Ô&BÔCØ×ÑÜÔ)¸È'Ñ+Rõ	
r"   c                óŽ  — t        ddd«      }| j                  t        d|«       | j                  «       }t	        |«      j                  t        «       t        d|i«       | j                  | j                  j                  «       j                  d«      d«       | j                  t        t	        |«      j                  «       «       y)zt
        L{changePassPhrase} allows a user to change the passphrase of a
        private key interactively.
        r×   ÚnewpassrÛ   rJ   rÍ   ú;Your identification has been saved with the new passphrase.N©r(   r-   rÛ   r<   r   rv   r
   r   rB   r,   rw   rÐ   ÚassertNotEqualrŽ   )r0   ÚoldNewConfirmrJ   s      r    Útest_changePassphrasez!KeyGenTests.test_changePassphraseù  s�   € ô
 $ K°¸IÓFˆØ�
‰
”7˜I }Ô5à—;‘;“=ˆÜ�Ó×%Ñ%Ô&BÔCä˜* hÐ/Ô0Ø×ÑØ�K‰K× Ñ Ó"×(Ñ(¨Ó.ØIô	
ð 	×ÑÜ(¬(°8Ó*<×*GÑ*GÓ*Iõ	
r"   c                óŽ  — t        dd«      }| j                  t        d|«       | j                  «       }t	        |«      j                  t        «       t        |ddœ«       | j                  | j                  j                  «       j                  d«      d«       | j                  t        t	        |«      j                  «       «       y)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å   )r0   Ú
newConfirmrJ   s      r    Útest_changePassphraseWithOldz(KeyGenTests.test_changePassphraseWithOld  s›   € ô
 ! ¨IÓ6ˆ
Ø�
‰
”7˜I zÔ2à—;‘;“=ˆÜ�Ó×%Ñ%Ô&BÔCä h¸ÑDÔEØ×ÑØ�K‰K× Ñ Ó"×(Ñ(¨Ó.ØIô	
ð 	×ÑÜ(¬(°8Ó*<×*GÑ*GÓ*Iõ	
r"   c                óJ  — | j                  «       }t        |«      j                  t        «       t	        |dddœ«       | j                  | j                  j                  «       j                  d«      d«       | j                  t        t        |«      j                  «       «       y)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)rJ   r„   rã   rÍ   rä   N)r<   r   rv   r
   r   rB   r,   rw   rÐ   ræ   rŽ   rx   s     r    Útest_changePassphraseWithBothz)KeyGenTests.test_changePassphraseWithBoth!  s†   € ð
 —;‘;“=ˆÜ�Ó×%Ñ%Ô&BÔCäØ!¨;À<ÑPô	
ð 	×ÑØ�K‰K× Ñ Ó"×(Ñ(¨Ó.ØIô	
ð 	×ÑÜ(¬(°8Ó*<×*GÑ*GÓ*Iõ	
r"   c                ó,  — | j                  «       }t        |«      j                  t        «       | j	                  t
        t        |ddœ«      }| j                  dt        |«      «       | j                  t        t        |«      j                  «       «       y)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)
r<   r   rv   r
   rZ   rÄ   r   rB   r%   rŽ   ©r0   rJ   Úerrors      r    Ú$test_changePassphraseWrongPassphrasez0KeyGenTests.test_changePassphraseWrongPassphrase4  sz   € ð
 —;‘;“=ˆÜ�Ó×%Ñ%Ô&BÔCØ×!Ñ!ÜÔ(°xÈÑ*Qó
ˆð 	×ÑØ?ÄÀUÃô	
ð 	×ÑÔ5´xÀÓ7I×7TÑ7TÓ7VÕWr"   c                ój  — | j                  t        dt        d«      «       | j                  «       }t	        |«      j                  t        «       | j                  t        t        d|i«      }| j                  dt        |«      «       | j                  t        t	        |«      j                  «       «       y)zƒ
        L{changePassPhrase} exits if no passphrase is specified for the
        C{getpass} call and the key is encrypted.
        rÛ   rª   rJ   zMCould not change passphrase: Passphrase must be provided for an encrypted keyN)r-   rÛ   r(   r<   r   rv   r
   rZ   rÄ   r   rB   r%   rŽ   rð   s      r    Ú!test_changePassphraseEmptyGetPassz-KeyGenTests.test_changePassphraseEmptyGetPassC  sŒ   € ð
 	�
‰
”7˜I¤{°2£Ô7Ø—;‘;“=ˆÜ�Ó×%Ñ%Ô&BÔCØ×!Ñ!¤*Ô.>ÀÈXÐ@VÓWˆØ×Ñð#ä�‹Jô	
ð
 	×ÑÔ5´xÀÓ7I×7TÑ7TÓ7VÕWr"   c                ó  — | j                  «       }t        |«      j                  d«       | j                  t        t
        d|i«      }d}| j                  |t        |«      «       | j                  dt        |«      j                  «       «       y)zc
        L{changePassPhrase} exits if the file specified points to an invalid
        key.
        s   foobarrJ   z?Could not change passphrase: cannot guess the type of b'foobar'N)	r<   r   rv   rZ   rÄ   r   rB   r%   rŽ   )r0   rJ   rñ   Úexpecteds       r    Útest_changePassphraseBadKeyz'KeyGenTests.test_changePassphraseBadKeyS  ss   € ð
 —;‘;“=ˆÜ�Ó×%Ñ% iÔ0Ø×!Ñ!¤*Ô.>ÀÈXÐ@VÓWˆàWˆØ×Ñ˜¤3 u£:Ô.Ø×Ñ˜¤H¨XÓ$6×$AÑ$AÓ$CÕDr"   c                ób  — | j                  «       }t        |«      j                  t        «       dd„}| j	                  t
        d|«       | j                  t        t        |ddœ«      }| j                  dt        |«      «       | j                  t        t        |«      j                  «       «       y)zŸ
        L{changePassPhrase} doesn't modify the key file if an unexpected error
        happens when trying to create the key with the new passphrase.
        c                 ó   — t        d«      ‚)NÚoops)ÚRuntimeError©rK   Úkwargss     r    rÒ   z>KeyGenTests.test_changePassphraseCreateError.<locals>.toStringh  s   € Ü˜vÓ&Ð&r"   rÒ   rí   ©rJ   rã   z!Could not change passphrase: oopsN)rK   r#   rý   r#   r$   r   ©r<   r   rv   r	   r-   r   rZ   rÄ   r   rB   r%   rŽ   )r0   rJ   rÒ   rñ   s       r    Ú test_changePassphraseCreateErrorz,KeyGenTests.test_changePassphraseCreateError`  sŽ   € ð
 —;‘;“=ˆÜ�Ó×%Ñ%Ô&8Ô9ó	'ð 	�
‰
”3˜
 HÔ-à×!Ñ!ÜÜØ!¨lÑ;ó
ˆð 	×ÑÐ<¼cÀ%»jÔIà×ÑÔ+¬X°hÓ-?×-JÑ-JÓ-LÕMr"   c                óf  — | j                  «       }t        |«      j                  t        «       dd„}| j	                  t
        d|«       | j                  t        t        |ddœ«      }d}| j                  |t        |«      «       | j                  t        t        |«      j                  «       «       y)zq
        L{changePassPhrase} doesn't modify the key file if C{toString} returns
        an empty string.
        c                  ó   — yr©   r³   rü   s     r    rÒ   zCKeyGenTests.test_changePassphraseEmptyStringError.<locals>.toString  s   € Ør"   rÒ   rí   rþ   z9Could not change passphrase: cannot guess the type of b''N)rK   r#   rý   r#   r$   r%   rÿ   )r0   rJ   rÒ   rñ   rö   s        r    Ú%test_changePassphraseEmptyStringErrorz1KeyGenTests.test_changePassphraseEmptyStringErrorw  s“   € ð
 —;‘;“=ˆÜ�Ó×%Ñ%Ô&8Ô9ó	ð 	�
‰
”3˜
 HÔ-à×!Ñ!ÜÜØ!¨lÑ;ó
ˆð OˆØ×Ñ˜¤3 u£:Ô.à×ÑÔ+¬X°hÓ-?×-JÑ-JÓ-LÕMr"   c                ó,  — | j                  «       }t        |«      j                  t        «       | j	                  t
        t        |ddœ«      }| j                  dt        |«      «       | j                  t        t        |«      j                  «       «       y)z†
        L{changePassPhrase} exits when trying to change the passphrase on a
        public key, and doesn't change the file.
        r„   rþ   z.Could not change passphrase: key not encryptedN)
r<   r   rv   r   rZ   rÄ   r   rB   r%   rŽ   rð   s      r    Útest_changePassphrasePublicKeyz*KeyGenTests.test_changePassphrasePublicKey�  sv   € ð
 —;‘;“=ˆÜ�Ó×%Ñ%Ô&7Ô8Ø×!Ñ!ÜÔ(°xÈFÑ*Só
ˆð 	×ÑÐIÌ3ÈuË:ÔVØ×ÑÔ*¬H°XÓ,>×,IÑ,IÓ,KÕLr"   c                óÔ  — t        ddd«      }| j                  t        d|«       | j                  «       }t	        |«      j                  t        «       t        |ddœ«       | j                  | j                  j                  «       j                  d«      d«       t	        |«      j                  «       }| j                  t        |«       | j                  |j                  d«      «       y	)
zq
        L{changePassPhrase} can be told to write the new private key file in
        OpenSSH v1 format.
        r×   rã   rÛ   rQ   )rJ   rÇ   rÍ   rä   rÈ   N)r(   r-   rÛ   r<   r   rv   r
   r   rB   r,   rw   rÐ   rŽ   ræ   rE   rÉ   )r0   rç   rJ   rÊ   s       r    Útest_changePassphraseSubtypeV1z*KeyGenTests.test_changePassphraseSubtypeV1œ  s½   € ô
 $ K°¸IÓFˆØ�
‰
”7˜I }Ô5à—;‘;“=ˆÜ�Ó×%Ñ%Ô&BÔCä hÀtÑLÔMØ×ÑØ�K‰K× Ñ Ó"×(Ñ(¨Ó.ØIô	
ô % XÓ.×9Ñ9Ó;ÐØ×ÑÔ8Ð:KÔLØ�‰Ø×(Ñ(Ð)QÓRõ	
r"   c                ó8  ‡— g Šdˆfd„}ddi}t        ||«      }| j                  |d   d«       | j                  |j                  t        j
                  j                  dd«      «      «       | j                  dt        ‰«      «       | j                  dg‰«       y)	zg
        L{options} will default to "~/.ssh/id_rsa" if the user doesn't
        specify a key.
        c                 ó(   •— ‰j                  d«       yr©   r«   r­   s    €r    r¯   z5KeyGenTests.test_useDefaultForKey.<locals>.mock_input¹  r°   r"   rJ   rª   z.sshr�   é   Nr¶   )r   rB   rE   Úendswithr]   rŒ   ÚjoinÚlen)r0   r¯   rg   rJ   r®   s       @r    Útest_useDefaultForKeyz!KeyGenTests.test_useDefaultForKey²  s‘   ø€ ð
 $&ˆõ	ð ˜rÐ"ˆä# G¨ZÓ8ˆØ×ÑØ�JÑØô	
ð
 	�‰˜×)Ñ)¬"¯'©'¯,©,°v¸xÓ*HÓIÔJð 	×Ñ˜œC Ó.Ô/Ø×Ñ˜"˜˜}Õ-r"   c                ó€   — ddi}| j                  t        t        |«      }| j                  d|j                  d   «       y)z‹
        Ensure FileNotFoundError is handled, whether the user has supplied
        a bad path, or has no key at the default path.
        rJ   ú/foo/barú+could not be opened, please specify a file.r   N)rZ   rÄ   r   ÚassertInrK   ©r0   rg   Úexcs      r    Ú'test_displayPublicKeyHandleFileNotFoundz3KeyGenTests.test_displayPublicKeyHandleFileNotFoundË  s:   € ð
 ˜zÐ*ˆØ×Ñ¤
Ô,<¸gÓFˆØ�‰ÐCÀSÇXÁXÈaÁ[ÕQr"   c                ó€   — ddi}| j                  t        t        |«      }| j                  d|j                  d   «       y)úN
        Ensure FileNotFoundError is handled for an invalid filename.
        rJ   r  r  r   N)rZ   rÄ   r   r  rK   r  s      r    Ú'test_changePassPhraseHandleFileNotFoundz3KeyGenTests.test_changePassPhraseHandleFileNotFoundÔ  s:   € ð ˜zÐ*ˆØ×Ñ¤
Ô,<¸gÓFˆØ�‰ÐCÀSÇXÁXÈaÁ[ÕQr"   c                ó‚   — dddœ}| j                  t        t        |«      }| j                  d|j                  d   «       y)r  r  rc   rt   r  r   N)rZ   rÄ   r   r  rK   r  s      r    Ú'test_printFingerprintHandleFileNotFoundz3KeyGenTests.test_printFingerprintHandleFileNotFoundÜ  s:   € ð  *°YÑ?ˆØ×Ñ¤
Ô,<¸gÓFˆØ�‰ÐCÀSÇXÁXÈaÁ[ÕQr"   )r$   ÚNone)NN)rG   r%   rH   ú
str | NonerI   r  r$   r  ),Ú__name__Ú
__module__Ú__qualname__Ú__doc__r1   rN   rU   r`   rh   rl   rr   ry   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  r  r  r  r  r³   r"   r    r*   r*   C   s  „ ñó/ð #Ø(,ð	+àð+ð ð+ð &ð	+ð
 
ó+ó65ó(óEóKó
ó
ó
ó
ó
ó
ó0
ó2
ó4
ó4
ó$
ó Yó
ó ,ó8Jó$ 
óD
@ó
@ó@ó	
ó
ó(
ó(
ó&XóXó EóNó.Nó0Mó
ó,.ó2RóRôRr"   r*   )r'   r%   r$   zCallable[[object], str])'r   Ú
__future__r   rÛ   r]   r>   r.   Úior   Útypingr   r   Útwisted.conch.test.keydatar   r   r	   r
   r   Útwisted.python.filepathr   Útwisted.python.reflectr   Útwisted.trial.unittestr   r·   r   r   r   r   r   r   Útwisted.conch.ssh.keysr   r   r   r   Úskipr(   r*   r³   r"   r    ú<module>r*     su   ðñõ #ã Û 	Û Û 
Û 	Ý Ý å ÷õ õ -Ý 0Ý +á�Ô ÷÷ ÷ô ð E€Dóô$_
R�(õ _
Rr"   