B
    `W                 @   s  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 d dlmZmZmZmZ d dlmZmZmZ d dlmZmZmZmZ yd d	lmZ d
ZW n2 e k
r   dZdWe!e!e"e"e#e!dddZY nX dZ$dZ%dZ&dZ'dZ(dZ)dZ*e+dZ,dZ-dZ.dZ/dZ0dZ1dZ2dZ3dZ4e+e.d e/ ej5Z6e7e8e9d d!Z:ej;d"ej<dfej;d"ej=dfd#Z>e'e(e)d$Z?e@d%ZAe@d&ZBd'd( ZCe.d) e/d) fd*d+ZDd,d- ZEd.d/ ZFd0d1 ZGd2d3 ZHd4d5 ZId6d7 ZJd8d9 ZKd:d; ZLG d<d= d=eMZNG d>d? d?eMZOG d@dA dAeMZPG dBdC dCeMZQG dDdE dEeMZRe%eO e&eP e$eR e'eQdFeS e(eQdGeT e)eQdHeU iZVdIdJ ZWejXejYejZej[ej\f Z]dXe!ej^e! e]dKdLdMZ_dYe]ej^e! dNdOdPZ`ejXejaejbejcejdf ZedZe!eedQdRdSZfeee!dTdUdVZgdS )[    N)encodebytes)utils)UnsupportedAlgorithm)_get_backend)dsaeced25519rsa)Cipher
algorithmsmodes)EncodingNoEncryptionPrivateFormatPublicFormat)kdfTF)passwordsaltdesired_key_bytesroundsignore_few_roundsreturnc             C   s   t dd S )NzNeed bcrypt module)r   )r   r   r   r   r    r   _/home/dcms/DCMS/lib/python3.7/site-packages/cryptography/hazmat/primitives/serialization/ssh.py_bcrypt_kdf    s    r   s   ssh-ed25519s   ssh-rsas   ssh-dsss   ecdsa-sha2-nistp256s   ecdsa-sha2-nistp384s   ecdsa-sha2-nistp521s   -cert-v01@openssh.coms   \A(\S+)[ \t]+(\S+)s   openssh-key-v1 s#   -----BEGIN OPENSSH PRIVATE KEY-----s!   -----END OPENSSH PRIVATE KEY-----s   bcrypts   nones
   aes256-ctr   H   s   (.*?)          )s
   aes256-ctrs
   aes256-cbc)Z	secp256r1Z	secp384r1Z	secp521r1s   >Is   >Qc             C   s(   | j }|jtkrtd|j t|j S )z3Return SSH key_type and curve_name for private key.z)Unsupported curve for ssh private key: %r)curvename_ECDSA_KEY_TYPE
ValueError)
public_keyr    r   r   r   _ecdsa_key_typeS   s
    
r%      
c             C   s   d |t| |gS )N    )join_base64_encode)dataprefixsuffixr   r   r   _ssh_pem_encode]   s    r-   c             C   s    | rt | | dkrtddS )zRequire data to be full blocksr   zCorrupt data: missing paddingN)lenr#   )r*   Z	block_lenr   r   r   _check_block_sizea   s    r/   c             C   s   | rt ddS )z!All data should have been parsed.zCorrupt data: unparsed dataN)r#   )r*   r   r   r   _check_emptyg   s    r0   c       
      C   sT   |st dt|  \}}}}t|||| |d}	t||	d| ||	|d |S )z$Generate key + iv and return cipher.zKey is password-protected.TN)r#   _SSH_CIPHERSr   r
   )

ciphernamer   r   r   backendalgoZkey_lenmodeZiv_lenseedr   r   r   _init_cipherm   s
    r7   c             C   s6   t | dk rtdt| dd d | dd fS )ZUint32   zInvalid dataNr   )r.   r#   _U32unpack)r*   r   r   r   _get_u32w   s    r;   c             C   s6   t | dk rtdt| dd d | dd fS )ZUint64   zInvalid dataNr   )r.   r#   _U64r:   )r*   r   r   r   _get_u64~   s    r>   c             C   s8   t | \}} |t| kr td| d| | |d fS )zBytes with u32 length prefixzInvalid dataN)r;   r.   r#   )r*   nr   r   r   _get_sshstr   s    r@   c             C   s4   t | \}} |r$|d dkr$tdt|d| fS )zBig integer.r      zInvalid databig)r@   r#   int
from_bytes)r*   valr   r   r   
_get_mpint   s    rF   c             C   s4   | dk rt d| sdS |  d d }t| |S )z!Storage format for signed bigint.r   znegative mpint not allowedr'   r<   )r#   
bit_lengthr   Zint_to_bytes)rE   nbytesr   r   r   	_to_mpint   s    rI   c               @   sT   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dddZ
dd ZdS )	_FragListz,Build recursive structure without data copy.Nc             C   s   g | _ |r| j | d S )N)flistextend)selfinitr   r   r   __init__   s    z_FragList.__init__c             C   s   | j | dS )zAdd plain bytesN)rK   append)rM   rE   r   r   r   put_raw   s    z_FragList.put_rawc             C   s   | j t| dS )zBig-endian uint32N)rK   rP   r9   pack)rM   rE   r   r   r   put_u32   s    z_FragList.put_u32c             C   sL   t |tttfr,| t| | j| n| |  | j	|j dS )zBytes prefixed with u32 lengthN)

isinstancebytes
memoryview	bytearrayrS   r.   rK   rP   sizerL   )rM   rE   r   r   r   
put_sshstr   s
    z_FragList.put_sshstrc             C   s   |  t| dS )z*Big-endian bigint prefixed with u32 lengthN)rY   rI   )rM   rE   r   r   r   	put_mpint   s    z_FragList.put_mpintc             C   s   t tt| jS )zCurrent number of bytes)summapr.   rK   )rM   r   r   r   rX      s    z_FragList.sizer   c             C   s6   x0| j D ]&}t|}|||  }}||||< qW |S )zWrite into bytearray)rK   r.   )rM   ZdstbufposfragZflenstartr   r   r   render   s
    z_FragList.renderc             C   s"   t t|  }| | | S )zReturn as bytes)rV   rW   rX   r`   tobytes)rM   bufr   r   r   ra      s    
z_FragList.tobytes)N)r   )__name__
__module____qualname____doc__rO   rQ   rS   rY   rZ   rX   r`   ra   r   r   r   r   rJ      s   
	
rJ   c               @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )_SSHFormatRSAzhFormat for RSA keys.

    Public:
        mpint e, n
    Private:
        mpint n, e, d, iqmp, p, q
    c             C   s$   t |\}}t |\}}||f|fS )zRSA public fields)rF   )rM   r*   er?   r   r   r   
get_public   s    z_SSHFormatRSA.get_publicc             C   s0   |  |\\}}}t||}||}||fS )zMake RSA public key from data.)ri   r	   RSAPublicNumbersr$   )rM   key_typer*   r3   rh   r?   public_numbersr$   r   r   r   load_public   s    
z_SSHFormatRSA.load_publicc          	   C   s   t |\}}t |\}}t |\}}t |\}}t |\}}t |\}	}||f|kr\tdt||}
t||	}t||}t||	||
|||}||}||fS )zMake RSA private key from data.z Corrupt data: rsa field mismatch)rF   r#   r	   Zrsa_crt_dmp1Zrsa_crt_dmq1rj   ZRSAPrivateNumbersprivate_key)rM   r*   	pubfieldsr3   r?   rh   diqmppqZdmp1Zdmq1rl   private_numbersrn   r   r   r   load_private   s    
z_SSHFormatRSA.load_privatec             C   s$   |  }||j ||j dS )zWrite RSA public keyN)rl   rZ   rh   r?   )rM   r$   f_pubZpubnr   r   r   encode_public   s    z_SSHFormatRSA.encode_publicc             C   sZ   |  }|j}||j ||j ||j ||j ||j ||j dS )zWrite RSA private keyN)	rt   rl   rZ   r?   rh   rp   rq   rr   rs   )rM   rn   f_privrt   rl   r   r   r   encode_private   s    z_SSHFormatRSA.encode_privateN)	rc   rd   re   rf   ri   rm   ru   rw   ry   r   r   r   r   rg      s   rg   c               @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )_SSHFormatDSAzhFormat for DSA keys.

    Public:
        mpint p, q, g, y
    Private:
        mpint p, q, g, y, x
    c             C   s@   t |\}}t |\}}t |\}}t |\}}||||f|fS )zDSA public fields)rF   )rM   r*   rr   rs   gyr   r   r   ri     s
    z_SSHFormatDSA.get_publicc             C   sL   |  |\\}}}}}t|||}t||}	| |	 |	|}
|
|fS )zMake DSA public key from data.)ri   r   DSAParameterNumbersDSAPublicNumbers	_validater$   )rM   rk   r*   r3   rr   rs   r{   r|   parameter_numbersrl   r$   r   r   r   rm     s    

z_SSHFormatDSA.load_publicc             C   s|   |  |\\}}}}}t|\}}||||f|kr:tdt|||}	t||	}
| |
 t||
}||}||fS )zMake DSA private key from data.z Corrupt data: dsa field mismatch)	ri   rF   r#   r   r}   r~   r   ZDSAPrivateNumbersrn   )rM   r*   ro   r3   rr   rs   r{   r|   xr   rl   rt   rn   r   r   r   ru   '  s    

z_SSHFormatDSA.load_privatec             C   sL   |  }|j}| | ||j ||j ||j ||j dS )zWrite DSA public keyN)rl   r   r   rZ   rr   rs   r{   r|   )rM   r$   rv   rl   r   r   r   r   rw   5  s    
z_SSHFormatDSA.encode_publicc             C   s$   |  | | || j dS )zWrite DSA private keyN)rw   r$   rZ   rt   r   )rM   rn   rx   r   r   r   ry   @  s    z_SSHFormatDSA.encode_privatec             C   s    |j }|j dkrtdd S )Ni   z#SSH supports only 1024 bit DSA keys)r   rr   rG   r#   )rM   rl   r   r   r   r   r   E  s    z_SSHFormatDSA._validateN)
rc   rd   re   rf   ri   rm   ru   rw   ry   r   r   r   r   r   rz     s   	rz   c               @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )_SSHFormatECDSAzFormat for ECDSA keys.

    Public:
        str curve
        bytes point
    Private:
        str curve
        bytes point
        mpint secret
    c             C   s   || _ || _d S )N)ssh_curve_namer    )rM   r   r    r   r   r   rO   W  s    z_SSHFormatECDSA.__init__c             C   sJ   t |\}}t |\}}|| jkr*td|d dkr>td||f|fS )zECDSA public fieldszCurve name mismatchr   r8   zNeed uncompressed point)r@   r   r#   NotImplementedError)rM   r*   r    pointr   r   r   ri   [  s    
z_SSHFormatECDSA.get_publicc             C   s.   |  |\\}}}tj| j| }||fS )z Make ECDSA public key from data.)ri   r   EllipticCurvePublicKeyZfrom_encoded_pointr    ra   )rM   rk   r*   r3   
curve_namer   r$   r   r   r   rm   e  s    z_SSHFormatECDSA.load_publicc             C   sJ   |  |\\}}}t|\}}||f|kr2tdt|| j|}||fS )z!Make ECDSA private key from data.z"Corrupt data: ecdsa field mismatch)ri   rF   r#   r   Zderive_private_keyr    )rM   r*   ro   r3   r   r   secretrn   r   r   r   ru   m  s    z_SSHFormatECDSA.load_privatec             C   s*   | tjtj}|| j || dS )zWrite ECDSA public keyN)public_bytesr   ZX962r   ZUncompressedPointrY   r   )rM   r$   rv   r   r   r   r   rw   w  s    z_SSHFormatECDSA.encode_publicc             C   s,   |  }| }| || ||j dS )zWrite ECDSA private keyN)r$   rt   rw   rZ   Zprivate_value)rM   rn   rx   r$   rt   r   r   r   ry     s    z_SSHFormatECDSA.encode_privateN)
rc   rd   re   rf   rO   ri   rm   ru   rw   ry   r   r   r   r   r   K  s   


r   c               @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )_SSHFormatEd25519z~Format for Ed25519 keys.

    Public:
        bytes point
    Private:
        bytes point
        bytes secret_and_point
    c             C   s   t |\}}|f|fS )zEd25519 public fields)r@   )rM   r*   r   r   r   r   ri     s    z_SSHFormatEd25519.get_publicc             C   s(   |  |\\}}tj| }||fS )z"Make Ed25519 public key from data.)ri   r   Ed25519PublicKeyZfrom_public_bytesra   )rM   rk   r*   r3   r   r$   r   r   r   rm     s    
z_SSHFormatEd25519.load_publicc       	      C   sb   |  |\\}}t|\}}|dd }|dd }||ksF|f|krNtdtj|}||fS )z#Make Ed25519 private key from data.Nr   z$Corrupt data: ed25519 field mismatch)ri   r@   r#   r   Ed25519PrivateKeyZfrom_private_bytes)	rM   r*   ro   r3   r   Zkeypairr   Zpoint2rn   r   r   r   ru     s    z_SSHFormatEd25519.load_privatec             C   s   | tjtj}|| dS )zWrite Ed25519 public keyN)r   r   Rawr   rY   )rM   r$   rv   raw_public_keyr   r   r   rw     s    z_SSHFormatEd25519.encode_publicc             C   sR   |  }|tjtjt }|tjtj}t||g}| 	|| |
| dS )zWrite Ed25519 private keyN)r$   Zprivate_bytesr   r   r   r   r   r   rJ   rw   rY   )rM   rn   rx   r$   Zraw_private_keyr   Z	f_keypairr   r   r   ry     s    z _SSHFormatEd25519.encode_privateN)	rc   rd   re   rf   ri   rm   ru   rw   ry   r   r   r   r   r     s   r   s   nistp256s   nistp384s   nistp521c             C   s6   t | tst|  } | tkr&t|  S td|  dS )z"Return valid format or throw errorzUnsupported key type: %rN)rT   rU   rV   ra   _KEY_FORMATSr   )rk   r   r   r   _lookup_kformat  s
    
r   )r*   r   r   c             C   sR  t d|  t|}|dk	r(t d| t| }|s>td|d}|d}t	
t| || } | tsztdt| ttd } t| \}} t| \}} t| \}} t| \}	} |	dkrtdt| \}
} t|
\}}
t|}||
\}}
t|
 t| \}} t|  ||fttfkr| }|tkrHtd| |tkr^td| t| d	 }t|| t|\}}t|\}}t| t||| ||}t| |}nd
}t|| t|\}}t|\}}||krtdt|\}}||krtd||||\}}t|\}}|tdt| krNtd|S )z.Load private key from OpenSSH custom encoding.r*   Nr   zNot OpenSSH private key formatr   zOnly one key supportedzUnsupported cipher: %rzUnsupported KDF: %r   r<   zCorrupt data: broken checksumzCorrupt data: key type mismatchzCorrupt data: invalid padding)r   _check_bytesliker   _check_bytes_PEM_RCsearchr#   r_   endbinascii
a2b_base64rV   
startswith	_SK_MAGICr.   r@   r;   r   ri   r0   _NONEra   r1   r   _BCRYPTr/   r7   Z	decryptorupdateru   _PADDING)r*   r   r3   mp1p2r2   kdfnameZ
kdfoptionsnkeysZpubdataZpub_key_typekformatro   Zedatablklenr   Zkbufr   ciphZck1Zck2rk   rn   commentr   r   r   load_ssh_private_key  sl    









r   )rn   r   c             C   s>  |dk	rt d| |r,t|tkr,tdt| tjrFt| 	 }n>t| t
jrXt}n,t| tjrjt}nt| tjr|t}ntdt|}t }|rt}t| d }t}t}td}	||	 || td}
t|||	||
}nt }}d}d}d}td	}d
}t }|| | | 	 | t||g}|| |!| | || |"t#d||$ |    t }|"t% || || || || || || |$ }|$ }t&t'|| }|(| || }|dk	r|) *||| ||d  t+|d| }t'||||< |S )z3Serialize private key with OpenSSH custom encoding.Nr   zNPasswords longer than 72 bytes are not supported by OpenSSH private key formatzUnsupported key typer   r   r<   r   r8   r'   ),r   r   r.   _MAX_PASSWORDr#   rT   r   EllipticCurvePrivateKeyr%   r$   r	   RSAPrivateKey_SSH_RSAr   DSAPrivateKey_SSH_DSAr   r   _SSH_ED25519r   rJ   _DEFAULT_CIPHERr1   r   _DEFAULT_ROUNDSosurandomrY   rS   r   r7   r   rw   ry   rQ   r   rX   r   rV   rW   r`   Z	encryptorZupdate_intor-   )rn   r   rk   r   Zf_kdfoptionsr2   r   r   r   r   r3   r   r   Zcheckvalr   Zf_public_keyZ	f_secretsZf_mainslenmlenrb   Zofstxtr   r   r   serialize_ssh_private_key(  st    















 r   )r*   r   c          	   C   s  t |}td|  t| }|s*td|d }}|d}d}t|tt d krrd}|dtt  }t	|}yt
t|} W n" ttjfk
r   tdY nX t| \}} ||krtd|rt| \}	} ||| |\}
} |rxt| \}} t| \}} t| \}} t| \}} t| \}} t| \}} t| \}} t| \}} t| \}} t| \}} t| \}} t|  |
S )	z-Load public key from OpenSSH one-line format.r*   zInvalid line formatr      FNTzInvalid key format)r   r   r   _SSH_PUBKEY_RCmatchr#   group_CERT_SUFFIXr.   r   rV   r   r   	TypeErrorErrorr@   rm   r>   r;   r0   )r*   r3   r   rk   Zorig_key_typeZkey_bodyZ	with_certr   Zinner_key_typenoncer$   serialZcctypeZkey_idZ
principalsZvalid_afterZvalid_beforeZcrit_options
extensionsreservedZsig_key	signaturer   r   r   load_ssh_public_key  sH    

r   )r$   r   c             C   s   t | tjrt| }n>t | tjr(t}n,t | tjr:t	}nt | t
jrLt}ntdt|}t }|| || | t|  }d|d|gS )z&One-line public key format for OpenSSHzUnsupported key typer'       )rT   r   r   r%   r	   RSAPublicKeyr   r   DSAPublicKeyr   r   r   r   r#   r   rJ   rY   rw   r   
b2a_base64ra   stripr(   )r$   rk   r   rv   Zpubr   r   r   serialize_ssh_public_key  s    

r   )F)N)N)N)hr   r   restructtypingbase64r   r)   Zcryptographyr   Zcryptography.exceptionsr   Zcryptography.hazmat.backendsr   Z)cryptography.hazmat.primitives.asymmetricr   r   r   r	   Z&cryptography.hazmat.primitives.ciphersr
   r   r   Z,cryptography.hazmat.primitives.serializationr   r   r   r   Zbcryptr   r   Z_bcrypt_supportedImportErrorrU   rC   boolr   r   r   Z_ECDSA_NISTP256Z_ECDSA_NISTP384Z_ECDSA_NISTP521r   compiler   r   Z	_SK_STARTZ_SK_ENDr   r   r   r   r   DOTALLr   rV   rW   ranger   ZAESZCTRZCBCr1   r"   Structr9   r=   r%   r-   r/   r0   r7   r;   r>   r@   rF   rI   objectrJ   rg   rz   r   r   Z	SECP256R1Z	SECP384R1Z	SECP521R1r   r   Unionr   r   r   r   Z_SSH_PRIVATE_KEY_TYPESOptionalr   r   r   r   r   r   Z_SSH_PUBLIC_KEY_TYPESr   r   r   r   r   r   <module>   s   





0>>=:	
LS
+