U
    ʹh                     @  s  U 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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mZmZmZ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"m#Z#m$Z$m%Z% zd dl&m'Z( dZ)W n4 e*k
r"   dZ)ddddddddddZ(Y nX dZ+dZ,dZ-dZ.dZ/dZ0dZ1dZ2dZ3dZ4dZ5e6dZ7d Z8d!Z9d"Z:d#Z;d$Z<d%Z=d&Z>e6e9d' e: ej?Z@eAeBeCd(d)ZDeG d*d+ d+ZEeEejFd,ejGd&d&ddd-eEejFd,ejHd&d&ddd-eEejFd,ejId&d.d&dd-d/ZJd0eKd1< e.e/e0d2ZLd3dd4d5d6ZMd7dd8d9d:ZNe9d; e:d; fd<dddd=d>d?ZOd<dd@dAdBdCZPd<d@dDdEdFZQddGdddHdIdJdKZRdLdMdDdNdOZSdLdMdDdPdQZTdLdRdDdSdTZUdLdMdDdUdVZVdddWdXdYZWG dZd[ d[ZXG d\d] d]ZYG d^d_ d_ZZG d`da daZ[G dbdc dcZ\dRdddedfZ]G dgdh dhZ^G didj djZ_e,eY e-eZ e+e\ e.e[dke` e/e[dlea e0e[dmeb e2e^ e3e_ iZcd<dndodpZdejeejfejgejhejif Zjdddqd<dGdrddsdtdudvZkdsddwddxdydzZlejeejmejnejoejpf Zqejeejmejnejpf ZrG d{d| d|ejsZtG d}d~ d~ZudddddZvdd<ddDddZwd<ddDddZxdLddddZyddddddZzdd<drddddZ{ddd8ddZ|ejeejfejgejif Z}dZ~G dd dZdS )    )annotationsN)encodebytes)	dataclass)utilsUnsupportedAlgorithm)hashes)dsaeced25519paddingrsa)AEADDecryptionContextCipher
algorithmsmodes)EncodingKeySerializationEncryptionNoEncryptionPrivateFormatPublicFormat_KeySerializationEncryption)kdfTFbytesintbool)passwordsaltdesired_key_bytesroundsignore_few_roundsreturnc                 C  s   t dd S )NzNeed bcrypt moduler   )r   r   r   r   r     r"   t/var/www/html/timesheet/backend/venv/lib/python3.8/site-packages/cryptography/hazmat/primitives/serialization/ssh.py_bcrypt_kdf1   s    r$   s   ssh-ed25519s   ssh-rsas   ssh-dsss   ecdsa-sha2-nistp256s   ecdsa-sha2-nistp384s   ecdsa-sha2-nistp521s   -cert-v01@openssh.coms   sk-ssh-ed25519@openssh.coms"   sk-ecdsa-sha2-nistp256@openssh.coms   rsa-sha2-256s   rsa-sha2-512s   \A(\S+)[ \t]+(\S+)s   openssh-key-v1 s#   -----BEGIN OPENSSH PRIVATE KEY-----s!   -----END OPENSSH PRIVATE KEY-----s   bcrypts   none
   aes256-ctr   s   (.*?)      c                   @  sF   e Zd ZU ded< ded< ded< ded< ded< d	ed
< ded< dS )
_SSHCipherztype[algorithms.AES]algr   key_lenz3type[modes.CTR] | type[modes.CBC] | type[modes.GCM]mode	block_leniv_len
int | Nonetag_lenr   is_aeadN)__name__
__module____qualname____annotations__r"   r"   r"   r#   r)   \   s   
r)       )r*   r+   r,   r-   r.   r0   r1      )r%   s
   aes256-cbcs   aes256-gcm@openssh.comzdict[bytes, _SSHCipher]_SSH_CIPHERS)	secp256r1	secp384r1	secp521r1z&SSHPrivateKeyTypes | SSHPublicKeyTypes)keyr!   c                 C  s   t | tjrt|  }nft | tjr0t| }nPt | tjtjfrHt	}n8t | t
jt
jfr`t}n t | tjtjfrxt}ntd|S )NUnsupported key type)
isinstancer
   EllipticCurvePrivateKey_ecdsa_key_type
public_keyEllipticCurvePublicKeyr   RSAPrivateKeyRSAPublicKey_SSH_RSAr	   DSAPrivateKeyDSAPublicKey_SSH_DSAr   Ed25519PrivateKeyEd25519PublicKey_SSH_ED25519
ValueError)r<   key_typer"   r"   r#   _get_ssh_key_type   s    
 
rN   ec.EllipticCurvePublicKeyrA   r!   c                 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: )curvename_ECDSA_KEY_TYPErL   )rA   rQ   r"   r"   r#   r@      s    

r@      
utils.Buffer)dataprefixsuffixr!   c                 C  s   d |t| |gS )N    )join_base64_encode)rV   rW   rX   r"   r"   r#   _ssh_pem_encode   s    r\   None)rV   r-   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)lenrL   )rV   r-   r"   r"   r#   _check_block_size   s    r_   rV   r!   c                 C  s   | rt ddS )z!All data should have been parsed.zCorrupt data: unparsed dataN)rL   rV   r"   r"   r#   _check_empty   s    rb   bytes | Nonez)Cipher[modes.CBC | modes.CTR | modes.GCM])
ciphernamer   r   r   r!   c                 C  sV   |st dt|  }t|||j|j |d}t||d|j |||jd S )z$Generate key + iv and return cipher.z9Key is password-protected, but password was not provided.TN)	TypeErrorr8   r$   r+   r.   r   r*   r,   )rd   r   r   r   ciphseedr"   r"   r#   _init_cipher   s       
  rh   
memoryviewztuple[int, memoryview]c                 C  s6   t | dk rtdtj| dd dd| dd fS )ZUint32   Invalid dataNbig	byteorderr^   rL   r   
from_bytesra   r"   r"   r#   _get_u32   s    rq   c                 C  s6   t | dk rtdtj| dd dd| dd fS )ZUint64   rk   Nrl   rm   ro   ra   r"   r"   r#   _get_u64   s    rs   ztuple[memoryview, memoryview]c                 C  s8   t | \}} |t| kr td| d| | |d fS )zBytes with u32 length prefixrk   N)rq   r^   rL   )rV   nr"   r"   r#   _get_sshstr   s    ru   c                 C  s4   t | \}} |r$|d dkr$tdt|d| fS )zBig integer.r      rk   rl   )ru   rL   r   rp   )rV   valr"   r"   r#   
_get_mpint   s    rx   rw   r!   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 allowedrY   rr   )rL   
bit_lengthr   int_to_bytes)rw   nbytesr"   r"   r#   	_to_mpint   s    r}   c                   @  s   e Zd ZU dZded< d#ddddd	Zd
ddddZdddddZdddddZdddddZ	dddddZ
ddddZd$ddddddZd dd!d"ZdS )%	_FragListz,Build recursive structure without data copy.zlist[utils.Buffer]flistNzlist[utils.Buffer] | Noner]   )initr!   c                 C  s   g | _ |r| j | d S N)r   extend)selfr   r"   r"   r#   __init__  s    z_FragList.__init__rU   ry   c                 C  s   | j | dS )zAdd plain bytesN)r   appendr   rw   r"   r"   r#   put_raw  s    z_FragList.put_rawr   c                 C  s   | j |jddd dS )zBig-endian uint32rj   rl   lengthrn   Nr   r   to_bytesr   r"   r"   r#   put_u32  s    z_FragList.put_u32c                 C  s   | j |jddd dS )zBig-endian uint64rr   rl   r   Nr   r   r"   r"   r#   put_u64  s    z_FragList.put_u64zbytes | _FragListc                 C  sL   t |tttfr,| t| | j| n| |  | j	|j dS )zBytes prefixed with u32 lengthN)
r>   r   ri   	bytearrayr   r^   r   r   sizer   r   r"   r"   r#   
put_sshstr  s
    z_FragList.put_sshstrc                 C  s   |  t| dS )z*Big-endian bigint prefixed with u32 lengthN)r   r}   r   r"   r"   r#   	put_mpint  s    z_FragList.put_mpintr!   c                 C  s   t tt| jS )zCurrent number of bytes)summapr^   r   r   r"   r"   r#   r      s    z_FragList.sizer   ri   )dstbufposr!   c                 C  s2   | j D ]&}t|}|||  }}||||< q|S )zWrite into bytearray)r   r^   )r   r   r   fragZflenstartr"   r"   r#   render$  s
    
z_FragList.renderr   c                 C  s"   t t|  }| | | S )zReturn as bytes)ri   r   r   r   tobytes)r   bufr"   r"   r#   r   ,  s    
z_FragList.tobytes)N)r   )r2   r3   r4   __doc__r5   r   r   r   r   r   r   r   r   r   r"   r"   r"   r#   r~      s   
	r~   c                   @  sf   e Zd ZdZdddddZddddd	Zdd
ddddZddddddZddddddZdS )_SSHFormatRSAzhFormat for RSA keys.

    Public:
        mpint e, n
    Private:
        mpint n, e, d, iqmp, p, q
    ri   z"tuple[tuple[int, int], memoryview]r`   c                 C  s$   t |\}}t |\}}||f|fS )zRSA public fieldsrx   )r   rV   ert   r"   r"   r#   
get_public<  s    z_SSHFormatRSA.get_publicz#tuple[rsa.RSAPublicKey, memoryview]c                 C  s.   |  |\\}}}t||}| }||fS )zMake RSA public key from data.)r   r   RSAPublicNumbersrA   )r   rV   r   rt   public_numbersrA   r"   r"   r#   load_publicD  s    z_SSHFormatRSA.load_publicr   z$tuple[rsa.RSAPrivateKey, memoryview]rV   unsafe_skip_rsa_key_validationr!   c              	   C  s   t |\}}t |\}}t |\}}t |\}}t |\}}t |\}	}||f|kr\tdt||}
t||	}t||}t||	||
|||}|j|d}||fS )zMake RSA private key from data.z Corrupt data: rsa field mismatchr   )rx   rL   r   rsa_crt_dmp1rsa_crt_dmq1r   RSAPrivateNumbersprivate_key)r   rV   	pubfieldsr   rt   r   diqmppqdmp1dmq1r   private_numbersr   r"   r"   r#   load_privateM  s0          z_SSHFormatRSA.load_privatezrsa.RSAPublicKeyr~   r]   rA   f_pubr!   c                 C  s$   |  }||j ||j dS )zWrite RSA public keyN)r   r   r   rt   )r   rA   r   Zpubnr"   r"   r#   encode_publice  s    z_SSHFormatRSA.encode_publiczrsa.RSAPrivateKeyr   f_privr!   c                 C  sZ   |  }|j}||j ||j ||j ||j ||j ||j dS )zWrite RSA private keyN)	r   r   r   rt   r   r   r   r   r   )r   r   r   r   r   r"   r"   r#   encode_privatem  s    z_SSHFormatRSA.encode_privateN	r2   r3   r4   r   r   r   r   r   r   r"   r"   r"   r#   r   3  s   	r   c                   @  sv   e Zd ZdZdddddZddddd	Zdd
ddddZddddddZddddddZdddddZ	dS )_SSHFormatDSAzhFormat for DSA keys.

    Public:
        mpint p, q, g, y
    Private:
        mpint p, q, g, y, x
    ri   ztuple[tuple, memoryview]r`   c                 C  s@   t |\}}t |\}}t |\}}t |\}}||||f|fS )zDSA public fieldsr   )r   rV   r   r   gyr"   r"   r#   r     s
    z_SSHFormatDSA.get_publicz#tuple[dsa.DSAPublicKey, memoryview]c           	      C  sJ   |  |\\}}}}}t|||}t||}| | | }||fS )zMake DSA public key from data.)r   r	   DSAParameterNumbersDSAPublicNumbers	_validaterA   )	r   rV   r   r   r   r   parameter_numbersr   rA   r"   r"   r#   r     s    
z_SSHFormatDSA.load_publicr   z$tuple[dsa.DSAPrivateKey, memoryview]r   c                 C  sz   |  |\\}}}}}t|\}}||||f|kr:tdt|||}	t||	}
| |
 t||
}| }||fS )zMake DSA private key from data.z Corrupt data: dsa field mismatch)	r   rx   rL   r	   r   r   r   DSAPrivateNumbersr   )r   rV   r   r   r   r   r   r   xr   r   r   r   r"   r"   r#   r     s    
z_SSHFormatDSA.load_privatezdsa.DSAPublicKeyr~   r]   r   c                 C  sL   |  }|j}| | ||j ||j ||j ||j dS )zWrite DSA public keyN)r   r   r   r   r   r   r   r   )r   rA   r   r   r   r"   r"   r#   r     s    
z_SSHFormatDSA.encode_publiczdsa.DSAPrivateKeyr   c                 C  s$   |  | | || j dS )zWrite DSA private keyN)r   rA   r   r   r   )r   r   r   r"   r"   r#   r     s    z_SSHFormatDSA.encode_privatezdsa.DSAPublicNumbers)r   r!   c                 C  s    |j }|j dkrtdd S )Ni   z#SSH supports only 1024 bit DSA keys)r   r   rz   rL   )r   r   r   r"   r"   r#   r     s    z_SSHFormatDSA._validateN)
r2   r3   r4   r   r   r   r   r   r   r   r"   r"   r"   r#   r   }  s   r   c                   @  sv   e Zd ZdZdddddZddd	d
dZddd	ddZddddddZddddddZddddddZ	dS )_SSHFormatECDSAzFormat for ECDSA keys.

    Public:
        str curve
        bytes point
    Private:
        str curve
        bytes point
        mpint secret
    r   ec.EllipticCurvessh_curve_namerQ   c                 C  s   || _ || _d S r   r   )r   r   rQ   r"   r"   r#   r     s    z_SSHFormatECDSA.__init__ri   z0tuple[tuple[memoryview, memoryview], memoryview]r`   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   rj   zNeed uncompressed point)ru   r   rL   NotImplementedError)r   rV   rQ   pointr"   r"   r#   r     s    
z_SSHFormatECDSA.get_public,tuple[ec.EllipticCurvePublicKey, memoryview]c                 C  s.   |  |\\}}}tj| j| }||fS z Make ECDSA public key from data.)r   r
   rB   Zfrom_encoded_pointrQ   r   )r   rV   _r   rA   r"   r"   r#   r     s     z_SSHFormatECDSA.load_publicr   z-tuple[ec.EllipticCurvePrivateKey, memoryview]r   c                 C  sH   |  |\\}}}t|\}}||f|kr2tdt|| j}||fS )z!Make ECDSA private key from data.z"Corrupt data: ecdsa field mismatch)r   rx   rL   r
   derive_private_keyrQ   )r   rV   r   r   Z
curve_namer   secretr   r"   r"   r#   r     s    z_SSHFormatECDSA.load_privaterO   r~   r]   r   c                 C  s*   | tjtj}|| j || dS )zWrite ECDSA public keyN)public_bytesr   X962r   UncompressedPointr   r   )r   rA   r   r   r"   r"   r#   r     s     z_SSHFormatECDSA.encode_publiczec.EllipticCurvePrivateKeyr   c                 C  s,   |  }| }| || ||j dS )zWrite ECDSA private keyN)rA   r   r   r   private_value)r   r   r   rA   r   r"   r"   r#   r     s    z_SSHFormatECDSA.encode_privateN)
r2   r3   r4   r   r   r   r   r   r   r   r"   r"   r"   r#   r     s   

r   c                   @  sf   e Zd ZdZdddddZddddd	Zdd
ddddZddddddZddddddZdS )_SSHFormatEd25519z~Format for Ed25519 keys.

    Public:
        bytes point
    Private:
        bytes point
        bytes secret_and_point
    ri   z$tuple[tuple[memoryview], memoryview]r`   c                 C  s   t |\}}|f|fS )zEd25519 public fields)ru   )r   rV   r   r"   r"   r#   r     s    z_SSHFormatEd25519.get_public+tuple[ed25519.Ed25519PublicKey, memoryview]c                 C  s(   |  |\\}}tj| }||fS z"Make Ed25519 public key from data.)r   r   rJ   from_public_bytesr   )r   rV   r   rA   r"   r"   r#   r     s
    z_SSHFormatEd25519.load_publicr   z,tuple[ed25519.Ed25519PrivateKey, memoryview]r   c           	      C  sb   |  |\\}}t|\}}|dd }|dd }||ksF|f|krNtdtj|}||fS )z#Make Ed25519 private key from data.Nr6   z$Corrupt data: ed25519 field mismatch)r   ru   rL   r   rI   from_private_bytes)	r   rV   r   r   r   Zkeypairr   Zpoint2r   r"   r"   r#   r   %  s    z_SSHFormatEd25519.load_privatezed25519.Ed25519PublicKeyr~   r]   r   c                 C  s   | tjtj}|| dS )zWrite Ed25519 public keyN)r   r   Rawr   r   )r   rA   r   raw_public_keyr"   r"   r#   r   3  s
     z_SSHFormatEd25519.encode_publiczed25519.Ed25519PrivateKeyr   c                 C  sR   |  }|tjtjt }|tjtj}t||g}| 	|| |
| dS )zWrite Ed25519 private keyN)rA   private_bytesr   r   r   r   r   r   r~   r   r   )r   r   r   rA   Zraw_private_keyr   Z	f_keypairr"   r"   r#   r   <  s       z _SSHFormatEd25519.encode_privateNr   r"   r"   r"   r#   r   
  s   	
	r   r   c                 C  s2   t | \}} | ds*td| d|| fS )z!
    U2F application strings
    s   ssh:z4U2F application string does not start with b'ssh:' ())ru   r   
startswithrL   )rV   applicationr"   r"   r#   load_applicationM  s    
r   c                   @  s0   e Zd ZdZdddddZddddd	Zd
S )_SSHFormatSKEd25519z
    The format of a sk-ssh-ed25519@openssh.com public key is:

        string		"sk-ssh-ed25519@openssh.com"
        string		public key
        string		application (user-specified, but typically "ssh:")
    ri   r   r`   c                 C  s&   t t|\}}t|\}}||fS r   )_lookup_kformatrK   r   r   r   rV   rA   r   r"   r"   r#   r   c  s    z_SSHFormatSKEd25519.load_publictyping.NoReturnc                 C  s   t dd S )Nz,sk-ssh-ed25519 private keys cannot be loadedr   r   rV   r"   r"   r#   r   k  s    z_SSHFormatSKEd25519.get_publicNr2   r3   r4   r   r   r   r"   r"   r"   r#   r   Z  s   r   c                   @  s0   e Zd ZdZdddddZddddd	Zd
S )_SSHFormatSKECDSAz
    The format of a sk-ecdsa-sha2-nistp256@openssh.com public key is:

        string		"sk-ecdsa-sha2-nistp256@openssh.com"
        string		curve name
        ec_point	Q
        string		application (user-specified, but typically "ssh:")
    ri   r   r`   c                 C  s&   t t|\}}t|\}}||fS r   )r   _ECDSA_NISTP256r   r   r   r"   r"   r#   r   }  s    z_SSHFormatSKECDSA.load_publicr   c                 C  s   t dd S )Nz4sk-ecdsa-sha2-nistp256 private keys cannot be loadedr   r   r"   r"   r#   r     s    z_SSHFormatSKECDSA.get_publicNr   r"   r"   r"   r#   r   s  s   	r   s   nistp256s   nistp384s   nistp521rM   c                 C  s8   t | tst|  } | tkr&t|  S td| dS )z"Return valid format or throw errorzUnsupported key type: N)r>   r   ri   r   _KEY_FORMATSr   r   r"   r"   r#   r     s
    
r   r   z
typing.AnySSHPrivateKeyTypes)rV   r   backendr   r!   c                C  s  t d|  |dk	r t d| t| }|s6td|d}|d}t	t
| || } | tsrtdt
| ttd } t| \}} t| \}} t| \}	} t| \}
} |
dkrtdt| \}} t|\}}t|}||\}}t| |tks|tkr(| }|tkr0td||tkrHtd|t| j}t| j}t| \}} t| jrt| }t||krtd	nt|  t|| t|	\}}t|\}}t| t||| |}| }t
||}t| jrt |t!s
t"t|#| nt|$  n0|r6t%d
t| \}} t|  d}t|| t|\}}t|\}}||krtdt|\}}||krtd|j&|||d\}}t|\}}|t'dt| krtdt |t(j)rt*j+dt j,dd |S )z.Load private key from OpenSSH custom encoding.rV   Nr   zNot OpenSSH private key formatr'   zOnly one key supportedzUnsupported cipher: zUnsupported KDF: z+Corrupt data: invalid tag length for cipherz4Password was given but private key is not encrypted.rr   zCorrupt data: broken checksumzCorrupt data: key type mismatchr   zCorrupt data: invalid paddingDSSH DSA keys are deprecated and will be removed in a future release.   
stacklevel)-r   _check_byteslike_check_bytes_PEM_RCsearchrL   r   endbinascii
a2b_base64ri   r   	_SK_MAGICr^   ru   rq   r   r   rb   _NONEr   r8   r   _BCRYPTr-   r0   r1   r   r_   rh   	decryptorupdater>   r   AssertionErrorfinalize_with_tagfinalizere   r   _PADDINGr	   rF   warningswarnDeprecatedIn40)rV   r   r   r   mp1Zp2rd   kdfnameZ
kdfoptionsnkeysZpubdataZpub_key_typekformatr   Zciphername_bytesblklenr0   Zedatatagr   Zkbufr   rf   decck1ck2rM   r   r   r"   r"   r#   load_ssh_private_key  s    













r  r   )r   r   encryption_algorithmr!   c                 C  s  t d| t| tjr*tjdt jdd t| }t	|}t
 }|rt}t| j}t}t}	t|trt|jdk	rt|j}	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| S )
z3Serialize private key with OpenSSH custom encoding.r   ISSH DSA key support is deprecated and will be removed in a future releaserj   r   Nr&   rr   r'   rY   )%r   r   r>   r	   rF   r   r  r  rN   r   r~   _DEFAULT_CIPHERr8   r-   r   _DEFAULT_ROUNDSr   _kdf_roundsosurandomr   r   rh   r   r   rA   r   r   r   r   r   ri   r   r   	encryptorupdate_intor\   )r   r   r  rM   r  Zf_kdfoptionsrd   r  r  r   r   rf   r  ZcheckvalcommentZf_public_keyZ	f_secretsZf_mainslenmlenr   Zofsr"   r"   r#   _serialize_ssh_private_key  sl    
















 r  c                   @  s   e Zd ZdZdZdS )SSHCertificateTyper'   r   N)r2   r3   r4   USERZHOSTr"   r"   r"   r#   r  w  s   r  c                   @  s  e Zd Zdddddddddddddddddddd	Zedd
ddZdd
ddZedd
ddZedd
ddZedd
ddZ	edd
ddZ
edd
ddZedd
ddZedd
ddZedd
dd Zdd
d!d"Zdd
d#d$Zd%d
d&d'Zd(S ))SSHCertificateri   SSHPublicKeyTypesr   list[bytes]dict[bytes, bytes]r   )_nonce_public_key_serial_cctype_key_id_valid_principals_valid_after_valid_before_critical_options_extensions	_sig_type_sig_key_inner_sig_type
_signature_tbs_cert_body_cert_key_type
_cert_bodyc                 C  s   || _ || _|| _zt|| _W n tk
r<   tdY nX || _|| _|| _|| _	|	| _
|
| _|| _|| _|| _|| _|| _|| _|| _d S )NzInvalid certificate type)r!  r"  r#  r  _typerL   r%  r&  r'  r(  r)  r*  r+  r,  r-  r.  r0  r1  r/  )r   r!  r"  r#  r$  r%  r&  r'  r(  r)  r*  r+  r,  r-  r.  r/  r0  r1  r"   r"   r#   r   }  s(    zSSHCertificate.__init__r   c                 C  s
   t | jS r   )r   r!  r   r"   r"   r#   nonce  s    zSSHCertificate.nonceSSHCertPublicKeyTypesc                 C  s   t t| jS r   )typingcastr4  r"  r   r"   r"   r#   rA     s    zSSHCertificate.public_keyc                 C  s   | j S r   )r#  r   r"   r"   r#   serial  s    zSSHCertificate.serialr  c                 C  s   | j S r   )r2  r   r"   r"   r#   type  s    zSSHCertificate.typec                 C  s
   t | jS r   )r   r%  r   r"   r"   r#   key_id  s    zSSHCertificate.key_idc                 C  s   | j S r   )r&  r   r"   r"   r#   valid_principals  s    zSSHCertificate.valid_principalsc                 C  s   | j S r   )r(  r   r"   r"   r#   valid_before  s    zSSHCertificate.valid_beforec                 C  s   | j S r   )r'  r   r"   r"   r#   valid_after  s    zSSHCertificate.valid_afterc                 C  s   | j S r   )r)  r   r"   r"   r#   critical_options  s    zSSHCertificate.critical_optionsc                 C  s   | j S r   )r*  r   r"   r"   r#   
extensions  s    zSSHCertificate.extensionsc                 C  s&   t | j}|| j\}}t| |S r   )r   r+  r   r,  rb   )r   Z	sigformatsignature_keyZsigkey_restr"   r"   r#   r?    s    
zSSHCertificate.signature_keyc                 C  s"   t | jd tjt | jdd S )N    F)newline)r   r0  r   
b2a_base64r1  r   r"   r"   r#   r     s    zSSHCertificate.public_bytesr]   c                 C  s   |   }t|tjr.|t| jt| j nt|tj	rt
| j\}}t
|\}}t| t||}t|j}||t| jt| nnt|tjst| jtkrt }n*| jtkrt }n| jtkstt }|t| jt| jt | d S r   )r?  r>   r   rJ   verifyr   r.  r/  r
   rB   rx   rb   
asym_utilsencode_dss_signature_get_ec_hash_algrQ   ECDSAr   rD   r   r-  rE   r   SHA1_SSH_RSA_SHA256SHA256_SSH_RSA_SHA512SHA512r   PKCS1v15)r   r?  rrV   sZcomputed_sighash_algr"   r"   r#   verify_cert_signature  s<     
  



z$SSHCertificate.verify_cert_signatureN)r2   r3   r4   r   propertyr3  rA   r7  r8  r9  r:  r;  r<  r=  r>  r?  r   rQ  r"   r"   r"   r#   r  |  s.   .)r  r   zhashes.HashAlgorithm)rQ   r!   c                 C  sD   t | tjrt S t | tjr(t S t | tjs8tt	 S d S r   )
r>   r
   	SECP256R1r   rJ  	SECP384R1SHA384	SECP521R1r   rL  )rQ   r"   r"   r#   rF    s    rF  z"SSHCertificate | SSHPublicKeyTypesc           "      C  s  t d|  t| }|s"td|d }}|d}d}|tr^d}|d tt  }|t	krr|srt
dt|}ztt|}W n" ttjfk
r   tdY nX |r|}	t|\}
}|
|krtd	|rt|\}}||\}}|rpt|\}}t|\}}t|\}}t|\}}g }|rPt|\}}|t| q,t|\}}t|\}}t|\}}t|}t|\}}t|}t|\}}t|\}}t|\}}|t	kr|st
d
|	d t|  }t|\}}t| t|\}} |tkr|tttfks,|tkr4||kr4tdt| \}!} t|  t||||||||||||||!|||	S t| |S d S )NrV   zInvalid line formatr'   r   FTz-DSA keys aren't supported in SSH certificateszInvalid formatzInvalid key formatz3DSA signatures aren't supported in SSH certificatesz!Signature key type does not match)r   r   _SSH_PUBKEY_RCmatchrL   groupendswith_CERT_SUFFIXr^   rH   r   r   ri   r   r   re   Errorru   r   rs   rq   r   r   _parse_exts_optsrb   rE   rI  rK  r  )"rV   _legacy_dsa_allowedr  rM   Zorig_key_typeZkey_bodyZ	with_certr  restZ	cert_bodyZinner_key_typer3  rA   r7  Zcctyper9  Z
principalsr:  Z	principalr<  r;  Zcrit_optionsr=  extsr>  r   Zsig_key_rawZsig_typeZsig_keyZtbs_cert_bodyZsignature_rawZinner_sig_typeZsig_rest	signaturer"   r"   r#   _load_ssh_public_identity  s    


rb  c                 C  s   t | S r   )rb  ra   r"   r"   r#   load_ssh_public_identityf  s    rc  r   )	exts_optsr!   c                 C  s   i }d }| rt | \}} t|}||kr0td|d k	rH||k rHtdt | \}} t|dkrt |\}}t|dkrtdt|||< |}q|S )NzDuplicate namezFields not lexically sortedr   z!Unexpected extra data after value)ru   r   rL   r^   )rd  result	last_namerR   Zbnamevalueextrar"   r"   r#   r]  l  s"    r]  r  zhashes.MD5 | hashes.SHA256)r<   hash_algorithmr!   c                 C  sj   t |tjtjfstdt| }t|}t }|| |	| | |
 }t|}|| | S )Nz+hash_algorithm must be either MD5 or SHA256)r>   r   MD5rJ  re   rN   r   r~   r   r   r   Hashr   r   )r<   ri  rM   r  r   Zssh_binary_dataZhash_objr"   r"   r#   ssh_key_fingerprint  s    


rl  )rV   r   r!   c                 C  sF   t | dd}t|tr | }n|}t|tjrBtjdtj	dd |S )NT)r^  r   r   r   )
rb  r>   r  rA   r	   rG   r   r  r   r  )rV   r   Zcert_or_keyrA   r"   r"   r#   load_ssh_public_key  s    

rm  c                 C  sl   t | tjrtjdtjdd t| }t|}t	 }|
| || | t|  }d|d|gS )z&One-line public key format for OpenSSHr  rj   r   rY   r@  )r>   r	   rG   r   r  r   r  rN   r   r~   r   r   r   rB  r   striprZ   )rA   rM   r  r   Zpubr"   r"   r#   serialize_ssh_public_key  s    
ro     c                   @  s   e Zd Zddddg dddg g f
ddddddddd	d	d

ddZdd dddZdd dddZdd dddZdd dddZdd dddZd d! Z	d"d d#d$d%Z
d"d d&d'd(Zddd d)d*d+Zddd d)d,d-Zd.d/d0d1d2ZdS )3SSHCertificateBuilderNFzSSHCertPublicKeyTypes | Noner/   zSSHCertificateType | Nonerc   r  r   zlist[tuple[bytes, bytes]]
r"  r#  r2  r%  r&  _valid_for_all_principalsr(  r'  r)  r*  c                 C  s@   || _ || _|| _|| _|| _|| _|| _|| _|	| _|
| _	d S r   rr  )r   r"  r#  r2  r%  r&  rs  r(  r'  r)  r*  r"   r"   r#   r     s    zSSHCertificateBuilder.__init__r4  rP   c                 C  s^   t |tjtjtjfstd| jd k	r0t	dt
|| j| j| j| j| j| j| j| j| jd
S )Nr=   zpublic_key already setrr  )r>   r
   rB   r   rD   r   rJ   re   r"  rL   rq  r#  r2  r%  r&  rs  r(  r'  r)  r*  )r   rA   r"   r"   r#   rA     s,    
z SSHCertificateBuilder.public_keyr   )r7  r!   c                 C  sp   t |tstdd|  kr&dk s0n td| jd k	rBtdt| j|| j| j| j	| j
| j| j| j| jd
S )Nzserial must be an integerr               z"serial must be between 0 and 2**64zserial already setrr  )r>   r   re   rL   r#  rq  r"  r2  r%  r&  rs  r(  r'  r)  r*  )r   r7  r"   r"   r#   r7    s$    

zSSHCertificateBuilder.serialr  )r8  r!   c                 C  sR   t |tstd| jd k	r$tdt| j| j|| j| j	| j
| j| j| j| jd
S )Nz"type must be an SSHCertificateTypeztype already setrr  )r>   r  re   r2  rL   rq  r"  r#  r%  r&  rs  r(  r'  r)  r*  )r   r8  r"   r"   r#   r8    s     

zSSHCertificateBuilder.typer   )r9  r!   c                 C  sR   t |tstd| jd k	r$tdt| j| j| j|| j	| j
| j| j| j| jd
S )Nzkey_id must be byteszkey_id already setrr  )r>   r   re   r%  rL   rq  r"  r#  r2  r&  rs  r(  r'  r)  r*  )r   r9  r"   r"   r#   r9  '  s     

zSSHCertificateBuilder.key_id)r:  r!   c                 C  s|   | j rtdtdd |D r$|s,td| jr:tdt|tkrNtdt| j| j	| j
| j|| j | j| j| j| jd
S )NzDPrincipals can't be set because the cert is valid for all principalsc                 s  s   | ]}t |tV  qd S r   )r>   r   ).0r   r"   r"   r#   	<genexpr>C  s     z9SSHCertificateBuilder.valid_principals.<locals>.<genexpr>z5principals must be a list of bytes and can't be emptyzvalid_principals already setz:Reached or exceeded the maximum number of valid_principalsrr  )rs  rL   allre   r&  r^   _SSHKEY_CERT_MAX_PRINCIPALSrq  r"  r#  r2  r%  r(  r'  r)  r*  )r   r:  r"   r"   r#   r:  :  s:    z&SSHCertificateBuilder.valid_principalsc                 C  sJ   | j rtd| jrtdt| j| j| j| j| j d| j| j	| j
| jd
S )Nz@valid_principals already set, can't set valid_for_all_principalsz$valid_for_all_principals already setTrr  )r&  rL   rs  rq  r"  r#  r2  r%  r(  r'  r)  r*  r   r"   r"   r#   valid_for_all_principals^  s$    z.SSHCertificateBuilder.valid_for_all_principalszint | float)r;  r!   c                 C  sv   t |ttfstdt|}|dk s.|dkr6td| jd k	rHtdt| j| j| j	| j
| j| j|| j| j| jd
S )Nz$valid_before must be an int or floatr   rt  zvalid_before must [0, 2**64)zvalid_before already setrr  )r>   r   floatre   rL   r(  rq  r"  r#  r2  r%  r&  rs  r'  r)  r*  )r   r;  r"   r"   r#   r;  t  s&    
z"SSHCertificateBuilder.valid_before)r<  r!   c                 C  sv   t |ttfstdt|}|dk s.|dkr6td| jd k	rHtdt| j| j| j	| j
| j| j| j|| j| jd
S )Nz#valid_after must be an int or floatr   rt  zvalid_after must [0, 2**64)zvalid_after already setrr  )r>   r   rz  re   rL   r'  rq  r"  r#  r2  r%  r&  rs  r(  r)  r*  )r   r<  r"   r"   r#   r<    s&    
z!SSHCertificateBuilder.valid_after)rR   rg  r!   c                 C  sr   t |trt |tstd|dd | jD kr8tdt| j| j| j| j	| j
| j| j| j| j||ff| jd
S )Nname and value must be bytesc                 S  s   g | ]\}}|qS r"   r"   ru  rR   r   r"   r"   r#   
<listcomp>  s     z=SSHCertificateBuilder.add_critical_option.<locals>.<listcomp>zDuplicate critical option namerr  )r>   r   re   r)  rL   rq  r"  r#  r2  r%  r&  rs  r(  r'  r*  r   rR   rg  r"   r"   r#   add_critical_option  s     z)SSHCertificateBuilder.add_critical_optionc                 C  sr   t |trt |tstd|dd | jD kr8tdt| j| j| j| j	| j
| j| j| j| j| j||ffd
S )Nr{  c                 S  s   g | ]\}}|qS r"   r"   r|  r"   r"   r#   r}    s     z7SSHCertificateBuilder.add_extension.<locals>.<listcomp>zDuplicate extension namerr  )r>   r   re   r*  rL   rq  r"  r#  r2  r%  r&  rs  r(  r'  r)  r~  r"   r"   r#   add_extension  s     z#SSHCertificateBuilder.add_extensionSSHCertPrivateKeyTypesr  )r   r!   c              	   C  s  t |tjtjtjfstd| jd kr0t	d| j
d kr>dn| j
}| jd krVt	d| jd krddn| j}| js~| js~t	d| jd krt	d| jd krt	d| j| jkrt	d	| jjd
d d | jjdd d t| j}|t }td}t|}t }|| || || j| || || jj || t }	| jD ]}
|	|
 qT||	  || j || j t }| jD ]L\}}|| t |dkrt }|| ||  n
|| q||  t }| jD ]L\}}|| t |dkr@t }|| ||  n
|| q ||  |d t|}t|}t }|| ||! | ||  t |tjr|"| }t }|| || ||  nt |tjrnt#|j$}|"| t%|}t&'|\}}t }|| t }|(| |(| ||  ||  nTt |tjst)t }|t* |"| t+, t-. }|| ||  t/0| 1 }t23t4t5d6|d|gS )NzUnsupported private key typezpublic_key must be setr   ztype must be setrY   zAvalid_principals must be set if valid_for_all_principals is Falsezvalid_before must be setzvalid_after must be setz-valid_after must be earlier than valid_beforec                 S  s   | d S Nr   r"   r   r"   r"   r#   <lambda>  rY   z,SSHCertificateBuilder.sign.<locals>.<lambda>)r<   c                 S  s   | d S r  r"   r  r"   r"   r#   r    rY   r6   r@  )7r>   r
   r?   r   rC   r   rI   re   r"  rL   r#  r2  r%  r&  rs  r(  r'  r)  sortr*  rN   r[  r  r  r   r~   r   r   r   r   rg  r   r^   rA   signrF  rQ   rG  rD  decode_dss_signaturer   r   rK  r   rM  r   rL  r   rB  rn  r5  r6  r  rc  rZ   )r   r   r7  r9  rM   Zcert_prefixr3  r  fZfprincipalsr   ZfcritrR   rg  ZfoptvalZfextZfextvalZca_typeZcaformatZcafra  ZfsigrP  rN  rO  ZfsigblobZ	cert_datar"   r"   r#   r    s    























  
zSSHCertificateBuilder.sign)r2   r3   r4   r   rA   r7  r8  r9  r:  ry  r;  r<  r  r  r  r"   r"   r"   r#   rq    s,   "$rq  )F)N)F)N)
__future__r   r   enumr  rer5  r   base64r   r[   dataclassesr   cryptographyr   cryptography.exceptionsr   cryptography.hazmat.primitivesr   )cryptography.hazmat.primitives.asymmetricr	   r
   r   r   r   rD  &cryptography.hazmat.primitives.ciphersr   r   r   r   ,cryptography.hazmat.primitives.serializationr   r   r   r   r   r   bcryptr   r$   Z_bcrypt_supportedImportErrorrK   rE   rH   r   Z_ECDSA_NISTP384Z_ECDSA_NISTP521r[  Z_SK_SSH_ED25519Z_SK_SSH_ECDSA_NISTP256rI  rK  compilerW  r   Z	_SK_STARTZ_SK_ENDr   r   r  r  DOTALLr   ri   r   ranger   r)   AESZCTRCBCGCMr8   r5   rS   rN   r@   r\   r_   rb   rh   rq   rs   ru   rx   r}   r~   r   r   r   r   r   r   r   rS  rT  rV  r   r   Unionr?   rC   rF   rI   r   r  r  rB   rD   rG   rJ   r  r4  Enumr  r  rF  rb  rc  r]  rl  rm  ro  r  rx  rq  r"   r"   r"   r#   <module>   sD    	  

		 
6JFGC        	 rM  _ 	