ó õùPc@s´dZddlZddlmZmZddlZddlmZddlm Z m Z ddl Tddl m Z ddlmZdd lmZmZd efd „ƒYZdS( s! Common API for all public keys. iÿÿÿÿN(thexlifyt unhexlify(tMD5(tDES3tAES(t*(tutil(tMessage(t SSHExceptiontPasswordRequiredExceptiontPKeycBs8eZdZiied6dd6dd6ejd6d6ied6dd6dd6ejd6d 6Zddd „Zd „Z d „Z d „Z d„Z d„Z d„Zd„Zd„Zd„Zdd„ZeeƒZdd„ZeeƒZdd„Zdd„Zdd„Zdd„Zdd„Zdd„ZRS(s% Base class for public keys. tcipheritkeysizet blocksizetmodes AES-128-CBCiis DES-EDE3-CBCcCsdS(sY Create a new instance of this public key type. If C{msg} is given, the key's public part(s) will be filled in from the message. If C{data} is given, the key's public part(s) will be filled in from the string. @param msg: an optional SSH L{Message} containing a public key of this type. @type msg: L{Message} @param data: an optional string containing a public key of this type @type data: str @raise SSHException: if a key cannot be created from the C{data} or C{msg} given, or no key was passed in. N((tselftmsgtdata((s(..\python\site-packages\paramiko\pkey.pyt__init__0scCsdS(s Return a string of an SSH L{Message} made up of the public part(s) of this key. This string is suitable for passing to L{__init__} to re-create the key object later. @return: string representation of an SSH key message. @rtype: str t((R((s(..\python\site-packages\paramiko\pkey.pyt__str__Bs cCsJt|ƒ}t|ƒ}||kr1t||ƒStt|ƒt|ƒƒS(s± Compare this key to another. Returns 0 if this key is equivalent to the given key, or non-0 if they are different. Only the public parts of the key are compared, so a public key will compare equal to its corresponding private key. @param other: key to compare to. @type other: L{PKey} @return: 0 if the two keys are equivalent, non-0 otherwise. @rtype: int (thashtcmptstr(Rtotherthstho((s(..\python\site-packages\paramiko\pkey.pyt__cmp__Ms    cCsdS(s Return the name of this private key implementation. @return: name of this private key type, in SSH terminology (for example, C{"ssh-rsa"}). @rtype: str R((R((s(..\python\site-packages\paramiko\pkey.pytget_name_scCsdS(s¿ Return the number of significant bits in this key. This is useful for judging the relative security of a key. @return: bits in the key. @rtype: int i((R((s(..\python\site-packages\paramiko\pkey.pytget_bitsiscCstS(s® Return C{True} if this key has the private part necessary for signing data. @return: C{True} if this is a private key. @rtype: bool (tFalse(R((s(..\python\site-packages\paramiko\pkey.pytcan_signsscCstjt|ƒƒjƒS(sã Return an MD5 fingerprint of the public part of this key. Nothing secret is revealed. @return: a 16-byte string (binary) of the MD5 fingerprint, in SSH format. @rtype: str (RtnewRtdigest(R((s(..\python\site-packages\paramiko\pkey.pytget_fingerprint}s cCstjt|ƒƒjddƒS(s7 Return a base64 string containing the public part of this key. Nothing secret is revealed. This format is compatible with that used to store public key files or recognized host keys. @return: a base64 string containing the public part of the key. @rtype: str s R(tbase64t encodestringRtreplace(R((s(..\python\site-packages\paramiko\pkey.pyt get_base64ˆs cCsdS(sp Sign a blob of data with this private key, and return a L{Message} representing an SSH signature message. @param rng: a secure random number generator. @type rng: L{Crypto.Util.rng.RandomPool} @param data: the data to sign. @type data: str @return: an SSH signature message. @rtype: L{Message} R((RtrngR((s(..\python\site-packages\paramiko\pkey.pyt sign_ssh_data“s cCstS(s› Given a blob of data, and an SSH message representing a signature of that data, verify that it was signed with this key. @param data: the data that was signed. @type data: str @param msg: an SSH signature message @type msg: L{Message} @return: C{True} if the signature verifies correctly; C{False} otherwise. @rtype: boolean (R(RRR((s(..\python\site-packages\paramiko\pkey.pytverify_ssh_sig¡s cCs|d|d|ƒ}|S(s× Create a key object by reading a private key file. If the private key is encrypted and C{password} is not C{None}, the given password will be used to decrypt the key (otherwise L{PasswordRequiredException} is thrown). Through the magic of python, this factory method will exist in all subclasses of PKey (such as L{RSAKey} or L{DSSKey}), but is useless on the abstract PKey class. @param filename: name of the file to read @type filename: str @param password: an optional password to use to decrypt the key file, if it's encrypted @type password: str @return: a new key object based on the given private key @rtype: L{PKey} @raise IOError: if there was an error reading the file @raise PasswordRequiredException: if the private key file is encrypted, and C{password} is C{None} @raise SSHException: if the key file is invalid tfilenametpassword((tclsR*R+tkey((s(..\python\site-packages\paramiko\pkey.pytfrom_private_key_file°scCs|d|d|ƒ}|S(s8 Create a key object by reading a private key from a file (or file-like) object. If the private key is encrypted and C{password} is not C{None}, the given password will be used to decrypt the key (otherwise L{PasswordRequiredException} is thrown). @param file_obj: the file to read from @type file_obj: file @param password: an optional password to use to decrypt the key, if it's encrypted @type password: str @return: a new key object based on the given private key @rtype: L{PKey} @raise IOError: if there was an error reading the key @raise PasswordRequiredException: if the private key file is encrypted, and C{password} is C{None} @raise SSHException: if the key file is invalid tfile_objR+((R,R/R+R-((s(..\python\site-packages\paramiko\pkey.pytfrom_private_keyÊscCstdƒ‚dS(s³ Write private key contents into a file. If the password is not C{None}, the key is encrypted before writing. @param filename: name of the file to write @type filename: str @param password: an optional password to use to encrypt the key file @type password: str @raise IOError: if there was an error writing the file @raise SSHException: if the key is invalid sNot implemented in PKeyN(t Exception(RR*R+((s(..\python\site-packages\paramiko\pkey.pytwrite_private_key_fileâs cCstdƒ‚dS(sÌ Write private key contents into a file (or file-like) object. If the password is not C{None}, the key is encrypted before writing. @param file_obj: the file object to write into @type file_obj: file @param password: an optional password to use to encrypt the key @type password: str @raise IOError: if there was an error writing to the file @raise SSHException: if the key is invalid sNot implemented in PKeyN(R1(RR/R+((s(..\python\site-packages\paramiko\pkey.pytwrite_private_keyñs cCs2t|dƒ}|j|||ƒ}|jƒ|S(s Read an SSH2-format private key file, looking for a string of the type C{"BEGIN xxx PRIVATE KEY"} for some C{xxx}, base64-decode the text we find, and return it as a string. If the private key is encrypted and C{password} is not C{None}, the given password will be used to decrypt the key (otherwise L{PasswordRequiredException} is thrown). @param tag: C{"RSA"} or C{"DSA"}, the tag used to mark the data block. @type tag: str @param filename: name of the file to read. @type filename: str @param password: an optional password to use to decrypt the key file, if it's encrypted. @type password: str @return: data blob that makes up the private key. @rtype: str @raise IOError: if there was an error reading the file. @raise PasswordRequiredException: if the private key file is encrypted, and C{password} is C{None}. @raise SSHException: if the key file is invalid. tr(topent_read_private_keytclose(RttagR*R+tfR((s(..\python\site-packages\paramiko\pkey.pyt_read_private_key_files cCs¬|jƒ}d}x>|t|ƒkrR||jƒd|dkrR|d7}qW|t|ƒkr|td|dƒ‚ni}|d7}xg|t|ƒkrõ||jdƒ}t|ƒdkrÊPn|djƒ||djƒ<|d7}qW|}x>||jƒd|dkr<|t|ƒkr<|d7}qÿWy#tjd j|||!ƒƒ} Wn/tj j k r‘} td t | ƒƒ‚nXd |kr¢| S|d d krÉtd |d ƒ‚ny|djdƒ\} } Wntdƒ‚nX| |j krtd| ƒ‚n|dkr9tdƒ‚n|j | d} |j | d}|j | d}t| ƒ}tjt|||ƒ}| j|||ƒj| ƒS(Nis -----BEGIN s PRIVATE KEY-----is not a valid s private key files: s -----END Rsbase64 decoding error: s proc-types 4,ENCRYPTEDs"Unknown private key structure "%s"sdek-infot,s(Can't parse DEK-info in private key filesUnknown private key cipher "%s"sPrivate key file is encryptedR R R(t readlinestlentstripRtsplittlowerR#t decodestringtjointbinasciitErrorRt _CIPHER_TABLEtNoneR RRtgenerate_key_bytesRR tdecrypt(RR8R9R+tlineststarttheaderstltendRtetencryption_typetsaltstrR R RtsaltR-((s(..\python\site-packages\paramiko\pkey.pyR6sN 3 3#   cCsFt|ddƒ}tj|dƒ|j||||ƒ|jƒdS(s× Write an SSH2-format private key file in a form that can be read by paramiko or openssh. If no password is given, the key is written in a trivially-encoded format (base64) which is completely insecure. If a password is given, DES-EDE3-CBC is used. @param tag: C{"RSA"} or C{"DSA"}, the tag used to mark the data block. @type tag: str @param filename: name of the file to write. @type filename: str @param data: data blob that makes up the private key. @type data: str @param password: an optional password to use to encrypt the file. @type password: str @raise IOError: if there was an error writing the file. twi€N(R5tostchmodt_write_private_keyR7(RR8R*RR+R9((s(..\python\site-packages\paramiko\pkey.pyt_write_private_key_fileKscCsÉ|jd|ƒ|dk r4|jjƒd}|j|d}|j|d}|j|d}|j|d} tjdƒ} tjt| ||ƒ} t |ƒ|dkrÖ|t |ƒ|} |d| 7}n|j | | | ƒj |ƒ}|jd ƒ|jd |t | ƒj ƒfƒ|jd ƒntj|ƒ} d j| jd ƒƒ} d jgtdt | ƒd ƒD]}| ||d !^qzƒ} |j| ƒ|jd ƒ|jd|ƒdS(Ns-----BEGIN %s PRIVATE KEY----- iR R R RitsProc-Type: 4,ENCRYPTED sDEK-Info: %s,%s s Ri@s-----END %s PRIVATE KEY----- (twriteRFREtkeysR'treadRRGRR=R tencryptRtupperR#R$RBR?trange(RR8R9RR+t cipher_nameR R R RRQR-tntsti((s(..\python\site-packages\paramiko\pkey.pyRUcs,  #?  N(t__name__t __module__t__doc__RtMODE_CBCRRERFRRRRRRR"R&R(R)R.t classmethodR0R2R3R:R6RVRU(((s(..\python\site-packages\paramiko\pkey.pyR $s0&)           / (RdR#RCRRRSt Crypto.HashRt Crypto.CipherRRtparamiko.commontparamikoRtparamiko.messageRtparamiko.ssh_exceptionRR tobjectR (((s(..\python\site-packages\paramiko\pkey.pyts