o
    Z2h                     @  sB  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 n e*y   dZ)	ddddZ(Y nw 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/d0 d0ZEeEejFd1ejGd+d+ddd2eEejFd1ejHd+d+ddd2eEejFd1ejId+d3d+dd2d4ZJd5eKd6< e.e/e0d7ZLdd:d;ZMdd>d?ZNe9d@ e:d@ fddEdFZOddIdJZPddKdLZQddPdQZRddTdUZSddVdWZTddYdZZUdd[d\ZVdd^d_ZWG d`da daZXG dbdc dcZYG ddde deZZG dfdg dgZ[G dhdi diZ\ddjdkZ]G dldm dmZ^G dndo doZ_e,eY e-eZ e+e\ e.e[dpe` e/e[dqea e0e[dreb e2e^ e3e_ iZcddtduZdejeejfejgejhejif Zj	dddvdd{d|ZkdddZlejeejmejnejoejpf Zqejeejmejnejpf ZrG dd dejsZtG dd dZudddZv	ddddZwdddZxdddZydddZz	ddddZ{ddd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passwordbytessaltdesired_key_bytesintroundsignore_few_roundsboolreturnc                 C     t d)NzNeed bcrypt moduler   )r   r   r   r   r    r#   /home/skpark/git/infrasmart_work/infrasmart/venv/lib/python3.10/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/   r1   r2      )r&   s
   aes256-cbcs   aes256-gcm@openssh.comzdict[bytes, _SSHCipher]_SSH_CIPHERS)	secp256r1	secp384r1	secp521r1key&SSHPrivateKeyTypes | SSHPublicKeyTypesc                 C  s   t | tjrt|  }|S t | tjrt| }|S t | tjtjfr't	}|S t | t
jt
jfr4t}|S t | tjtjfrAt}|S td)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$   
rP   rC   ec.EllipticCurvePublicKeyc                 C  s*   | j }|jtv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_TYPErN   )rC   rR   r#   r#   r$   rB      s   


rB      
datautils.Bufferprefixsuffixc                 C  s   d |t| |gS )N    )join_base64_encode)rV   rX   rY   r#   r#   r$   _ssh_pem_encode   s   r]   r.   Nonec                 C  s    | r
t | | dkrtddS )zRequire data to be full blocksr   zCorrupt data: missing paddingN)lenrN   )rV   r.   r#   r#   r$   _check_block_size   s   r`   c                 C  s   | rt ddS )z!All data should have been parsed.zCorrupt data: unparsed dataN)rN   rV   r#   r#   r$   _check_empty   s   rb   
ciphernamebytes | None)Cipher[modes.CBC | modes.CTR | modes.GCM]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)	TypeErrorr9   r%   r,   r/   r   r+   r-   )rc   r   r   r   ciphseedr#   r#   r$   _init_cipher   s   ri   
memoryviewtuple[int, memoryview]c                 C  6   t | dk r
tdtj| dd dd| dd fS )Uint32   Invalid dataNbig	byteorderr_   rN   r   
from_bytesra   r#   r#   r$   _get_u32      "ru   c                 C  rl   )Uint64   ro   Nrp   rq   rs   ra   r#   r#   r$   _get_u64   rv   ry   tuple[memoryview, memoryview]c                 C  s8   t | \}} |t| krtd| d| | |d fS )zBytes with u32 length prefixro   N)ru   r_   rN   )rV   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      ro   rp   )r|   rN   r   rt   )rV   valr#   r#   r$   
_get_mpint   s   r   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 allowedrZ   rx   )rN   
bit_lengthr   int_to_bytes)r~   nbytesr#   r#   r$   	_to_mpint   s   r   c                   @  sx   e Zd ZU dZded< d$d%d	d
Zd&ddZd'ddZd'ddZd(ddZ	d'ddZ
d)ddZd*d+dd Zd,d"d#ZdS )-	_FragListz,Build recursive structure without data copy.zlist[utils.Buffer]flistNinitlist[utils.Buffer] | Noner!   r^   c                 C  s   g | _ |r| j | d S d S N)r   extend)selfr   r#   r#   r$   __init__  s   z_FragList.__init__r~   rW   c                 C  s   | j | dS )zAdd plain bytesN)r   appendr   r~   r#   r#   r$   put_raw     z_FragList.put_rawr   c                 C     | j |jddd dS )zBig-endian uint32rn   rp   lengthrr   Nr   r   to_bytesr   r#   r#   r$   put_u32     z_FragList.put_u32c                 C  r   )zBig-endian uint64rx   rp   r   Nr   r   r#   r#   r$   put_u64  r   z_FragList.put_u64bytes | _FragListc                 C  sN   t |tttfr| t| | j| dS | |  | j	|j dS )zBytes prefixed with u32 lengthN)
r@   r   rj   	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_mpintc                 C  s   t tt| jS )zCurrent number of bytes)summapr_   r   r   r#   r#   r$   r      r   z_FragList.sizer   dstbufrj   posc                 C  s2   | j D ]}t|}||| }}||||< q|S )zWrite into bytearray)r   r_   )r   r   r   fragflenstartr#   r#   r$   render$  s
   
z_FragList.renderr   c                 C  s"   t t|  }| | | S )zReturn as bytes)rj   r   r   r   tobytes)r   bufr#   r#   r$   r   ,  s   
z_FragList.tobytesr   )r   r   r!   r^   )r~   rW   r!   r^   )r~   r   r!   r^   )r~   r   r!   r^   r!   r   )r   )r   rj   r   r   r!   r   r!   r   )r3   r4   r5   __doc__r6   r   r   r   r   r   r   r   r   r   r#   r#   r#   r$   r      s   
 




	
r   c                   @  B   e Zd ZdZdddZdd	d
ZdddZd ddZd!ddZdS )"_SSHFormatRSAzhFormat for RSA keys.

    Public:
        mpint e, n
    Private:
        mpint n, e, d, iqmp, p, q
    rV   rj   r!   "tuple[tuple[int, int], memoryview]c                 C  s$   t |\}}t |\}}||f|fS )zRSA public fieldsr   )r   rV   er{   r#   r#   r$   
get_public<  s   z_SSHFormatRSA.get_public#tuple[rsa.RSAPublicKey, memoryview]c                 C  s.   |  |\\}}}t||}| }||fS )zMake RSA public key from data.)r   r   RSAPublicNumbersrC   )r   rV   r   r{   public_numbersrC   r#   r#   r$   load_publicD  s   z_SSHFormatRSA.load_publicunsafe_skip_rsa_key_validationr    $tuple[rsa.RSAPrivateKey, memoryview]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   )r   rN   r   rsa_crt_dmp1rsa_crt_dmq1r   RSAPrivateNumbersprivate_key)r   rV   	pubfieldsr   r{   r   diqmppqdmp1dmq1r   private_numbersr   r#   r#   r$   load_privateM  s$   z_SSHFormatRSA.load_privaterC   rsa.RSAPublicKeyf_pubr   r^   c                 C  s$   |  }||j ||j dS )zWrite RSA public keyN)r   r   r   r{   )r   rC   r   pubnr#   r#   r$   encode_publice  s   z_SSHFormatRSA.encode_publicr   rsa.RSAPrivateKeyf_privc                 C  sZ   |  }|j}||j ||j ||j ||j ||j ||j dS )zWrite RSA private keyN)	r   r   r   r{   r   r   r   r   r   )r   r   r   r   r   r#   r#   r$   encode_privatem  s   z_SSHFormatRSA.encode_privateN)rV   rj   r!   r   )rV   rj   r!   r   )rV   rj   r   r    r!   r   )rC   r   r   r   r!   r^   )r   r   r   r   r!   r^   	r3   r4   r5   r   r   r   r   r   r   r#   r#   r#   r$   r   3  s    


	
r   c                   @  sL   e Zd ZdZd!ddZd"d	d
Zd#ddZd$ddZd%ddZd&ddZ	d S )'_SSHFormatDSAzhFormat for DSA keys.

    Public:
        mpint p, q, g, y
    Private:
        mpint p, q, g, y, x
    rV   rj   r!   tuple[tuple, memoryview]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_public#tuple[dsa.DSAPublicKey, memoryview]c           	      C  sJ   |  |\\}}}}}t|||}t||}| | | }||fS )zMake DSA public key from data.)r   r	   DSAParameterNumbersDSAPublicNumbers	_validaterC   )	r   rV   r   r   r   r   parameter_numbersr   rC   r#   r#   r$   r     s   
z_SSHFormatDSA.load_publicr   r    $tuple[dsa.DSAPrivateKey, memoryview]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   r   rN   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_privaterC   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   rC   r   r   r   r#   r#   r$   r     s   
z_SSHFormatDSA.encode_publicr   dsa.DSAPrivateKeyr   c                 C  s$   |  | | || j dS )zWrite DSA private keyN)r   rC   r   r   r   )r   r   r   r#   r#   r$   r     s   z_SSHFormatDSA.encode_privater   dsa.DSAPublicNumbersc                 C  s    |j }|j dkrtdd S )Ni   z#SSH supports only 1024 bit DSA keys)r   r   r   rN   )r   r   r   r#   r#   r$   r     s   z_SSHFormatDSA._validateN)rV   rj   r!   r   )rV   rj   r!   r   )rV   rj   r   r    r!   r   )rC   r   r   r   r!   r^   )r   r   r   r   r!   r^   )r   r   r!   r^   )
r3   r4   r5   r   r   r   r   r   r   r   r#   r#   r#   r$   r   }  s    




r   c                   @  sL   e Zd ZdZd#ddZd$ddZd%ddZd&ddZd'ddZd(d d!Z	d"S ))_SSHFormatECDSAzFormat for ECDSA keys.

    Public:
        str curve
        bytes point
    Private:
        str curve
        bytes point
        mpint secret
    ssh_curve_namer   rR   ec.EllipticCurvec                 C  s   || _ || _d S r   )r   rR   )r   r   rR   r#   r#   r$   r     s   
z_SSHFormatECDSA.__init__rV   rj   r!   0tuple[tuple[memoryview, memoryview], memoryview]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   rn   zNeed uncompressed point)r|   r   rN   NotImplementedError)r   rV   rR   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
   rD   from_encoded_pointrR   r   )r   rV   _r   rC   r#   r#   r$   r     s
   
z_SSHFormatECDSA.load_publicr   r    -tuple[ec.EllipticCurvePrivateKey, memoryview]c                 C  sH   |  |\\}}}t|\}}||f|krtdt|| j}||fS )z!Make ECDSA private key from data.z"Corrupt data: ecdsa field mismatch)r   r   rN   r
   derive_private_keyrR   )r   rV   r   r   
curve_namer   secretr   r#   r#   r$   r     s   z_SSHFormatECDSA.load_privaterC   rQ   r   r   r^   c                 C  s*   | tjtj}|| j || dS )zWrite ECDSA public keyN)public_bytesr   X962r   UncompressedPointr   r   )r   rC   r   r   r#   r#   r$   r     s
   z_SSHFormatECDSA.encode_publicr   ec.EllipticCurvePrivateKeyr   c                 C  s,   |  }| }| || ||j dS )zWrite ECDSA private keyN)rC   r   r   r   private_value)r   r   r   rC   r   r#   r#   r$   r     s   z_SSHFormatECDSA.encode_privateN)r   r   rR   r   )rV   rj   r!   r   rV   rj   r!   r   )rV   rj   r   r    r!   r   )rC   rQ   r   r   r!   r^   )r   r   r   r   r!   r^   )
r3   r4   r5   r   r   r   r   r   r   r   r#   r#   r#   r$   r     s    






r   c                   @  r   )"_SSHFormatEd25519z~Format for Ed25519 keys.

    Public:
        bytes point
    Private:
        bytes point
        bytes secret_and_point
    rV   rj   r!   $tuple[tuple[memoryview], memoryview]c                 C  s   t |\}}|f|fS )zEd25519 public fields)r|   )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   rL   from_public_bytesr   )r   rV   r   rC   r#   r#   r$   r     s
   z_SSHFormatEd25519.load_publicr   r    ,tuple[ed25519.Ed25519PrivateKey, memoryview]c           	      C  sb   |  |\\}}t|\}}|dd }|dd }||ks#|f|kr'tdtj|}||fS )z#Make Ed25519 private key from data.Nr7   z$Corrupt data: ed25519 field mismatch)r   r|   rN   r   rK   from_private_bytes)	r   rV   r   r   r   keypairr   point2r   r#   r#   r$   r   %  s   z_SSHFormatEd25519.load_privaterC   ed25519.Ed25519PublicKeyr   r   r^   c                 C  s   | tjtj}|| dS )zWrite Ed25519 public keyN)r   r   Rawr   r   )r   rC   r   raw_public_keyr#   r#   r$   r   3  s   z_SSHFormatEd25519.encode_publicr   ed25519.Ed25519PrivateKeyr   c                 C  sR   |  }|tjtjt }|tjtj}t||g}| 	|| |
| dS )zWrite Ed25519 private keyN)rC   private_bytesr   r   r   r   r   r   r   r   r   )r   r   r   rC   raw_private_keyr   	f_keypairr#   r#   r$   r   <  s   z _SSHFormatEd25519.encode_privateN)rV   rj   r!   r   rV   rj   r!   r   )rV   rj   r   r    r!   r   )rC   r   r   r   r!   r^   )r   r   r   r   r!   r^   r   r#   r#   r#   r$   r   
  s    
	



	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:' ())r|   r   
startswithrN   )rV   applicationr#   r#   r$   load_applicationM  s   r  c                   @  $   e Zd ZdZdddZ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:")
    rV   rj   r!   r   c                 C  &   t t|\}}t|\}}||fS r   )_lookup_kformatrM   r   r  r   rV   rC   r   r#   r#   r$   r   c     z_SSHFormatSKEd25519.load_publictyping.NoReturnc                 C  r"   )Nz,sk-ssh-ed25519 private keys cannot be loadedr   r   rV   r#   r#   r$   r   k     z_SSHFormatSKEd25519.get_publicNr   rV   rj   r!   r  r3   r4   r5   r   r   r   r#   r#   r#   r$   r  Z  s    
r  c                   @  r  )_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:")
    rV   rj   r!   r   c                 C  r  r   )r  _ECDSA_NISTP256r   r  r	  r#   r#   r$   r   }  r
  z_SSHFormatSKECDSA.load_publicr  c                 C  r"   )Nz4sk-ecdsa-sha2-nistp256 private keys cannot be loadedr   r  r#   r#   r$   r     r  z_SSHFormatSKECDSA.get_publicNr   r  r  r#   r#   r#   r$   r  s  s    
	r  s   nistp256s   nistp384s   nistp521rO   c                 C  s4   t | tst|  } | tv rt|  S td| )z"Return valid format or throw errorzUnsupported key type: )r@   r   rj   r   _KEY_FORMATSr   )rO   r#   r#   r$   r    s
   
r  r   backend
typing.Anyr   SSHPrivateKeyTypesc                C  s  t d|  |durt d| t| }|std|d}|d}t	t
| || } | ts9tdt
| ttd } t| \}} t| \}} t| \}	} t| \}
} |
dkrctdt| \}} t|\}}t|}||\}}t| |tks|tkr| }|tvrtd||tkrt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!sJ t|"| nt|#  n|rt$d
t| \}} t|  d}t|| t|\}}t|\}}||kr;tdt|\}}||krJtd|j%|||d\}}t|\}}|t&dt| kritdt |t'j(ryt)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.rx   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searchrN   r   endbinascii
a2b_base64rj   r  	_SK_MAGICr_   r|   ru   r  r   rb   _NONEr   r9   r   _BCRYPTr.   r1   r2   r   r`   ri   	decryptorupdater@   r   finalize_with_tagfinalizerf   r   _PADDINGr	   rH   warningswarnDeprecatedIn40)rV   r   r  r   mp1p2rc   kdfname
kdfoptionsnkeyspubdatapub_key_typekformatr   ciphername_bytesblklenr1   edatatagr   kbufr   rg   decck1ck2rO   r   r   r#   r#   r$   load_ssh_private_key  s   











r=  r   encryption_algorithmr   c                 C  s  t d| t| tjrtjdt jdd t| }t	|}t
 }|rQt}t| j}t}t}	t|tr:|jdur:|j}	td}
||
 ||	 t|||
|	}nt }}d}d}d}td}d	}t
 }|| ||  | t
||g}|| || | || |td|| |    t
 }|t || || || || || || | }| }tt || }|!| || }|du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 releasern   r  Nr'   rx   r(   rZ   )%r   r  r@   r	   rH   r)  r*  r+  rP   r  r   _DEFAULT_CIPHERr9   r.   r#  _DEFAULT_ROUNDSr   _kdf_roundsosurandomr   r   ri   r"  r   rC   r   r   r(  r   r!  rj   r   r   	encryptorupdate_intor]   )r   r   r>  rO   r4  f_kdfoptionsrc   r6  r/  r   r   rg   r1  checkvalcommentf_public_key	f_secretsf_mainslenmlenr   ofsr#   r#   r$   _serialize_ssh_private_key  sj   
















 rP  c                   @  s   e Zd ZdZdZdS )SSHCertificateTyper(   r  N)r3   r4   r5   USERHOSTr#   r#   r#   r$   rQ  w  s    rQ  c                   @  s   e Zd Zd9ddZed:ddZd;ddZed<d d!Zed=d#d$Zed:d%d&Z	ed>d'd(Z
ed<d)d*Zed<d+d,Zed?d-d.Zed?d/d0Zd;d1d2Zd:d3d4Zd@d6d7Zd8S )ASSHCertificate_noncerj   _public_keySSHPublicKeyTypes_serialr   _cctype_key_id_valid_principalslist[bytes]_valid_after_valid_before_critical_optionsdict[bytes, bytes]_extensions	_sig_type_sig_key_inner_sig_type
_signature_tbs_cert_body_cert_key_typer   
_cert_bodyc                 C  s   || _ || _|| _zt|| _W n ty   tdw || _|| _|| _|| _	|	| _
|
| _|| _|| _|| _|| _|| _|| _|| _d S )NzInvalid certificate type)rU  rV  rX  rQ  _typerN   rZ  r[  r]  r^  r_  ra  rb  rc  rd  re  rg  rh  rf  )r   rU  rV  rX  rY  rZ  r[  r]  r^  r_  ra  rb  rc  rd  re  rf  rg  rh  r#   r#   r$   r   }  s*   
zSSHCertificate.__init__r!   c                 C  
   t | jS r   )r   rU  r   r#   r#   r$   nonce     
zSSHCertificate.nonceSSHCertPublicKeyTypesc                 C  s   t t| jS r   )typingcastrm  rV  r   r#   r#   r$   rC     s   zSSHCertificate.public_keyc                 C     | j S r   )rX  r   r#   r#   r$   serial     zSSHCertificate.serialrQ  c                 C  rp  r   )ri  r   r#   r#   r$   type  rr  zSSHCertificate.typec                 C  rj  r   )r   rZ  r   r#   r#   r$   key_id  rl  zSSHCertificate.key_idc                 C  rp  r   )r[  r   r#   r#   r$   valid_principals  rr  zSSHCertificate.valid_principalsc                 C  rp  r   )r^  r   r#   r#   r$   valid_before  rr  zSSHCertificate.valid_beforec                 C  rp  r   )r]  r   r#   r#   r$   valid_after  rr  zSSHCertificate.valid_afterc                 C  rp  r   )r_  r   r#   r#   r$   critical_options  rr  zSSHCertificate.critical_optionsc                 C  rp  r   )ra  r   r#   r#   r$   
extensions  rr  zSSHCertificate.extensionsc                 C  s&   t | j}|| j\}}t| |S r   )r  rb  r   rc  rb   )r   	sigformatsignature_key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   rg  r  
b2a_base64rh  r   r#   r#   r$   r     s   zSSHCertificate.public_bytesr^   c                 C  s  |   }t|tjr|t| jt| j d S t|tj	rIt
| j\}}t
|\}}t| t||}t|j}||t| jt| d S t|tjsQJ | jtkr[t }n| jtkret }n| jtkslJ t }|t| jt| jt | d S r   )r{  r@   r   rL   verifyr   re  rf  r
   rD   r   rb   
asym_utilsencode_dss_signature_get_ec_hash_algrR   ECDSAr   rF   rd  rG   r   SHA1_SSH_RSA_SHA256SHA256_SSH_RSA_SHA512SHA512r   PKCS1v15)r   r{  rrV   scomputed_sighash_algr#   r#   r$   verify_cert_signature  s6   




z$SSHCertificate.verify_cert_signatureN)"rU  rj   rV  rW  rX  r   rY  r   rZ  rj   r[  r\  r]  r   r^  r   r_  r`  ra  r`  rb  rj   rc  rj   rd  rj   re  rj   rf  rj   rg  r   rh  rj   r   )r!   rm  r   )r!   rQ  )r!   r\  )r!   r`  )r!   r^   )r3   r4   r5   r   propertyrk  rC   rq  rs  rt  ru  rv  rw  rx  ry  r{  r   r  r#   r#   r#   r$   rT  |  s0    
)


rT  rR   r   hashes.HashAlgorithmc                 C  s@   t | tjr
t S t | tjrt S t | tjsJ t S r   )	r@   r
   	SECP256R1r   r  	SECP384R1SHA384	SECP521R1r  )rR   r#   r#   r$   r    s   r  "SSHCertificate | SSHPublicKeyTypesc           "      C  sp  t d|  t| }|std|d }}|d}d}|tr/d}|d tt  }|t	kr9|s9t
dt|}z	tt|}W n ttjfyT   tdw |rY|}	t|\}
}|
|krgtd	|rot|\}}||\}}|r2t|\}}t|\}}t|\}}t|\}}g }|rt|\}}|t| |st|\}}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vs|tkr||krtdt| \}!} t|  t||||||||||||||!|||	S t| |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matchrN   groupendswith_CERT_SUFFIXr_   rJ   r   r  rj   r  r   rf   Errorr|   r   ry   ru   r   r   _parse_exts_optsrb   rG   r  r  rT  )"rV   _legacy_dsa_allowedr,  rO   orig_key_typekey_body	with_certr4  rest	cert_bodyinner_key_typerk  rC   rq  cctypert  
principalsru  	principalrw  rv  crit_optionsrx  extsry  r   sig_key_rawsig_typesig_keytbs_cert_bodysignature_rawinner_sig_typesig_rest	signaturer#   r#   r$   _load_ssh_public_identity  s   



r  c                 C  s   t | S r   )r  ra   r#   r#   r$   load_ssh_public_identityf  s   r  	exts_optsr`  c                 C  s   i }d }| rJt | \}} t|}||v rtd|d ur$||k r$tdt | \}} t|dkr@t |\}}t|dkr@tdt|||< |}| s|S )NzDuplicate namezFields not lexically sortedr   z!Unexpected extra data after value)r|   r   rN   r_   )r  result	last_namerS   bnamevalueextrar#   r#   r$   r  l  s$   r  rW  hash_algorithmhashes.MD5 | hashes.SHA256c                 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   MD5r  rf   rP   r  r   r   r   r   Hashr%  r'  )r=   r  rO   r4  r   ssh_binary_datahash_objr#   r#   r$   ssh_key_fingerprint  s   


r  c                 C  sF   t | dd}t|tr| }n|}t|tjr!tjdtj	dd |S )NT)r  r  r  r  )
r  r@   rT  rC   r	   rI   r)  r*  r   r+  )rV   r  cert_or_keyrC   r#   r#   r$   load_ssh_public_key  s   

r  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?  rn   r  rZ   r}  )r@   r	   rI   r)  r*  r   r+  rP   r  r   r   r   r  r  r   stripr[   )rC   rO   r4  r   pubr#   r#   r$   serialize_ssh_public_key  s   
r     c                
   @  s   e Zd Zddddg dddg g f
d>ddZd?ddZd@ddZdAd!d"ZdBd%d&ZdCd(d)Zd*d+ Z	dDd.d/Z
dEd1d2ZdFd5d6ZdFd7d8ZdGd<d=ZdS )HSSHCertificateBuilderNFrV  SSHCertPublicKeyTypes | NonerX  r0   ri  SSHCertificateType | NonerZ  rd   r[  r\  _valid_for_all_principalsr    r^  r]  r_  list[tuple[bytes, bytes]]ra  c                 C  s@   || _ || _|| _|| _|| _|| _|| _|| _|	| _|
| _	d S r   
rV  rX  ri  rZ  r[  r  r^  r]  r_  ra  )r   rV  rX  ri  rZ  r[  r  r^  r]  r_  ra  r#   r#   r$   r     s   
zSSHCertificateBuilder.__init__rC   rm  r!   c                 C  s^   t |tjtjtjfstd| jd urt	dt
|| j| j| j| j| j| j| j| j| jd
S )Nr?   zpublic_key already setr  )r@   r
   rD   r   rF   r   rL   rf   rV  rN   r  rX  ri  rZ  r[  r  r^  r]  r_  ra  )r   rC   r#   r#   r$   rC     s,   
z SSHCertificateBuilder.public_keyrq  r   c                 C  sv   t |ts	tdd|  krdk std td| jd ur$t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 setr  )r@   r   rf   rN   rX  r  rV  ri  rZ  r[  r  r^  r]  r_  ra  )r   rq  r#   r#   r$   rq    s(   

zSSHCertificateBuilder.serialrs  rQ  c                 C  sR   t |ts	td| jd urtdt| j| j|| j| j	| j
| j| j| j| jd
S )Nz"type must be an SSHCertificateTypeztype already setr  )r@   rQ  rf   ri  rN   r  rV  rX  rZ  r[  r  r^  r]  r_  ra  )r   rs  r#   r#   r$   rs    s    

zSSHCertificateBuilder.typert  r   c                 C  sR   t |ts	td| jd urtdt| j| j| j|| j	| j
| j| j| j| jd
S )Nzkey_id must be byteszkey_id already setr  )r@   r   rf   rZ  rN   r  rV  rX  ri  r[  r  r^  r]  r_  ra  )r   rt  r#   r#   r$   rt  '  s    

zSSHCertificateBuilder.key_idru  c                 C  s|   | j rtdtdd |D r|std| jrtdt|tkr't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_principalsr  )r  rN   allrf   r[  r_   _SSHKEY_CERT_MAX_PRINCIPALSr  rV  rX  ri  rZ  r^  r]  r_  ra  )r   ru  r#   r#   r$   ru  :  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 setTr  )r[  rN   r  r  rV  rX  ri  rZ  r^  r]  r_  ra  r   r#   r#   r$   valid_for_all_principals^  s$   z.SSHCertificateBuilder.valid_for_all_principalsrv  int | floatc                 C  sv   t |ttfstdt|}|dk s|dkrtd| jd ur$tdt| j| j| j	| j
| j| j|| j| j| jd
S )Nz$valid_before must be an int or floatr   r  zvalid_before must [0, 2**64)zvalid_before already setr  )r@   r   floatrf   rN   r^  r  rV  rX  ri  rZ  r[  r  r]  r_  ra  )r   rv  r#   r#   r$   rv  t  s&   
z"SSHCertificateBuilder.valid_beforerw  c                 C  sv   t |ttfstdt|}|dk s|dkrtd| jd ur$tdt| j| j| j	| j
| j| j| j|| j| jd
S )Nz#valid_after must be an int or floatr   r  zvalid_after must [0, 2**64)zvalid_after already setr  )r@   r   r  rf   rN   r]  r  rV  rX  ri  rZ  r[  r  r^  r_  ra  )r   rw  r#   r#   r$   rw    s&   
z!SSHCertificateBuilder.valid_afterrS   r  c                 C  st   t |tr
t |tstd|dd | jD v rtdt| j| j| j| j	| j
| j| j| jg | j||f| jd
S )Nname and value must be bytesc                 S     g | ]\}}|qS r#   r#   r  rS   r   r#   r#   r$   
<listcomp>      z=SSHCertificateBuilder.add_critical_option.<locals>.<listcomp>zDuplicate critical option namer  )r@   r   rf   r_  rN   r  rV  rX  ri  rZ  r[  r  r^  r]  ra  r   rS   r  r#   r#   r$   add_critical_option  s    z)SSHCertificateBuilder.add_critical_optionc                 C  st   t |tr
t |tstd|dd | jD v rtdt| j| j| j| j	| j
| j| j| j| jg | j||fd
S )Nr  c                 S  r  r#   r#   r  r#   r#   r$   r    r  z7SSHCertificateBuilder.add_extension.<locals>.<listcomp>zDuplicate extension namer  )r@   r   rf   ra  rN   r  rV  rX  ri  rZ  r[  r  r^  r]  r_  r  r#   r#   r$   add_extension  s    z#SSHCertificateBuilder.add_extensionr   SSHCertPrivateKeyTypesrT  c              	   C  s  t |tjtjtjfstd| jd u rt	d| j
d u rdn| j
}| jd u r+t	d| jd u r2dn| j}| js?| js?t	d| jd u rHt	d| jd u rQt	d| j| jkr[t	d	| jjd
d d | jjdd d t| j}|t }td}t|}t }|| || || j| || || jj || t }	| jD ]}
|	|
 q||	  || j || j t }| jD ]$\}}|| t |dkrt }|| ||  q|| q||  t }| jD ]%\}}|| t |dkrt }|| ||  q|| q||  |d t|}t|}t }|| ||! | ||  t |tjrq|"| }t }|| || ||  nlt |tjrt#|j$}|"| t%|}t&'|\}}t }|| t }|(| |(| ||  ||  n*t |tjsJ t }|t) |"| t*+ t,- }|| ||  t./| 0 }t12t3t4d5|d|gS )NzUnsupported private key typezpublic_key must be setr   ztype must be setrZ   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     | d S Nr   r#   r   r#   r#   r$   <lambda>      z,SSHCertificateBuilder.sign.<locals>.<lambda>)r=   c                 S  r  r  r#   r  r#   r#   r$   r    r  r7   r}  )6r@   r
   rA   r   rE   r   rK   rf   rV  rN   rX  ri  rZ  r[  r  r^  r]  r_  sortra  rP   r  rC  rD  r  r   r   r   r   r   r  r   r_   rC   signr  rR   r  r  decode_dss_signaturer   r  r   r  r   r  r  r  r  rn  ro  rT  r  r[   )r   r   rq  rt  rO   cert_prefixrk  r4  ffprincipalsr   fcritrS   r  foptvalfextfextvalca_typecaformatcafr  fsigr  r  r  fsigblob	cert_datar#   r#   r$   r    s   
























zSSHCertificateBuilder.sign)rV  r  rX  r0   ri  r  rZ  rd   r[  r\  r  r    r^  r0   r]  r0   r_  r  ra  r  )rC   rm  r!   r  )rq  r   r!   r  )rs  rQ  r!   r  )rt  r   r!   r  )ru  r\  r!   r  )rv  r  r!   r  )rw  r  r!   r  )rS   r   r  r   r!   r  )r   r  r!   rT  )r3   r4   r5   r   rC   rq  rs  rt  ru  r  rv  rw  r  r  r  r#   r#   r#   r$   r    s.    




$



r  )F)r   r   r   r   r   r   r   r   r   r    r!   r   )r=   r>   r!   r   )rC   rQ   r!   r   )rV   rW   rX   r   rY   r   r!   r   )rV   rW   r.   r   r!   r^   )rV   rW   r!   r^   )
rc   r   r   rd   r   r   r   r   r!   re   )rV   rj   r!   rk   )rV   rj   r!   rz   )r~   r   r!   r   )r!   rz   )rO   rW   r   )
rV   rW   r   rd   r  r  r   r    r!   r  )r   r  r   r   r>  r   r!   r   )rR   r   r!   r  )rV   rW   r!   r  )rV   r   r!   r  )r  rj   r!   r`  )r=   rW  r  r  r!   r   )rV   rW   r  r  r!   rW  )rC   rW  r!   r   )
__future__r   r  enumrC  rern  r)  base64r   r\   dataclassesr   cryptographyr   cryptography.exceptionsr   cryptography.hazmat.primitivesr   )cryptography.hazmat.primitives.asymmetricr	   r
   r   r   r   r  &cryptography.hazmat.primitives.ciphersr   r   r   r   ,cryptography.hazmat.primitives.serializationr   r   r   r   r   r   bcryptr   r%   _bcrypt_supportedImportErrorrM   rG   rJ   r  _ECDSA_NISTP384_ECDSA_NISTP521r  _SK_SSH_ED25519_SK_SSH_ECDSA_NISTP256r  r  compiler  r!  	_SK_START_SK_ENDr#  r"  r@  rA  DOTALLr  rj   r   ranger(  r*   AESCTRCBCGCMr9   r6   rT   rP   rB   r]   r`   rb   ri   ru   ry   r|   r   r   r   r   r   r   r   r  r  r  r  r  r  r  r  UnionrA   rE   rH   rK   r  r=  rP  rD   rF   rI   rL   rW  rm  EnumrQ  rT  r  r  r  r  r  r  r  r  r  r  r#   r#   r#   r$   <module>   s6   	
		 










6JFG
C
	
rM 

_


	