HEX
Server: LiteSpeed
System: Linux php-prod-1.spaceapp.ru 5.15.0-157-generic #167-Ubuntu SMP Wed Sep 17 21:35:53 UTC 2025 x86_64
User: sport3497 (1034)
PHP: 8.1.33
Disabled: NONE
Upload Files
File: //usr/local/CyberCP/lib64/python3.10/site-packages/asyncssh/__pycache__/public_key.cpython-310.pyc
o

�hF �@s�UdZddlZddlZddlZddlZddlZddlZddlmZddlm	Z	m
Z
mZmZm
Z
ddlmZmZddlmZmZmZmZmZmZmZddlmZmZmZmZddlmZd	d
lm Z m!Z!d	dl"m#Z#d	dl$m%Z%zd	d
lm&Z&d	dlm'Z'm(Z(dZ)Wne*y�dZ)Ynwzddl+Z+e,e+d�Z-Wne*y�dZ-Ynwd	dl.m/Z/m0Z0m1Z1d	dl.m2Z2m3Z3m4Z4d	dlm5Z5m6Z6d	dl"m7Z7m8Z8d	dl9m:Z:m;Z;m<Z<m=Z=d	dl9m>Z>m?Z?m@Z@mAZAd	dlBmCZCmDZDmEZEmFZFd	dlBmGZGmHZHd	dlImJZJmKZKmLZLd	dlImMZMmNZNd	dl$mOZOmPZPee:ZQeeReeRfZSeeTeUeeRfZVeeWedfZXeeWeeededffZYeeWeWfZZeeeWeTfeeWedffZ[eeWedfZ\ee1edfZ]eeTeedee^d fffZ_eeRe^fZ`ee^eTeTeWeWeTeTeWeWf	ZaeeeRee^geWffZbeeWeeHge^ffZcedeReeRfZdeeWe<ddfZeeeeeeefZfeeWe<dfZgee<eegfZheeWe<dfZieeieeifZjed!egeegeiffZkeekeekfZld"e �o�e%fd#e%fd$e!fd%e fd&d'd(fZmd)Znd*Zoe	e
eee
d�ZpgZqeeWerd+<gZseeWerd,<gZteeWerd-<gZueeWerd.<gZveeWerd/<gZweeWerd0<iZxeXerd1<iZyeYerd2<iZzeZerd3<iZ{e[erd4<iZ|e\erd5<iZ}e]erd6<iZ~e_erd7<e�d8�Z�e�d9�Z�e�d:ej��Z�d	Z�d;Z�e^�Z�d<Z�d=Z�d>Z�d?eVd@eTfdAdB�Z�d�dDeWdEeTd@eWfdFdG�Z�GdHdI�dIe��Z�GdJdK�dKe��Z�GdLdM�dMe��Z�GdNdO�dOe�Z�GdPdQ�dQe�Z�GdRd�d�Z�GdSd�d�Z�GdTd�de��Z�GdUdV�dVe��Z�GdWdX�dXe��Z�GdYdZ�dZe��Z�Gd[d!�d!�Z�Gd\d]�d]e��Z�dDeWd@eeWeeWeWffd^d_�Z�dDeWd@eeeWeWfeWffd`da�Z�dDeWd@eeeWeWffdbdc�Z�dDeWddeTdeeWdfeRd@eeWeTff
dgdh�Z�d�dDeWdieWdje�d@eeeReeeTffdkdl�Z�dmeWdne^doee�d@e�fdpdq�Z�dmeWdne^d@e�fdrds�Z�dne^doee�d@e�fdtdu�Z�dne^d@e�fdvdw�Z�dDeWdxee:doee�d@e�fdydz�Z�dDeWd@e�fd{d|�Z�dne^dxee:doee�d@e�fd}d~�Z�dne^d@e�fdd��Z�	d�dDeWd�eQd@e�fd�d��Z�dmeWd�eeWeWfdDeWdxee:doee�d@e�fd�d��Z�dmeWdDeWd@e�fd�d��Z�dmeWdDeWd@e�fd�d��Z�dDeWdxee:doee�d@eee�eeTffd�d��Z�dDeWd@eee�eeTffd�d��Z�dDeWd@eee�eeTffd�d��Z�dDeWdxee:doee�d@ee�fd�d��Z�dDeWd@ee�fd�d��Z�dDeWd@ee�fd�d��Z�d�eTd�ee�d�e^d@dfd�d��Z�	d�d�eWd�ee�d�e�d�eeeWd@df
d�d��Z�d�eTd�eWd�eWd�ee�d�ee�d�e�d@dfd�d��Z�d�eWd�e�d@dfd�d��Z�d@eeWfd�d��Z�d@eeWfd�d��Z�d@eeWfd�d��Z�d@eeWfd�d��Z�d@eeWfd�d��Z�d@eeWfd�d��Z�dDeWd@e�fd�d��Z�	d�dDeWd�eQd@e�fd�d��Z�d�d�eRd�eQd@e�fd�d��Z�		d�dDe:dxee:doee�d@e�fd�d��Z�		d�dDeWdxee:doee�d@ee�ee�ffd�d��Z�dDe:d@e�fd�d��Z�dDe:d@e�fd�dÄZ�dDeWd@ee�fd�dńZ�dDeRd@eRfd�dDŽZ�		d�d�e<dxee:doee�d@e�fd�dʄZ�		d�d�e<dxee:doee�d@ee�ee�ffd�d̄Z�d�e<d@e�fd�d΄Z�d�e<d@e�fd�dЄZ�		d�d�e<dxee:doee�d@ee�fd�d҄Z�d�e<d@ee�fd�dԄZ�d�e<d@ee�fd�dքZ�					d�d�eldxee:d�ejd�e�d�e�doee�d�eej�d@ee�fd�dބZ�		�d�dxee:d�ejd@ee�fd�d�Z�d�ehd@ee�fd�d�Z�d@eee�e�ffd�d�Z�d�ejd@ee�fd�d�Z�	d�d�efd�e�d@eeWfd�d�Z�d@eeWfd�d�Z�d�ddd�d�eRd�eRd�eeRd�e�d@ee�f
d�d�Z�dS)�z"SSH asymmetric encryption handlers�N)�datetime)�md5�sha1�sha256�sha384�sha512)�Path�PurePath)�Callable�Dict�List�Mapping�Optional�Sequence�Set)�Tuple�Type�Union�cast)�Protocol�)�ed25519_available�ed448_available)�
Encryption)�sk_available)�X509Certificate)�generate_x509_certificate�import_x509_certificateTF�kdf)�ASN1DecodeError�	BitString�ObjectIdentifier)�
der_encode�
der_decode�der_decode_partial)�	CryptoKey�PyCAKey)�get_encryption_params�get_encryption)�
BytesOrStr�DefTuple�FilePath�	IPNetwork)�
ip_network�	read_file�
write_file�parse_time_interval)�NameList�String�UInt32�UInt64)�PacketDecodeError�	SSHPacket)�KeyEncryptionError�
pkcs1_encrypt�
pkcs8_encrypt)�
pkcs1_decrypt�
pkcs8_decrypt)�SSH_SK_USER_PRESENCE_REQD�sk_get_resident�SSHKey�SSHCertificate�SSHOpenSSHCertificate.�
SSHKeyPair�
id_ed25519_sk�id_ecdsa_sk�id_ed448�
id_ed25519)�id_ecdsaT)�id_rsaT)�id_dsaT)z/opt/local/etcz/opt/local/etc/sshz/usr/local/etcz/usr/local/etc/sshz/etcz/etc/ssh)�ssh_host_ed448_key�ssh_host_ed25519_key�ssh_host_ecdsa_key�ssh_host_rsa_key�ssh_host_dsa_key�_public_key_algs�_default_public_key_algs�_certificate_algs�_default_certificate_algs�_x509_certificate_algs�_default_x509_certificate_algs�_public_key_alg_map�_certificate_alg_map�_certificate_sig_alg_map�_certificate_version_map�_pem_map�_pkcs8_oid_map�_sk_alg_mapz\d{8}z\d{14}z.(?:Distinguished[ -_]?Name|Subject|DN)[=:]?\s?�sopenssh-key-v1��F�t�returncCs�t|t�r|St|t�rt|�St|t�rt|���St|t�rd|dkr*tt���St�|�}|r;tt�	|d����St
�|�}|rLtt�	|d����Sztt��t|��WStycYtd��wtd��)zParse a time value�nowz%Y%m%dz%Y%m%d%H%M%SzUnrecognized time value)
�
isinstance�int�floatr�	timestamp�str�time�_abs_date_pattern�	fullmatch�strptime�_abs_time_patternr0�
ValueError)r^�match�rm�F/usr/local/CyberCP/lib/python3.10/site-packages/asyncssh/public_key.py�_parse_time�s,





�ro�@�data�wrapcs<t���dd��d���fdd�tdt����D��dS)z)Break a Base64 value into multiple lines.N����
c3s �|]}�||��VqdS�Nrm��.0�i�rqrrrmrn�	<genexpr>�s��z_wrap_base64.<locals>.<genexpr>r)�binascii�
b2a_base64�join�range�lenryrmryrn�_wrap_base64�s��r�c@�eZdZdZdS)�KeyGenerationErrora8Key generation error

       This exception is raised by :func:`generate_private_key`,
       :meth:`generate_user_certificate() <SSHKey.generate_user_certificate>`
       or :meth:`generate_host_certificate()
       <SSHKey.generate_host_certificate>` when the requested parameters are
       unsupported.

    N��__name__�
__module__�__qualname__�__doc__rmrmrmrnr���r�c@r�)�KeyImportErrorz�Key import error

       This exception is raised by key import functions when the
       data provided cannot be imported as a valid key.

    Nr�rmrmrmrnr��r�r�c@r�)�KeyExportErrorz�Key export error

       This exception is raised by key export functions when the
       requested format is unknown or encryption is requested for a
       format which doesn't support it.

    Nr�rmrmrmrnr��r�r�c@s"eZdZdZdedefdd�ZdS)�
SigningKeyz$Protocol for signing a block of datarqr_cC�dS)z'Sign a block of data with a private keyNrm��selfrqrmrmrn�sign��zSigningKey.signN)r�r�r�r��bytesr�rmrmrmrnr��sr�c@s&eZdZdZdededefdd�ZdS)�VerifyingKeyz5Protocol for verifying a signature on a block of datarq�sigr_cCr�)z7Verify a signature on a block of data with a public keyNrm)r�rqr�rmrmrn�verify�r�zVerifyingKey.verifyN)r�r�r�r�r��boolr�rmrmrmrnr��sr�c%@s\eZdZUdZdZeed<dZeeed<dZ	eeed<dZ
eeed<e�Ze
eed<d	Zeed
<dZeed<dZeeed
<dZeed<dZeed<d�deefdd�Zededdfdd��Zededdfdd��Zededdfdd��Zededefdd��Zededefdd ��Zed!ed"edefd#d$��Z ed!ed"edefd%d&��Z!ed'e"defd(d)��Z#ed'e"defd*d+��Z$e%defd,d-��Z&e%defd.d/��Z'e%de(fd0d1��Z)ddd2e*d3e*d4e*d5ed6e+d7e,d8e,d9e-d:e.ed;e.e/dd<fd=d>�Z0ddd?ed@eed3ee*d7e,d8e,dAedBee*dCe1dDe+dEe+dFe.ed;e.e/ddGfdHdI�Z2defdJdK�Z3defdLdM�Z4deefdNdO�Z5	P	Qd�dRedSedeefdTdU�Z6	P	Qd�d;e/dRedSeddfdVdW�Z7deefdXdY�Z8dZe9dee:fddfd[d\�Z;d�dFedefd^d_�Z<d`eddfdadb�Z=d"edFedefdcdd�Z>d"edeedefdfdg�Z?d"edeed'e"defdhdi�Z@d"edeedefdjdk�ZAd"edledefdmdn�ZBdefdodp�ZCdefdqdr�ZDdeEeeffdsdt�ZFdeEeeffdudv�ZGdefdwdx�ZHdefdydz�ZIdefd{d|�ZJd�d}d~�ZK			�			�	�	�	�		d�d�dd5ed2e*d3e*d6e+d7e,d8e,d�eed�eeed�ed�ed�ed�ed�ed`ed�e.ed;e.e/dd<f$d�d��ZL	�		�	�		d�d�dd5ed2e*d3e*d6e+d7e,d8e,d�e.ed;e.e/dd<fd�d��ZM		�	�	�		d�d�dd?ed@eed3ee*d6e+d7e,d8e,dCe1d�e.ed;e.e/ddGfd�d��ZN		�	�	�		d�d�dd?ed@eed3ee*d6e+d7e,d8e,dCe1d�e.ed;e.e/ddGfd�d��ZO			�	�			d�d�dd?ed@eed3ee*d7e,d8e,dBee*d�e.ed;e.e/ddGfd�d��ZP	�		�	]	�	d�d�ed�eeQd�edFed�e*d�e*d�edefd�d��ZRd�d�edefd�d��ZSdZe:ddfd�d��ZTdZe:ddfd�d��ZUdZe:ddfd�d��ZVdZe:ddfd�d��ZWdS)�r>z5Parent class which holds an asymmetric encryption key��	algorithmrm�sig_algorithms�cert_algorithms�x509_algorithms�all_sig_algorithms��default_x509_hash�pem_nameN�	pkcs8_oidF�use_executor�use_webauthn�keycCs||_d|_d|_d|_dS)NF)�_key�_comment�	_filename�_touch_required)r�r�rmrmrn�__init__�s
zSSHKey.__init__r_cK�t�)zGenerate a new SSH private key��NotImplementedError)�clsr��kwargsrmrmrn�generate�zSSHKey.generate�
key_paramscCr�)zConstruct a private keyr��r�r�rmrmrn�make_private
r�zSSHKey.make_privatecCr�)zConstruct a public keyr�r�rmrmrn�make_publicr�zSSHKey.make_public�key_datacCr�)�"Decode a PKCS#1 format private keyNrm�r�r�rmrmrn�decode_pkcs1_privater�zSSHKey.decode_pkcs1_privatecCr�)�!Decode a PKCS#1 format public keyNrmr�rmrmrn�decode_pkcs1_publicr�zSSHKey.decode_pkcs1_public�
alg_paramsrqcCr�)�"Decode a PKCS#8 format private keyNrm�r�r�rqrmrmrn�decode_pkcs8_privater�zSSHKey.decode_pkcs8_privatecCr�)�!Decode a PKCS#8 format public keyNrmr�rmrmrn�decode_pkcs8_public"r�zSSHKey.decode_pkcs8_public�packetcCr�)z Decode an SSH format private keyNrm�r�r�rmrmrn�decode_ssh_private&r�zSSHKey.decode_ssh_privatecCr�)zDecode an SSH format public keyNrmr�rmrmrn�decode_ssh_public*r�zSSHKey.decode_ssh_publiccC�t|j�|��S)z0Return private key data in OpenSSH binary format)r2r��encode_ssh_private�r�rmrmrn�private_data.�zSSHKey.private_datacCr�)z/Return public key data in OpenSSH binary format)r2r��encode_ssh_publicr�rmrmrn�public_data4r�zSSHKey.public_datacCs|jdusJ�|jjS)z'Return PyCA key for use in X.509 moduleN)r��pyca_keyr�rmrmrnr�:szSSHKey.pyca_key�version�serial�	cert_type�key_id�
principals�valid_after�valid_before�cert_options�sig_alg_name�commentr@cCs�t|t�rdd�|�d�D�}nt|�}t|�}t|�}||kr$td��|
dkr.|jd}ntt|
���}|dkr=|�	�}zt
|j|f\}
}WntyTt
d�d�w|�||
||||||||	||�S)	�Generate a new SSH certificatecSsg|]}|���qSrm)�strip�rw�prmrmrn�
<listcomp>L�z0SSHKey._generate_certificate.<locals>.<listcomp>�,�5Valid before time must be later than valid after timermrzUnknown certificate versionN)rare�split�listrorkr�r�encode�get_comment_bytesrWr��KeyErrorr�r�)r�r�r�r�r�r�r�r�r�r�r�r��sig_algr��cert_handlerrmrmrn�_generate_certificateAs0

�
��zSSHKey._generate_certificate�subject�issuer�ca�ca_path_len�purposes�user_principals�host_principals�	hash_name�SSHX509CertificatecCs�tstd��|jstd|��d��t|�}t|�}||kr#td��|dkr*|j}|
dkr2|��}
t�	||||||||||	|
|||
�S)� Generate a new X.509 certificatez/X.509 certificate generation requires PyOpenSSLz/X.509 certificate generation not supported for z keysr�rm)
�_x509_availabler�r��
get_algorithmrorkr�r�r�r�)r�r�r�r�r�r�r�r�r�r�r�r�r�r�rmrmrn�_generate_x509_certificatels,
���z!SSHKey._generate_x509_certificatecC�|j�d�S)z-Return the algorithm associated with this key�ascii�r��decoder�rmrmrnr���zSSHKey.get_algorithmcC�
t|j�S)zSReturn whether a comment is set for this key

           :returns: `bool`

        �r�r�r�rmrmrn�has_comment��
zSSHKey.has_commentcC�|jp|jS)znReturn the comment associated with this key as a byte string

           :returns: `bytes` or `None`

        �r�r�r�rmrmrnr��szSSHKey.get_comment_bytes�utf-8�strict�encoding�errorscC�|��}|r|�||�SdS)a"Return the comment associated with this key as a Unicode string

           :param encoding:
               The encoding to use to decode the comment as a Unicode
               string, defaulting to UTF-8
           :param errors:
               The error handling scheme to use for Unicode decode errors
           :type encoding: `str`
           :type errors: `str`

           :returns: `str` or `None`

           :raises: :exc:`UnicodeDecodeError` if the comment cannot be
                    decoded using the specified encoding

        N�r�r��r�r�rr�rmrmrn�get_comment�szSSHKey.get_commentcC�$t|t�r|�||�}|pd|_dS)abSet the comment associated with this key

           :param comment:
               The new comment to associate with this key
           :param encoding:
               The Unicode encoding to use to encode the comment,
               defaulting to UTF-8
           :param errors:
               The error handling scheme to use for Unicode encode errors
           :type comment: `str`, `bytes`, or `None`
           :type encoding: `str`
           :type errors: `str`

           :raises: :exc:`UnicodeEncodeError` if the comment cannot be
                    encoded using the specified encoding

        N�rarer�r��r�r�r�rrmrmrn�set_comment��
zSSHKey.set_commentcC�|jS)z^Return the filename associated with this key

           :returns: `bytes` or `None`

        )r�r�rmrmrn�get_filename�szSSHKey.get_filename�filenamecCs4t|t�r	t|�}t|t�r|�d�}|pd|_dS)z�Set the filename associated with this key

           :param filename:
               The new filename to associate with this key
           :type filename: `PurePath`, `str`, `bytes`, or `None`

        r�N)rar	rer�r�)r�rrmrmrn�set_filename�s

	

zSSHKey.set_filenamercs�zt|}Wntytd�d�w||j�}|dkr3|���d��fdd�tdt��d�D��}n|��}t	�
|��d	�dd
��d�}|�
�d|S)arGet the fingerprint of this key

           Available hashes include:

               md5, sha1, sha256, sha384, sha512

           :param hash_name: (optional)
               The hash algorithm to use to construct the fingerprint.
           :type hash_name: `str`

           :returns: `str`

           :raises: :exc:`ValueError` if the hash name is invalid

        zUnknown hash algorithmNr�:c3s �|]}�||d�VqdS)r[Nrmrv��fprmrnrzs�z)SSHKey.get_fingerprint.<locals>.<genexpr>rr[r�rs�=)�_hashesr�rkr��	hexdigestr}r~r�digestr{r|r�r��upper)r�r��hash_alg�h�fp_text�fpbrmrrn�get_fingerprint�s
�
&zSSHKey.get_fingerprint�touch_requiredcCs
||_dS)z7Set whether touch is required when using a security keyN)r�)r�rrmrmrn�set_touch_requireds
zSSHKey.set_touch_requiredcCs|jdusJ�|j�||�S)z,Return a raw signature of the specified dataN)r�r�)r�rqr�rmrmrn�sign_rawszSSHKey.sign_raw�
sig_algorithmcCr�)z3Abstract method to compute an SSH-encoded signaturer��r�rqrrmrmrn�sign_ssh%�zSSHKey.sign_sshcCr�)z2Abstract method to verify an SSH-encoded signaturer�)r�rqrr�rmrmrn�
verify_ssh*r�zSSHKey.verify_sshcCsB|�d�r|dd�}||jvrtd��d�t|�|�||�f�S)z5Return an SSH-encoded signature of the specified data�x509v3-�Nz Unrecognized signature algorithmr�)�
startswithr�rkr}r2r rrmrmrnr�0s



�zSSHKey.signr�cCsFzt|�}|��}||jvrWdS|�|||�WSty"YdSw)z<Verify an SSH signature of the specified data using this keyF)r6�
get_stringr�r"r5)r�rqr�r�rrmrmrnr�<s
�z
SSHKey.verifycC�td��)z6Export parameters associated with a PKCS#1 private keyz'PKCS#1 private key export not supported�r�r�rmrmrn�encode_pkcs1_privateJ�zSSHKey.encode_pkcs1_privatecCr')z5Export parameters associated with a PKCS#1 public keyz&PKCS#1 public key export not supportedr(r�rmrmrn�encode_pkcs1_publicPr*zSSHKey.encode_pkcs1_publiccCr')z6Export parameters associated with a PKCS#8 private keyz'PKCS#8 private key export not supportedr(r�rmrmrn�encode_pkcs8_privateVr*zSSHKey.encode_pkcs8_privatecCr')z5Export parameters associated with a PKCS#8 public keyz&PKCS#8 public key export not supportedr(r�rmrmrn�encode_pkcs8_public\r*zSSHKey.encode_pkcs8_publiccCr')z8Export parameters associated with an OpenSSH private keyz(OpenSSH private key export not supportedr(r�rmrmrnr�br*zSSHKey.encode_ssh_privatecCr')z7Export parameters associated with an OpenSSH public keyz'OpenSSH public key export not supportedr(r�rmrmrnr�hr*zSSHKey.encode_ssh_publiccCr�)z-Encode certificate private key data for agentr�r�rmrmrn�encode_agent_cert_privatenr!z SSHKey.encode_agent_cert_privatecCs&t|j�}|�|j�|�|j�|S)a7Return public key corresponding to this key

           This method converts an :class:`SSHKey` object which contains
           a private key into one which contains only the corresponding
           public key. If it is called on something which is already
           a public key, it has no effect.

        )�decode_ssh_public_keyr�rr�r
r�)r��resultrmrmrn�convert_to_publicss

zSSHKey.convert_to_publicrr�����T�user_key�
force_command�source_address�permit_x11_forwarding�permit_agent_forwarding�permit_port_forwarding�
permit_pty�permit_user_rcr�c
Cs�i}|r||d<|	rdd�|	D�|d<|
rd|d<|rd|d<|r%d|d<|
r+d|d	<|r1d|d
<|s7d|d<|�|||t|||||||�S)a�Generate a new SSH user certificate

           This method returns an SSH user certificate with the requested
           attributes signed by this private key.

           :param user_key:
               The user's public key.
           :param key_id:
               The key identifier associated with this certificate.
           :param version: (optional)
               The version of certificate to create, defaulting to 1.
           :param serial: (optional)
               The serial number of the certificate, defaulting to 0.
           :param principals: (optional)
               The user names this certificate is valid for. By default,
               it can be used with any user name.
           :param valid_after: (optional)
               The earliest time the certificate is valid for, defaulting to
               no restriction on when the certificate starts being valid.
               See :ref:`SpecifyingTimeValues` for allowed time specifications.
           :param valid_before: (optional)
               The latest time the certificate is valid for, defaulting to
               no restriction on when the certificate stops being valid.
               See :ref:`SpecifyingTimeValues` for allowed time specifications.
           :param force_command: (optional)
               The command (if any) to force a session to run when this
               certificate is used.
           :param source_address: (optional)
               A list of source addresses and networks for which the
               certificate is valid, defaulting to all addresses.
           :param permit_x11_forwarding: (optional)
               Whether or not to allow this user to use X11 forwarding,
               defaulting to `True`.
           :param permit_agent_forwarding: (optional)
               Whether or not to allow this user to use agent forwarding,
               defaulting to `True`.
           :param permit_port_forwarding: (optional)
               Whether or not to allow this user to use port forwarding,
               defaulting to `True`.
           :param permit_pty: (optional)
               Whether or not to allow this user to allocate a
               pseudo-terminal, defaulting to `True`.
           :param permit_user_rc: (optional)
               Whether or not to run the user rc file when this certificate
               is used, defaulting to `True`.
           :param touch_required: (optional)
               Whether or not to require the user to touch the security key
               when authenticating with it, defaulting to `True`.
           :param sig_alg: (optional)
               The algorithm to use when signing the new certificate.
           :param comment:
               The comment to associate with this certificate. By default,
               the comment will be set to the comment currently set on
               user_key.
           :type user_key: :class:`SSHKey`
           :type key_id: `str`
           :type version: `int`
           :type serial: `int`
           :type principals: `str` or `list` of `str`
           :type force_command: `str` or `None`
           :type source_address: list of ip_address and ip_network values
           :type permit_x11_forwarding: `bool`
           :type permit_agent_forwarding: `bool`
           :type permit_port_forwarding: `bool`
           :type permit_pty: `bool`
           :type permit_user_rc: `bool`
           :type touch_required: `bool`
           :type sig_alg: `str`
           :type comment: `str`, `bytes`, or `None`

           :returns: :class:`SSHCertificate`

           :raises: | :exc:`ValueError` if the validity times are invalid
                    | :exc:`KeyGenerationError` if the requested certificate
                      parameters are unsupported

        �
force-commandcSsg|]}t|��qSrm)r-�rw�addrrmrmrnr��s�z4SSHKey.generate_user_certificate.<locals>.<listcomp>�source-addressT�permit-X11-forwarding�permit-agent-forwarding�permit-port-forwarding�
permit-pty�permit-user-rc�no-touch-required)r��CERT_TYPE_USER)r�r3r�r�r�r�r�r�r4r5r6r7r8r9r:rr�r�r�rmrmrn�generate_user_certificate�s2Z
�
�z SSHKey.generate_user_certificate�host_keyc


Cs.|	dkr|��}	|�|||t||||i||	�S)a!Generate a new SSH host certificate

           This method returns an SSH host certificate with the requested
           attributes signed by this private key.

           :param host_key:
               The host's public key.
           :param key_id:
               The key identifier associated with this certificate.
           :param version: (optional)
               The version of certificate to create, defaulting to 1.
           :param serial: (optional)
               The serial number of the certificate, defaulting to 0.
           :param principals: (optional)
               The host names this certificate is valid for. By default,
               it can be used with any host name.
           :param valid_after: (optional)
               The earliest time the certificate is valid for, defaulting to
               no restriction on when the certificate starts being valid.
               See :ref:`SpecifyingTimeValues` for allowed time specifications.
           :param valid_before: (optional)
               The latest time the certificate is valid for, defaulting to
               no restriction on when the certificate stops being valid.
               See :ref:`SpecifyingTimeValues` for allowed time specifications.
           :param sig_alg: (optional)
               The algorithm to use when signing the new certificate.
           :param comment:
               The comment to associate with this certificate. By default,
               the comment will be set to the comment currently set on
               host_key.
           :type host_key: :class:`SSHKey`
           :type key_id: `str`
           :type version: `int`
           :type serial: `int`
           :type principals: `str` or `list` of `str`
           :type sig_alg: `str`
           :type comment: `str`, `bytes`, or `None`

           :returns: :class:`SSHCertificate`

           :raises: | :exc:`ValueError` if the validity times are invalid
                    | :exc:`KeyGenerationError` if the requested certificate
                      parameters are unsupported
        rm)r�r��CERT_TYPE_HOST)
r�rGr�r�r�r�r�r�r�r�rmrmrn�generate_host_certificate�s5
�z SSHKey.generate_host_certificate�secureShellClientrcCs"|�||||||dd||d|	|
�
S)a�
Generate a new X.509 user certificate

           This method returns an X.509 user certificate with the requested
           attributes signed by this private key.

           :param user_key:
               The user's public key.
           :param subject:
               The subject name in the certificate, expresed as a
               comma-separated list of X.509 `name=value` pairs.
           :param issuer: (optional)
               The issuer name in the certificate, expresed as a
               comma-separated list of X.509 `name=value` pairs. If
               not specified, the subject name will be used, creating
               a self-signed certificate.
           :param serial: (optional)
               The serial number of the certificate, defaulting to a random
               64-bit value.
           :param principals: (optional)
               The user names this certificate is valid for. By default,
               it can be used with any user name.
           :param valid_after: (optional)
               The earliest time the certificate is valid for, defaulting to
               no restriction on when the certificate starts being valid.
               See :ref:`SpecifyingTimeValues` for allowed time specifications.
           :param valid_before: (optional)
               The latest time the certificate is valid for, defaulting to
               no restriction on when the certificate stops being valid.
               See :ref:`SpecifyingTimeValues` for allowed time specifications.
           :param purposes: (optional)
               The allowed purposes for this certificate or `None` to
               not restrict the certificate's purpose, defaulting to
               'secureShellClient'
           :param hash_alg: (optional)
               The hash algorithm to use when signing the new certificate,
               defaulting to SHA256.
           :param comment: (optional)
               The comment to associate with this certificate. By default,
               the comment will be set to the comment currently set on
               user_key.
           :type user_key: :class:`SSHKey`
           :type subject: `str`
           :type issuer: `str`
           :type serial: `int`
           :type principals: `str` or `list` of `str`
           :type purposes: `str`, `list` of `str`, or `None`
           :type hash_alg: `str`
           :type comment: `str`, `bytes`, or `None`

           :returns: :class:`SSHCertificate`

           :raises: | :exc:`ValueError` if the validity times are invalid
                    | :exc:`KeyGenerationError` if the requested certificate
                      parameters are unsupported

        FNrm�r�)r�r3r�r�r�r�r�r�r�rr�rmrmrn�generate_x509_user_certificate:s
A�z%SSHKey.generate_x509_user_certificate�secureShellServercCs"|�||||||dd|d||	|
�
S)a
Generate a new X.509 host certificate

           This method returns an X.509 host certificate with the requested
           attributes signed by this private key.

           :param host_key:
               The host's public key.
           :param subject:
               The subject name in the certificate, expresed as a
               comma-separated list of X.509 `name=value` pairs.
           :param issuer: (optional)
               The issuer name in the certificate, expresed as a
               comma-separated list of X.509 `name=value` pairs. If
               not specified, the subject name will be used, creating
               a self-signed certificate.
           :param serial: (optional)
               The serial number of the certificate, defaulting to a random
               64-bit value.
           :param principals: (optional)
               The host names this certificate is valid for. By default,
               it can be used with any host name.
           :param valid_after: (optional)
               The earliest time the certificate is valid for, defaulting to
               no restriction on when the certificate starts being valid.
               See :ref:`SpecifyingTimeValues` for allowed time specifications.
           :param valid_before: (optional)
               The latest time the certificate is valid for, defaulting to
               no restriction on when the certificate stops being valid.
               See :ref:`SpecifyingTimeValues` for allowed time specifications.
           :param purposes: (optional)
               The allowed purposes for this certificate or `None` to
               not restrict the certificate's purpose, defaulting to
               'secureShellServer'
           :param hash_alg: (optional)
               The hash algorithm to use when signing the new certificate,
               defaulting to SHA256.
           :param comment: (optional)
               The comment to associate with this certificate. By default,
               the comment will be set to the comment currently set on
               host_key.
           :type host_key: :class:`SSHKey`
           :type subject: `str`
           :type issuer: `str`
           :type serial: `int`
           :type principals: `str` or `list` of `str`
           :type purposes: `str`, `list` of `str`, or `None`
           :type hash_alg: `str`
           :type comment: `str`, `bytes`, or `None`

           :returns: :class:`SSHCertificate`

           :raises: | :exc:`ValueError` if the validity times are invalid
                    | :exc:`KeyGenerationError` if the requested certificate
                      parameters are unsupported
        FNrmrK)r�rGr�r�r�r�r�r�r�rr�rmrmrn�generate_x509_host_certificate�s
@�z%SSHKey.generate_x509_host_certificate�ca_keyc

Cs"|�||||||d|ddd||	�
S)a�	Generate a new X.509 CA certificate

           This method returns an X.509 CA certificate with the requested
           attributes signed by this private key.

           :param ca_key:
               The new CA's public key.
           :param subject:
               The subject name in the certificate, expresed as a
               comma-separated list of X.509 `name=value` pairs.
           :param issuer: (optional)
               The issuer name in the certificate, expresed as a
               comma-separated list of X.509 `name=value` pairs. If
               not specified, the subject name will be used, creating
               a self-signed certificate.
           :param serial: (optional)
               The serial number of the certificate, defaulting to a random
               64-bit value.
           :param valid_after: (optional)
               The earliest time the certificate is valid for, defaulting to
               no restriction on when the certificate starts being valid.
               See :ref:`SpecifyingTimeValues` for allowed time specifications.
           :param valid_before: (optional)
               The latest time the certificate is valid for, defaulting to
               no restriction on when the certificate stops being valid.
               See :ref:`SpecifyingTimeValues` for allowed time specifications.
           :param ca_path_len: (optional)
               The maximum number of levels of intermediate CAs allowed
               below this new CA or `None` to not enforce a limit,
               defaulting to no limit.
           :param hash_alg: (optional)
               The hash algorithm to use when signing the new certificate,
               defaulting to SHA256.
           :param comment: (optional)
               The comment to associate with this certificate. By default,
               the comment will be set to the comment currently set on
               ca_key.
           :type ca_key: :class:`SSHKey`
           :type subject: `str`
           :type issuer: `str`
           :type serial: `int`
           :type ca_path_len: `int` or `None`
           :type hash_alg: `str`
           :type comment: `str`, `bytes`, or `None`

           :returns: :class:`SSHCertificate`

           :raises: | :exc:`ValueError` if the validity times are invalid
                    | :exc:`KeyGenerationError` if the requested certificate
                      parameters are unsupported
        TNrmrK)
r�rOr�r�r�r�r�r�rr�rmrmrn�generate_x509_ca_certificate�s
=�z#SSHKey.generate_x509_ca_certificate�openssh�
aes256-cbcr[��format_name�
passphrase�cipher_name�pbe_version�rounds�ignore_few_roundsc
Cs�|dvrNt|���}|dur/|dkrtd��t|||�\}	}
}d|	dt�|
���d}nd}|d	krL|jd
}d|d|t|�d
|d}|S|dvr�|�	�\}
}|
t
urftd|jf|f�}n
td|j|
f|f�}|dur|t|||||�}|dkr�|dur�d}nd}d|dt|�d
|d}|S|dk�rrt
�d�}d}d�|||jt|jp�d�f�}|du�rz|�d�}	t|	�\}}}}}}Wnttfy�td|�d�wts�td��d}t
�t�}d�t|�t|�f�}t|t�r�|�d�}t�||||||�}t|	|d|�||d��}t |d�}nd}d}	d}d}d}d}t!|�|}|�r@|t"t#d|d|��}|�rM|�$dd|�\}}nd}d�t%t|	�t|�t|�t|�t|j&�t|�|f�}dt|t'�dStd��) a�Export a private key in the requested format

           This method returns this object's private key encoded in the
           requested format. If a passphrase is specified, the key will
           be exported in encrypted form.

           Available formats include:

               pkcs1-der, pkcs1-pem, pkcs8-der, pkcs8-pem, openssh

           By default, openssh format will be used.

           Encryption is supported in pkcs1-pem, pkcs8-der, pkcs8-pem,
           and openssh formats. For pkcs1-pem, only the cipher can be
           specified. For pkcs8-der and pkcs-8, cipher,  hash and PBE
           version can be specified. For openssh, cipher and rounds
           can be specified.

           Available ciphers for pkcs1-pem are:

               aes128-cbc, aes192-cbc, aes256-cbc, des-cbc, des3-cbc

           Available ciphers for pkcs8-der and pkcs8-pem are:

               aes128-cbc, aes192-cbc, aes256-cbc, blowfish-cbc,
               cast128-cbc, des-cbc, des2-cbc, des3-cbc, rc4-40, rc4-128

           Available ciphers for openssh format include the following
           :ref:`encryption algorithms <EncryptionAlgs>`.

           Available hashes include:

               md5, sha1, sha256, sha384, sha512

           Available PBE versions include 1 for PBES1 and 2 for PBES2.

           Not all combinations of cipher, hash, and version are supported.

           The default cipher is aes256. In the pkcs8 formats, the default
           hash is sha256 and default version is PBES2.

           In openssh format, the default number of rounds is 128.

           .. note:: The openssh format uses bcrypt for encryption, but
                     unlike the traditional bcrypt cost factor used in
                     password hashing which scales logarithmically, the
                     encryption strength here scales linearly with the
                     rounds value. Since the cipher is rekeyed 64 times
                     per round, the default rounds value of 128 corresponds
                     to 8192 total iterations, which is the equivalent of
                     a bcrypt cost factor of 13.

           :param format_name: (optional)
               The format to export the key in.
           :param passphrase: (optional)
               A passphrase to encrypt the private key with.
           :param cipher_name: (optional)
               The cipher to use for private key encryption.
           :param hash_name: (optional)
               The hash to use for private key encryption.
           :param pbe_version: (optional)
               The PBE version to use for private key encryption.
           :param rounds: (optional)
               The number of KDF rounds to apply to the passphrase.
           :type format_name: `str`
           :type passphrase: `str` or `bytes`
           :type cipher_name: `str`
           :type hash_name: `str`
           :type pbe_version: `int`
           :type rounds: `int`

           :returns: `bytes` representing the exported private key

        ��	pkcs1-der�	pkcs1-pemNr[z9PKCS#1 DER format does not support private key encryptions!Proc-Type: 4,ENCRYPTED
DEK-Info: �,s

r�r\s PRIVATE KEY�-----BEGIN �-----
�	-----END �z	pkcs8-der�	pkcs8-pemrrbsENCRYPTED PRIVATE KEY�PRIVATE KEYrQ�rr��Unknown cipher: �?OpenSSH private key encryption requires bcrypt with KDF support�bcryptr���nones$-----BEGIN OPENSSH PRIVATE KEY-----
s"-----END OPENSSH PRIVATE KEY-----
�Unknown export format)(r"r)r�r8r{�b2a_hexrr�r�r,�OMITr�r9�os�urandomr}r�r2r�r�r'r��UnicodeEncodeErrorr7�_bcrypt_available�_OPENSSH_SALT_LENr3rare�bcryptrr(�maxrr�r~�encrypt_packet�_OPENSSH_KEY_V1r��_OPENSSH_WRAP_LEN)r�rTrUrVr�rWrXrYrq�alg�iv�headers�keytyper��
pkcs8_data�check�nkeys�key_size�iv_size�
block_size�_r�salt�kdf_datar��cipher�mac�padrmrmrn�export_private_key
s�Q����

������
����

�

����


����zSSHKey.export_private_keycCs2|dvr%t|���}|dkr#|jd}d|dt|�d|d}|S|dvrW|��\}}t|�}|tur@t|jf|f�}n	t|j|f|f�}|dkrUd	t|�d
}|S|dkry|jrdd|j}nd
}|j	dt
�|j�dd�|dS|dkr�|jr�d|jd}nd
}d|t|j�dSt
d��)a�Export a public key in the requested format

           This method returns this object's public key encoded in the
           requested format. Available formats include:

               pkcs1-der, pkcs1-pem, pkcs8-der, pkcs8-pem, openssh, rfc4716

           By default, openssh format will be used.

           :param format_name: (optional)
               The format to export the key in.
           :type format_name: `str`

           :returns: `bytes` representing the exported public key

        rZr\s PUBLIC KEYr^r_r`rarbs-----BEGIN PUBLIC KEY-----
s-----END PUBLIC KEY-----
rQ� r�Nrsrt�rfc4716�
Comment: "�"
� ---- BEGIN SSH2 PUBLIC KEY ----
�---- END SSH2 PUBLIC KEY ----
rj)r"r+r�r�r-r rlr�r�r�r{r|r�r�)r�rTrqrzr�r{r�rmrmrn�export_public_key�sd

������������zSSHKey.export_public_keycO�t||j|i|���dS)a�Write a private key to a file in the requested format

           This method is a simple wrapper around :meth:`export_private_key`
           which writes the exported key data to a file.

           :param filename:
               The filename to write the private key to.
           :param \*args,\ \*\*kwargs:
               Additional arguments to pass through to
               :meth:`export_private_key`.
           :type filename: :class:`PurePath <pathlib.PurePath>` or `str`

        N�r/r��r�r�argsr�rmrmrn�write_private_key�zSSHKey.write_private_keycOr�)a�Write a public key to a file in the requested format

           This method is a simple wrapper around :meth:`export_public_key`
           which writes the exported key data to a file.

           :param filename:
               The filename to write the public key to.
           :param \*args,\ \*\*kwargs:
               Additional arguments to pass through to
               :meth:`export_public_key`.
           :type filename: :class:`PurePath <pathlib.PurePath>` or `str`

        N�r/r�r�rmrmrn�write_public_keyr�zSSHKey.write_public_keycO�t||j|i|��d�dS)a�Append a private key to a file in the requested format

           This method is a simple wrapper around :meth:`export_private_key`
           which appends the exported key data to an existing file.

           :param filename:
               The filename to append the private key to.
           :param \*args,\ \*\*kwargs:
               Additional arguments to pass through to
               :meth:`export_private_key`.
           :type filename: :class:`PurePath <pathlib.PurePath>` or `str`

        �abNr�r�rmrmrn�append_private_key'�zSSHKey.append_private_keycOr�)a�Append a public key to a file in the requested format

           This method is a simple wrapper around :meth:`export_public_key`
           which appends the exported key data to an existing file.

           :param filename:
               The filename to append the public key to.
           :param \*args,\ \*\*kwargs:
               Additional arguments to pass through to
               :meth:`export_public_key`.
           :type filename: :class:`PurePath <pathlib.PurePath>` or `str`

        r�Nr�r�rmrmrn�append_public_key8r�zSSHKey.append_public_keyru�r�r�)r)r_r>)rrrmrr2NNTTTTTTrmrm)rrrmrr2rmrm)NNrmrr2rJrmrm)NNrmrr2rMrmrm)NNrr2Nrmrm)rQNrRrr[rSF�rQ)Xr�r�r�r�r�r��__annotations__r�rr�r��setr�rr�rer�r�rr!r�r�r�r%r��classmethodr��objectr�r�r�r�r�r�r6r�r��propertyr�r�r&r�rb�_CertPrincipals�_Time�_OpenSSHCertOptionsr*�_Commentr��X509CertPurposesr�r�r�r�rrrrr+r
rrrr r"r�r�r)r+rr,r-r�r�r.r1rFrIrLrNrPr)r�r�r�r�r�r�rmrmrmrnr>�sV
��������
�
+����������	�

�,		��
���
�	!
�
�
���������
�����	�	�
��
�|��������
�?�����������
�I�����������
�G��������
�C�������
�<@c@sBeZdZdZdZdZdedeedeededede	fd	d
�Z
ededede
eede	d
df
dd��Zded
efdd�Zd
efdd�Zd
efdd�Zd
efdd�Zd
e
efdd�Z		d-deded
e
efdd �Z		d-de	deded
d!fd"d#�Zd.d%ed
efd&d'�Z	$d.d(ed%ed
d!fd)d*�Z	$d.d(ed%ed
d!fd+d,�Zd!S)/r?z+Parent class which holds an SSH certificateFr�r��host_key_algorithmsr�r�r�cCs,||_||_||_||_||_|�|�dSru)r�r�r�r�r�r)r�r�r�r�r�r�r�rmrmrnr�PszSSHCertificate.__init__r��key_handlerr_cCr�)�1Construct an SSH certificate from packetized datar��r�r�r�r�r�rmrmrn�	construct[�zSSHCertificate.construct�othercCst|t|��o|j|jkSru)ra�typer�)r�r�rmrmrn�__eq__cs
�zSSHCertificate.__eq__cCr�ru)�hashr�r�rmrmrn�__hash__gs
zSSHCertificate.__hash__cCr�)z5Return the algorithm associated with this certificater�r�r�rmrmrnr�jr�zSSHCertificate.get_algorithmcCr�)z[Return whether a comment is set for this certificate

           :returns: `bool`

        r�r�rmrmrnr�or�zSSHCertificate.has_commentcCr
)z�Return the comment associated with this certificate as a
           byte string

           :returns: `bytes` or `None`

        )r�r�rmrmrnr�x�z SSHCertificate.get_comment_bytesr�r�r�rcCs|jr
|j�||�SdS)a5Return the comment associated with this certificate as a
           Unicode string

           :param encoding:
               The encoding to use to decode the comment as a Unicode
               string, defaulting to UTF-8
           :param errors:
               The error handling scheme to use for Unicode decode errors
           :type encoding: `str`
           :type errors: `str`

           :returns: `str` or `None`

           :raises: :exc:`UnicodeDecodeError` if the comment cannot be
                    decoded using the specified encoding

        N)r�r�)r�r�rrmrmrnr�szSSHCertificate.get_commentNcCr)ajSet the comment associated with this certificate

           :param comment:
               The new comment to associate with this key
           :param encoding:
               The Unicode encoding to use to encode the comment,
               defaulting to UTF-8
           :param errors:
               The error handling scheme to use for Unicode encode errors
           :type comment: `str`, `bytes`, or `None`
           :type encoding: `str`
           :type errors: `str`

           :raises: :exc:`UnicodeEncodeError` if the comment cannot be
                    encoded using the specified encoding

        Nrrrmrmrnr�r	zSSHCertificate.set_commentrQrTcCs�|jr|dkrtd��n|dvrtd��|dkr|jS|dkr(dt|j�dS|d	krJ|jr5d
|j}nd}|jd
t�|j�dd
�|dS|dkrf|jrYd|jd}nd}d|t|j�dStd��)a�Export a certificate in the requested format

           This function returns this certificate encoded in the requested
           format. Available formats include:

               der, pem, openssh, rfc4716

           By default, OpenSSH format will be used.

           :param format_name: (optional)
               The format to export the certificate in.
           :type format_name: `str`

           :returns: `bytes` representing the exported certificate

        r�z6RFC4716 format is not supported for X.509 certificates)�der�pemz>DER and PEM formats are not supported for OpenSSH certificatesr�r�s-----BEGIN CERTIFICATE-----
s-----END CERTIFICATE-----
rQr�r�Nrsrtr�r�r�r�rj)�is_x509r�r�r�r�r�r{r|)r�rTr�rmrmrn�export_certificate�sJ���������z!SSHCertificate.export_certificatercCst||�|��dS)a�Write a certificate to a file in the requested format

           This function is a simple wrapper around export_certificate
           which writes the exported certificate to a file.

           :param filename:
               The filename to write the certificate to.
           :param format_name: (optional)
               The format to export the certificate in.
           :type filename: :class:`PurePath <pathlib.PurePath>` or `str`
           :type format_name: `str`

        N�r/r��r�rrTrmrmrn�write_certificate�sz SSHCertificate.write_certificatecCst||�|�d�dS)a�Append a certificate to a file in the requested format

           This function is a simple wrapper around export_certificate
           which appends the exported certificate to an existing file.

           :param filename:
               The filename to append the certificate to.
           :param format_name: (optional)
               The format to export the certificate in.
           :type filename: :class:`PurePath <pathlib.PurePath>` or `str`
           :type format_name: `str`

        r�Nr�r�rmrmrn�append_certificate�sz!SSHCertificate.append_certificater�r�)r�r�r�r�r��
is_x509_chainr�rr>r�r�r�r6rrr�r�r�r�rbr�rer�r�r�rrr�r+r�r�rmrmrmrnr?Jsj���
�

���	
��
���
�7��
����csZeZdZUdZdZeed<dZeed<dZeed<dZ	eed<iZ
eed<iZeed<iZ
eed	<iZeed
<deded
edeededededededededef�fdd�Zedddedddedededeededededededdfdd��Zedededeeededdf
d d!��Zededededededededed"edefd#d$��Zededeedefd%d&��Ze ded'edefd(d)��Z!e d*e"defd+d,��Z#e d-e"defd.d/��Z$e d0e"defd1d2��Z%e d3ede&fd4d5��Z'e dedefd6d7��Z(e dedee)fd8d9��Z*e 	:dCded;ed<e&defd=d>��Z+ded?eedd@fdAdB�Z,�Z-S)Dr@z(Class which holds an OpenSSH certificaterm�_user_option_encoders�_user_extension_encoders�_host_option_encoders�_host_extension_encoders�_user_option_decoders�_user_extension_decoders�_host_option_decoders�_host_extension_decodersr�r�rqr��options�signing_keyr�r�r�r�r�r�c

sTt��||j|jp|f|||�||_||_||_||_||_|	|_	|
|_
||_dSru)�superr�r�r�r�r�r��_serial�
_cert_type�_key_id�_valid_after�
_valid_before)
r�r�r�rqr�r�r�r�r�r�r�r�r���	__class__rmrnr�s
�
zSSHOpenSSHCertificate.__init__r>r�r_c
Cs�d�dd�|D��}
|tkr|�|
|j�}|�|
|j�}n|�|
|j�}|�|
|j�}|��}d�t|�|�	|||||
||	||�	t|j
�f�}|t|�||��7}|��}||||||
||||||	|�S)r�r�cs��|]}t|�VqdSru�r2r�rmrmrnrz4��z1SSHOpenSSHCertificate.generate.<locals>.<genexpr>)r}rE�_encode_optionsr�r�r�r�r1r2�_encoder�r�)r�r�r�r�r�r�r�r�r�r�r�r�r��principal_bytesr��cert_extensionsrqrmrmrnr�,s:����
��
�zSSHOpenSSHCertificate.generater�r�c
Csl|dusJ�|�||�\	}}}}}	}
}}}
t|���}|��}|��}|��|�||�s1td��|�|�}|��}z|�d�}Wnt	yMtd�d�wt
|	�}g}	|rsz	|���d�}Wnt	yktd�d�w|	�|�|sV|tkr�|�
||jd�}|�|�
|
|jd��n|tkr�|�
||jd�}|�|�
|
|jd��ntd��|||||	||||||
||�S)	r�NzInvalid certificate signaturer�zInvalid characters in key IDz$Invalid characters in principal nameTFzUnknown certificate type)�_decoder/r&�get_consumed_payload�	check_endr�r�r�r��UnicodeDecodeErrorr6�appendrE�_decode_optionsr��updater�rHr�r�)r�r�r�r�r�r�r�r�r�r�r�r�r��
extensionsr�rq�	signaturer��key_id_bytes�	principalr�rmrmrnr�Rsb

�

���
�	����
�zSSHOpenSSHCertificate.constructr�c

Cr�)zEncode an SSH certificater��
r�r�r�r�r�r�r�r�r�r�rmrmrnr��szSSHOpenSSHCertificate._encodecCr�)zDecode an SSH certificater�)r�r�r�rmrmrnr��szSSHOpenSSHCertificate._decode�encoderscCsDg}|D]\}}|�|�}|r|�t|�t||���qd�|�S)z(Encode options found in this certificater�)�getr�r2r})r�r�r0�name�encoder�valuermrmrnr��s
�
z%SSHOpenSSHCertificate._encode_options�_valuecCr�)zEncode a boolean option valuer�rm)r�rmrmrn�_encode_bool�r�z"SSHOpenSSHCertificate._encode_boolr4cCsttt|��S)zEncode a force-command option)r2rr))r4rmrmrn�_encode_force_cmd�sz'SSHOpenSSHCertificate._encode_force_cmdr5cCstdd�ttt|�D��S)zEncode a source-address optioncss�|]
}t|��d�VqdS)r�N)rer�r<rmrmrnrz�s��z<SSHOpenSSHCertificate._encode_source_addr.<locals>.<genexpr>)r1rrr,)r5rmrmrn�_encode_source_addr�s�z)SSHOpenSSHCertificate._encode_source_addr�_packetcCr�)zDecode a boolean option valueTrm)r�rmrmrn�_decode_bool�r�z"SSHOpenSSHCertificate._decode_boolcCs*z|���d�WStytd�d�w)zDecode a force-command optionr�zInvalid characters in commandN)r&r�r�r��r�rmrmrn�_decode_force_cmd�s

�z'SSHOpenSSHCertificate._decode_force_cmdc	Cs2z
dd�|��D�WSttfytd�d�w)zDecode a source-address optioncSsg|]	}t|�d���qS)r�)r-r�r<rmrmrnr��s�z=SSHOpenSSHCertificate._decode_source_addr.<locals>.<listcomp>zInvalid source addressN)�get_namelistr�rkr�r�rmrmrn�_decode_source_addr�s�
�z)SSHOpenSSHCertificate._decode_source_addrT�decoders�criticalcCspt|�}i}|r6|��}|�|�}|r't|���}||�||�d�<|��n
|r4td|jddd���|s|S)z(Decode options found in this certificater�zUnrecognized critical option: �replace�r)r6r&r�r�r�r�)r�r�r�r�r0r��decoder�data_packetrmrmrnr��s

��z%SSHOpenSSHCertificate._decode_optionsr�NcCsj|j|kr	td��t��}||jkrtd��||jkrtd��|dur/|jr1||jvr3td��dSdSdS)zValidate an OpenSSH certificatezInvalid certificate typezCertificate not yet validzCertificate expiredNzCertificate principal mismatch)r�rkrfr�r�r�)r�r�r�r`rmrmrn�validate�s



�zSSHOpenSSHCertificate.validate)T).r�r�r�r�r��_OpenSSHCertEncodersr�r�r�r�r��_OpenSSHCertDecodersr�r�r�r�r>rrer�rbr�r�r�r�r6rrr�r��_OpenSSHCertParamsr��staticmethodr�r�r�r�r�r�r�r�r,r�r�r��
__classcell__rmrmr�rnr@s�
�������������������%

���8����������
	���"c@s�eZdZdZdejfdejffZdejfdejfdejfdejfdejfd	ejffZ	ej
ejd
�Zej
ej
ej
ej
ej
ej
d�Zeded
ededededededededefdd��Zededeedefdd��ZdS)�SSHOpenSSHCertificateV01z9Encoder/decoder class for version 01 OpenSSH certificatesr;r>r?r@rArBrCrD)s
force-commandssource-address)spermit-X11-forwardingspermit-agent-forwardingspermit-port-forwardings
permit-ptyspermit-user-rcsno-touch-requiredr�r�r�r�r�r�r�r�r�r_c

CsRd�tt�d��|��t|�t|�t|�t|�t|�t|�t|�t|	�td�f�S)z#Encode a version 01 SSH certificater�� r�)r}r2rmrnr�r4r3r�rmrmrnr�s�z SSHOpenSSHCertificateV01._encoder�r�c
	Csp|��}|�|�}|��}|��}|��}|��}|��}	|��}
|��}|��}|��}||||||	|
||f	S)z#Decode a version 01 SSH certificate)r&r��
get_uint64�
get_uint32)
r�r�r�r�r�r�r�r�r�r�r�r�r�rmrmrnr�)s

�z SSHOpenSSHCertificateV01._decodeN)r�r�r�r�r@r�r�r�r�r�r�r�r�r�r�r�r>rbrer�r�r6rr�r�rmrmrmrnr��sT��
��	��������r�cs.eZdZdZdZ	d.dedddef�fdd	�
Zd
ddee	de
dd
dfdd�Zede
dedeeeded
df
dd��Zedddddedeedeededededeededed ed!eded
dfd"d#��Ze	d.d$eded
dfd%d&��Z	'	'd/d(edd)eddee	ded*ed+ed
dfd,d-�Z�ZS)0r�z0Encoder/decoder class for SSH X.509 certificatesTNr��	x509_certrr�csRt��d|j|j|j||j|jp|�|j|_|j|_|j|_|j	|_	||_
dS)Nr#)r�r�r�r�rqr�r�r��issuer_hashr�r)r�r�rr�r�rmrnr�Cs
�
zSSHX509Certificate.__init__�cert�trusted_cert_paths�trust_storer_c	
Cs�|j}|D]>}d}z/	t||dt|��}|d7}tdt|��}|j|jks+||vr,q
|�|�|�|||�qt	t
fyCYqwdS)z:Look up certificates by issuer hash to build a trust storerT�.rr�N)rrrer�read_certificater�r��add�_expand_trust_store�OSErrorr�)	r�rrrr�path�idx�	cert_path�crmrmrnr	Os"
���z&SSHX509Certificate._expand_trust_storer�r�r�cCr�)�7Construct an SSH X.509 certificate from packetized data��RuntimeErrorr�rmrmrnr�hr�zSSHX509Certificate.constructr�r>r�r�r�r�r�r�r�r�r�r�r�cCs8|��}t|j|j|||||||	|
|||
|�}|||�S)r�)r1rr�)r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrmrmrnr�ps
�
zSSHX509Certificate.generaterqc
CsJzt|�}t|j�}Wnty}ztt|��d�d}~ww||||�S)z0Construct an SSH X.509 certificate from DER dataN)r�import_public_keyr�rkr�re)r�rqr�rr��excrmrmrn�construct_from_der�s��z%SSHX509Certificate.construct_from_derr��trust_chain�
trusted_certs�user_principal�host_principalc	Cs`dd�|D�t|�B}|r |�|||�|D]	}|�|||�q|j�dd�|D�|||�dS)�#Validate an X.509 certificate chaincSsh|]
}|j|jkr|�qSrm)r�r��rwrrmrmrn�	<setcomp>�sz4SSHX509Certificate.validate_chain.<locals>.<setcomp>cSsg|]}|j�qSrm)rrrmrmrnr��sz5SSHX509Certificate.validate_chain.<locals>.<listcomp>N)r�r	rr�)	r�rrrr�rrrrrmrmrn�validate_chain�s��z!SSHX509Certificate.validate_chainru�r�r�)r�r�r�r�r�r>r�r�rr+rr	r�r6r�rrr�rerbr�r�r�r�rrr�rmrmr�rnr�>s�����
�

�������������������������r�cs�eZdZdZdZdedeedeedef�fdd�Z	e
dedeedeed	efd
d��Zede
ded
eeeded	df
dd��Zededd	dfdd��Zded	efdd�Z		ddeedeedeedededed	dfdd�Z�ZS) �SSHX509CertificateChainz8Encoder/decoder class for an SSH X.509 certificate chainTr��certs�ocsp_responsesr�c
sx|dj}|�|||�}t��||j|j|||�ttt|�}|d}|d}	|j|_|	j	|_	|j
|_
||_||_dS)Nrrs)
r��_public_datar�r�r�rrr�r�r�r��_certs�_ocsp_responses)
r�r�rr r�r�rq�
x509_certs�
first_cert�	last_certr�rmrnr��s
�
z SSHX509CertificateChain.__init__r_cCsHt|�tt|��d�dd�|D��tt|��d�dd�|D��S)z!Return the X509 chain public datar�css�|]}t|j�VqdSru)r2r�rrmrmrnrz�s�z7SSHX509CertificateChain._public_data.<locals>.<genexpr>csr�rur�)rw�resprmrmrnrz�r�)r2r3rr})r�rr rmrmrnr!�s�
��z$SSHX509CertificateChain._public_datar�r�c	s^���}�fdd�t|�D�}���}�fdd�t|�D�}���|s(td��|||||�S)rcsg|]}t�����qSrm)�import_certificater&�rwr�r�rmrnr��s�z5SSHX509CertificateChain.construct.<locals>.<listcomp>csg|]}����qSrm)r&r)r�rmrnr��r�zNo certificates present)rr~r�r�)	r�r�r�r�r��
cert_countr�ocsp_resp_countr rmr�rnr��s
�z!SSHX509CertificateChain.constructr?cCs|d}||j|d|���S)z:Construct an SSH X.509 certificate chain from certificatesrrm)r�r�)r�rrrmrmrn�construct_from_certs�sz,SSHX509CertificateChain.construct_from_certscCs|�||j|j�S)z8Adjust public data to reflect chosen signature algorithm)r!r"r#)r�r�rmrmrn�adjust_public_data�sz*SSHX509CertificateChain.adjust_public_datar�rr�
revoked_certsr�rrNcCsH|r|jD]
}||vrtd��q|jd�|jdd�|||||�dS)rz.Revoked X.509 certificate in certificate chainrrN)r"rkr)r�rrr.r�rrrrmrmrnr�s
��z&SSHX509CertificateChain.validate_chainr)r�r�r�r�r�r�rr?r�r�r�r!r�r6rrr>r�r,r-r�r+rr�rerr�rmrmr�rnr�sT����	

���
��������rc@s6eZdZdZdZ				d-dededeedeed	ed
edee	deed
e
de
fdd�Zdefdd�Z
ede
fdd��Zede
fdd��Zdefdd�Zdefdd�Zdeefdd�Z		d.d ed!edeefd"d#�Z		d.d
ed ed!eddfd$d%�Zde	ddfd&d'�Zdeddfd(d)�Zd*edefd+d,�ZdS)/rAa7Parent class which represents an asymmetric key pair

       This is an abstract class which provides a method to sign data
       with a private key and members to access the corresponding
       algorithm and public key or certificate information needed to
       identify what key was used for signing.

    �unknownNFr�rr�r�r�r�rrr�r�cCs�||_||_|�|�||_||_|	|_|
|_|rA|jj|jkr$t	d��|j
|_
|jr0|j
|_n||_|j
|_
|j|_|j|_dS||_
||_||_
||_||_dS)N�Certificate key mismatch)�
key_algorithm�key_public_datar�_certr�r�r�r�r�rkr�r�rr�r�)r�r�rr�r�r�r�rrr�r�rmrmrnr�s,


zSSHKeyPair.__init__r_cCr
)z�Return what type of key pair this is

           This method returns 'local' for locally loaded keys, and
           'agent' for keys managed by an SSH agent.

        )�	_key_typer�rmrmrn�get_key_type/r�zSSHKeyPair.get_key_typecCr�)z/ Return if this key pair has an associated cert)r�r3r�rmrmrn�has_cert9s
zSSHKeyPair.has_certcCs|jr|jjSdS)z; Return if this key pair has an associated X.509 cert chainF)r3r�r�rmrmrn�has_x509_chain?r�zSSHKeyPair.has_x509_chaincCr�)z2Return the algorithm associated with this key pairr�r�r�rmrmrnr�Er�zSSHKeyPair.get_algorithmcCr')�9Return binary encoding of keypair for upload to SSH agentz)Private key export to agent not supported)r�r�rmrmrn�get_agent_private_keyJr*z SSHKeyPair.get_agent_private_keycCr�)z~Return the comment associated with this key pair as a
           byte string

           :returns: `bytes` or `None`

        r�r�rmrmrnr�PszSSHKeyPair.get_comment_bytesr�r�r�rcCr)a2Return the comment associated with this key pair as a
           Unicode string

           :param encoding:
               The encoding to use to decode the comment as a Unicode
               string, defaulting to UTF-8
           :param errors:
               The error handling scheme to use for Unicode decode errors
           :type encoding: `str`
           :type errors: `str`

           :returns: `str` or `None`

           :raises: :exc:`UnicodeDecodeError` if the comment cannot be
                    decoded using the specified encoding

        NrrrmrmrnrZszSSHKeyPair.get_commentcCr)agSet the comment associated with this key pair

           :param comment:
               The new comment to associate with this key
           :param encoding:
               The Unicode encoding to use to encode the comment,
               defaulting to UTF-8
           :param errors:
               The error handling scheme to use for Unicode encode errors
           :type comment: `str`, `bytes`, or `None`
           :type encoding: `str`
           :type errors: `str`

           :raises: :exc:`UnicodeEncodeError` if the comment cannot be
                    encoded using the specified encoding

        Nrrrmrmrnrrr	zSSHKeyPair.set_commentcCsX|jj|jkrtd��||_|j|_|jr|j|_n|j|_|j	|_	|j
|_
|j|_dS)z$Set certificate to use with this keyr0N)r�r�r2rkr3r�r�rr1r�r�)r�rrmrmrn�set_certificate�s
zSSHKeyPair.set_certificatecCsbzt|}Wn	tyYnw||_|js||_dS|jr/||_td|j�}|�|�|_	dSdS)z4Set the signature algorithm to use when signing datarN)
rVr�rr6r�r7rr3r-r�)r�rrrmrmrn�set_sig_algorithm�s�
�zSSHKeyPair.set_sig_algorithmrqcCr��z*Sign a block of data with this private keyrr�rmrmrnr��r�zSSHKeyPair.sign)NNFFr�)r�r�r�r�r4r�rr�rr?r�r�rer5r�r6r7r�r9r�rrr:r;r�rmrmrmrnrA�sb	��������
�'

��
���
�cs`eZdZdZdZ		ddedeedeef�fdd�
Zd	e	fd
d�Z
de	d	e	fd
d�Z�ZS)�SSHLocalKeyPairz�Class which holds a local asymmetric key pair

       This class holds a private key and associated public data
       which can either be the matching public key or a certificate
       which has signed that public key.

    �localNr��pubkeyrcs�|r|j|jkrtd��|��r|��}n|r |��r |��}n
|r+|��r+|��}nd}t��|j|j|j|j|j|||��|j	|j
�
||_dS)NzPublic key mismatch)r�rkr�r�r�r�r�r�rr�r�r�)r�r�r?rr�r�rmrnr��s



�
zSSHLocalKeyPair.__init__r_cCs4|jrt|j�|j��}n|j��}t|j�|S)r8)r3r2r�r�r.r�r�r�rmrmrnr9�s�
z%SSHLocalKeyPair.get_agent_private_keyrqcCs|j�||j�Sr<)r�r�rr�rmrmrnr���zSSHLocalKeyPair.sign�NN)
r�r�r�r�r4r>rr?r�r�r9r�r�rmrmr�rnr=�s��r=cCs�|�dd�}t|�dkrtd��t|�dkrd}n|d}|dtvr-|dtvr-td��z
|d|t�|d�fWStjyGtd�d�w)z1Parse an OpenSSH format public key or certificateNr[z)Invalid OpenSSH public key or certificaterz$Unknown OpenSSH public key algorithmr)r�rr�rTrUr{�
a2b_base64�Error)rq�liner�rmrmrn�_parse_openssh�s ��rEcCs�d}d}i}	|�d|�d}|r|||�n||d�}|��}d|vr6|�dd�\}}|��||��<nn|dkr=|nt|�}qz|t�||d��fWStjy[td�d�w)zParse a PEM data blockrNTrtr�:zInvalid PEM data�	�find�rstripr�r�rr{rBrCr�)rq�start�endryrD�hdrr�rmrmrn�
_parse_pem�s$�
�rMcCsd}d}d}d}	|�d|�d}|r|||�n||d�}|��}|dd�dkr4||dd�7}n4||7}d	|vrg|�d	d�\}}|��d
krd|��}|dd�dkrd|dd�dkrd|dd�}d}nn|dkrn|nt|�}q	z|t�||d��fWStjy�td�d�w)
zParse an RFC 4716 data blockrNr�Trtrrs�\rFsComment�"zInvalid RFC 4716 datarG)rqrJrKrLr�rDr�rmrmrn�_parse_rfc4716	s4 �
�rPrJ�header�fmtcCsbt�d|dd�d|dd�dtj��||�}|s%td|�d���|||���|��fS)	z0Match a block of data wrapped in a header/footer�^N�sEND�
s
[ \t\r\f\v]*$zMissing z footer)�re�compile�M�searchr�rJrK)rqrJrQrRrlrmrmrn�_match_block>	s"���rZrz�publicc
Cs^|�d�rz
t|�\}}d|f|fWStyYnwd}d}|dkr�|�d|�d}|r4|||�n||d�}|��}|�d�rp|�d|d	�rp|d
dt|����}t|||d�\}}t	|�\}}d
|||f|fS|r�|dkr�t|||d�\}}dt
|�|fSzt|�}	Wn	ty�Yn
wd|	|r�|fSt|�fS|}|dks$ddt|�fS)z=Find the next key/certificate and call the appropriate decode�0r�rNrtrr^r�s-----���PEMr�s---- BEGIN SSH2 PUBLIC KEY ----zRFC 4716r�rQrm)
r%r$rrHrI�endswithrr�rZrMrPrEr�)
rqrzr[r�rKrJrDr�ryrrmrmrn�_match_nextK	sB
�
���rar�r��unsafe_skip_rsa_key_validationcCsnt�|�}|durtd|�d���|�|�}|dur&td|�d��d���|dkr2tt|�|f}|�|�S)r�N�Unknown PEM key type: r��Invalid � private keysRSA)rXr�r�r�r�rrr�)r�r�rb�handlerr�rmrmrn�_decode_pkcs1_privatex	s
�
��
rgcCsVt�|�}|durtd|�d���|�|�}|dur&td|�d��d���|�|�S)r�Nrcr�rd� public key)rXr�r�r�r�r�)r�r�rfr�rmrmrn�_decode_pkcs1_public�	s
�

ricCst|t�r�t|�dkr�|ddvr�t|dt�r�dt|d�kr&dkr�ntd
��t|dt�r�t|d�dkrA|d\}}n	|ddt}}t�|�}|durWtd��|�||d�}|durv|j	rl|j	�
d�nd	}td
|�d���|td�kr�tt
|�|f}|�|�Std
��)r��r)rrrr[N�Unknown PKCS#8 algorithmr��PKCS#8rdrez1.2.840.113549.1.1.1zInvalid PKCS#8 private key)ra�tuplerr�rlrYr�r�r�r�r�r!rrr�)r�rbrwr�rfr��key_typermrmrn�_decode_pkcs8_private�	s0�
���
rocCst|t�r}t|�dkr}t|dt�r}dt|d�kr dkr}ntd
��t|dt�r}|djdkr}t|d�dkrB|d\}}n	|ddt}}t�|�}|durXtd��|�	||dj
�}|durx|jrn|j�d�nd}td|�d	���|�
|�Std
��)r�r[rrNrkr�rlrdrhzInvalid PKCS#8 public key)rarmrr �unusedrlrYr�r�r�r�r�r�r�)r�rwr�rfr�rnrmrmrn�_decode_pkcs8_public�	s.���
��
rqrUcCs��z8|�t�std��|tt�d�}t|�}|��}|��}|��}|��}|��}|��}	|��}
|dkr;td��|dkr�|durGtd��zt|�\}}}}}}Wnt	ydt
d|�d��d�w|d	krrt
d
|�d���tsxt
d��t|�}|��}
|��}|�
�t|t�r�|�d�}ztj||
|||d
d�}Wnty�t
d�d�wt||d|�||d��}|�dd|	d|
�}|dur�t
d��|}	t|	�}|��}|��}||kr�|dkr�t
d�d�td��|��}t�|�}|s�td��|�|�}|��}|��}t|�dk�s|ttdt|�d��k�r td��|dk�r-tt|�|f}|�|�}|�|�|WSt�yFtd�d�w)z$Decode an OpenSSH format private key�%Unrecognized OpenSSH private key typeNr�Invalid OpenSSH private keyri�=Passphrase must be specified to import encrypted private keysrer�rgz
Unknown kdf: rfr�T)rYrr�zIncorrect passphrasez%Unknown OpenSSH private key algorithm�sssh-rsa) r%rur�rr6r&r�get_remaining_payloadr'r�r7r�rpr�rarer�rrrrkr(�decrypt_packetrTr�r�r�r~rrr�rr5)rqrUrbr�rVrr�r}r�r�r�r~rr�rX�
bcrypt_keyr��
decrypted_key�check1�check2rwrfr�r�r�r�rmrmrn�_decode_openssh_private�	s�
����


���
�


*
�


�r|cCs�z6|�t�s
td��|tt�d�}t|�}|��}|��}|��}|��}|��}|dkr2td��t|�WStyBtd�d�w)z3Decode public key within OpenSSH format private keyrrNrrs)	r%rur�rr6r&rr/r5)rqr�r�r}r?rmrmrn�_decode_openssh_public;
s 


�r}c	Cs�|durzt||�}Wn	tyYnwzt||�WSty$YnwtD]}z	t|||�WSty;Yq'wtd��)zDecode a DER format private keyNzInvalid DER private key)r;r7ror�rXrg)r�rUrbr�rmrmrn�_decode_der_privateS
s(��
��r~c	CsRzt|�WStyYnwtD]}zt||�WSty$Yqwtd��)zDecode a DER format public keyzInvalid DER public key)rqr�rXri)r�r�rmrmrn�_decode_der_publics
s
��rr�cCst�||�S)z%Decode a DER format X.509 certificate)r�r)rqr�rmrmrn�_decode_der_certificate�
sr�ryc	Cs:|dkr
t|||�S|�d�dkr[|durtd��|�dd��d�}t|�d	kr,td
��|\}}zt�|�}Wn
tjyDtd
�d�wz	t||||�}Wnt	yZtd�d�wzt
|�}Wntymtd�d�w|d
kr�|durztd��d}zt||�}Wnt	y�td�d�w|r�t
|||�St||�S)zDecode a PEM format private key�OPENSSHs	Proc-Types4,ENCRYPTEDNrtsDEK-Infor�r]r[zInvalid PEM encryption paramsz$Unable to decrypt PKCS#1 private keyzInvalid PEM private keys	ENCRYPTEDz$Unable to decrypt PKCS#8 private key)r|r�r�r�rr{�a2b_hexrCr:r7r#rr;rgro)	r�ryrqrUrb�dek_inforwrxr�rmrmrn�_decode_pem_private�
sX�
���
����
r�cCs<zt|�}Wntytd�d�w|rt||�St|�S)zDecode a PEM format public keyzInvalid PEM public keyN)r#rr�rirq)r�rqr�rmrmrn�_decode_pem_public�
s
�
r�cCsT|dkrzt|�\}}|d|�}Wntytd�d�w|r%td��t�|�S)z%Decode a PEM format X.509 certificatesTRUSTEDNzInvalid PEM trusted certificatezInvalid PEM certificate)r$rr�r�r)r�rqr�rKrmrmrn�_decode_pem_certificate�
s
�
r�c	Csft|d�\}}}|dkrt|d||�}||fS|dkr-|\}}}t|||||�}||fSd}||fS)zDecode a private keyrcr�rr�N)rar~r�)	rqrUrbrR�key_inforKr�r�ryrmrmrn�_decode_private�
s
�	�

��r�c	Cst|ddd�\}}}|dkrt|d�}||fS|dkr*|\}}}t||�}||fS|dkrI|\}}}t|�}||jkr@td��|�|�||fS|d	kr^|\}}t|�}|�|�||fSt|d
�\}}}|dkrz|ddkrzt|d�}||fSt|d
d�\}}|r�|�	�}||fS)zDecode a public keys
PUBLIC KEYT�r[r�rr�rQzPublic key algorithm mismatchr�rcr�r[NF)
rarr�r/r�r�rr}r�r1)	rqrRr�rKr�r�r�r�r�rmrmrn�_decode_public�
s8�

�


�
��r�c	Cs�t|ddd�\}}}|dkrt|d|��}||fS|dkr,|\}}}t||�}||fS|dkrL|\}}}|�d�rCt||�}||fSt||�}||fS|d	kr]|\}}t||�}||fSd}||fS)
zDecode a certificatesCERTIFICATETr�r�Nr�rQr#r�)rar�r�r%�decode_ssh_certificate)	rqrRr�rKrr�r�r�r�rmrmrn�_decode_certificate"s*�

�


	
��
�r�cCs:g}|rt|||�\}}|r|�|�||d�}|s|S)zDecode a private key listN)r�r�)rqrUrb�keysr�rKrmrmrn�_decode_private_list?s�
�	r�cC�6g}|rt|�\}}|r|�|�||d�}|s|S)zDecode a public key listN)r�r�)rqr�r�rKrmrmrn�_decode_public_listR�
�r�cCr�)zDecode a certificate listN)r�r�)rqrrrKrmrmrn�_decode_certificate_listbr�r��sk_algrfr�cGs||ft|<dS)z%Register a new security key algorithmN)rZ)r�rfr�rmrmrn�register_sk_algrr@r�r��defaultr�cCsR|s|j}t�|�|rt�|�|t|<|jr|t|j<|jr'|t|j<dSdS)z#Register a new public key algorithmN)	r�rN�extendrOrTr�rXr�rY)r�rfr�r�rmrmrn�register_public_key_algxs


�r�r��cert_algorithmr�r�cCs@t�|�|rt�|�||ft|<|t|<||ft||f<dS)z$Register a new certificate algorithmN)rPr�rQrUrVrW)r�r�r�r�r�r�rmrmrn�register_certificate_alg�s

�r�cCs0trt�|�|rt�|�dtft|<dSdS)z*Register a new X.509 certificate algorithmN)r�rRr�rSrrU)r�r�rmrmrn�register_x509_certificate_alg�s

�r�cC�tS)z&Return supported public key algorithms)rNrmrmrmrn�get_public_key_algs�r!r�cCr�)z$Return default public key algorithms)rOrmrmrmrn�get_default_public_key_algs�r!r�cCr�)z8Return supported certificate-based public key algorithms)rPrmrmrmrn�get_certificate_algs�r!r�cCr�)z6Return default certificate-based public key algorithms)rQrmrmrmrn�get_default_certificate_algs�r!r�cCr�)z>Return supported X.509 certificate-based public key algorithms)rRrmrmrmrn�get_x509_certificate_algs�r!r�cCr�)z<Return default X.509 certificate-based public key algorithms)rSrmrmrmrn�!get_default_x509_certificate_algs�r!r�cCsvz.t|�}|��}t�|�}|r$|�|�}|��|�|�}||_|WStd|j	ddd���t
y:td�d�w)z"Decode a packetized SSH public keyzUnknown key algorithm: r�r�r��Invalid public keyN)r6r&rTr�r�r�r�r�r�r�r5)rqr�rwrfr�r�rmrmrnr/�s 


�
�r/c	Csjz&t|�}|��}t�|d�\}}|r|�||||�WStd|jddd���ttfy4td�d�w)z#Decode a packetized SSH certificaterAzUnknown certificate algorithm: r�r�r�zInvalid OpenSSH certificateN)	r6r&rUr�r�r�r�r5rk)rqr�r�rwr�r�rmrmrnr��s�
�r��alg_namec
Kst|�d�}t�|�}|r-z|j|fi|��}Wnttfy,}ztt|��d�d}~wwtd|��|�|�|S)a�Generate a new private key

       This function generates a new private key of a type matching
       the requested SSH algorithm. Depending on the algorithm, additional
       parameters can be passed which affect the generated key.

       Available algorithms include:

           ssh-dss, ssh-rsa, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384,
           ecdsa-sha2-nistp521, ecdsa-sha2-1.3.132.0.10, ssh-ed25519,
           ssh-ed448, sk-ecdsa-sha2-nistp256\@openssh.com,
           sk-ssh-ed25519\@openssh.com

       For dss keys, no parameters are supported. The key size is fixed at
       1024 bits due to the use of SHA1 signatures.

       For rsa keys, the key size can be specified using the `key_size`
       parameter, and the RSA public exponent can be changed using the
       `exponent` parameter. By default, generated keys are 2048 bits
       with a public exponent of 65537.

       For ecdsa keys, the curve to use is part of the SSH algorithm name
       and that determines the key size. No other parameters are supported.

       For ed25519 and ed448 keys, no parameters are supported. The key size
       is fixed by the algorithms at 256 bits and 448 bits, respectively.

       For sk keys, the application name to associate with the generated
       key can be specified using the `application` parameter. It defaults
       to `'ssh:'`. The user name to associate with the generated key can
       be specified using the `user` parameter. It defaults to `'AsyncSSH'`.

       When generating an sk key, a PIN can be provided via the `pin`
       parameter if the security key requires it.

       The `resident` parameter can be set to `True` to request that a
       resident key be created on the security key. This allows the key
       handle and public key information to later be retrieved so that
       the generated key can be used without having to store any
       information on the client system. It defaults to `False`.

       You can enable or disable the security key touch requirement by
       setting the `touch_required` parameter. It defaults to `True`,
       requiring that the user confirm their presence by touching the
       security key each time they use it to authenticate.

       :param alg_name:
           The SSH algorithm name corresponding to the desired type of key.
       :param comment: (optional)
           A comment to associate with this key.
       :param key_size: (optional)
           The key size in bits for RSA keys.
       :param exponent: (optional)
           The public exponent for RSA keys.
       :param application: (optional)
           The application name to associate with the generated SK key,
           defaulting to `'ssh:'`.
       :param user: (optional)
           The user name to associate with the generated SK key, defaulting
           to `'AsyncSSH'`.
       :param pin: (optional)
           The PIN to use to access the security key, defaulting to `None`.
       :param resident: (optional)
           Whether or not to create a resident key on the security key,
           defaulting to `False`.
       :param touch_required: (optional)
           Whether or not to require the user to touch the security key
           when authenticating with it, defaulting to `True`.
       :type alg_name: `str`
       :type comment: `str`, `bytes`, or `None`
       :type key_size: `int`
       :type exponent: `int`
       :type application: `str`
       :type user: `str`
       :type pin: `str`
       :type resident: `bool`
       :type touch_required: `bool`

       :returns: An :class:`SSHKey` private key

       :raises: :exc:`KeyGenerationError` if the requested key parameters
                are unsupported
    r�NzUnknown algorithm: )	r�rTr�r��	TypeErrorrkr�rer)r�r�r�r�rfr�rrmrmrn�generate_private_key�s
V
��
r�cCsRt|t�rz|�d�}Wntytd�d�wt|||�\}}|r%|Std��)aBImport a private key

       This function imports a private key encoded in PKCS#1 or PKCS#8 DER
       or PEM format or OpenSSH format. Encrypted private keys can be
       imported by specifying the passphrase needed to decrypt them.

       :param data:
           The data to import.
       :param passphrase: (optional)
           The passphrase to use to decrypt the key.
       :param unsafe_skip_rsa_key_validation: (optional)
           Whether or not to skip key validation when loading RSA private
           keys, defaulting to performing these checks unless changed by
           calling :func:`set_default_skip_rsa_key_validation`.
       :type data: `bytes` or ASCII `str`
       :type passphrase: `str` or `bytes`
       :type unsafe_skip_rsa_key_validation: bool

       :returns: An :class:`SSHKey` private key

    r��Invalid encoding for keyN�Invalid private key)rarer�ror�r�)rqrUrbr�r�rmrmrn�import_private_key_s

�r�cCs0t|||�\}}|r|t||d��fStd��)z3Import a private key and optional certificate chainNr�)r��import_certificate_chainr�)rqrUrbr�rKrmrmrn�import_private_key_and_certs�s�r�cC�Nt|t�rz|�d�}Wntytd�d�wt|�\}}|r#|Std��)aImport a public key

       This function imports a public key encoded in OpenSSH, RFC4716, or
       PKCS#1 or PKCS#8 DER or PEM format.

       :param data:
           The data to import.
       :type data: `bytes` or ASCII `str`

       :returns: An :class:`SSHKey` public key

    r�r�Nr�)rarer�ror�r�)rqr�r�rmrmrnr��

�rcCr�)a
Import a certificate

       This function imports an SSH certificate in DER, PEM, OpenSSH, or
       RFC4716 format.

       :param data:
           The data to import.
       :type data: `bytes` or ASCII `str`

       :returns: An :class:`SSHCertificate` object

    r�r�NzInvalid certificate)rarer�ror�r�)rqrr�rmrmrnr(�r�r(cCs"t|�}|r
t�|�}|Sd}|S)z!Import an X.509 certificate chainN)r�rr,)rqr�chainrmrmrnr��s
�r�cCsbz|���dd�\}}Wntytd�d�w|�d�r-t�|�}|r-||��d�Std��)z(Import an X.509 certificate subject nameNrz%Missing certificate subject algorithmzx509v3-zInvalid certificate subject)r�r�rkr�r%�_subject_patternrlrK)rqr�rlrmrmrn�import_certificate_subject�s
�

r�rcCstt|�||�}|�|�|S)a=Read a private key from a file

       This function reads a private key from a file. See the function
       :func:`import_private_key` for information about the formats
       supported.

       :param filename:
           The file to read the key from.
       :param passphrase: (optional)
           The passphrase to use to decrypt the key.
       :param unsafe_skip_rsa_key_validation: (optional)
           Whether or not to skip key validation when loading RSA private
           keys, defaulting to performing these checks unless changed by
           calling :func:`set_default_skip_rsa_key_validation`.
       :type filename: :class:`PurePath <pathlib.PurePath>` or `str`
       :type passphrase: `str` or `bytes`
       :type unsafe_skip_rsa_key_validation: bool

       :returns: An :class:`SSHKey` private key

    )r�r.r
)rrUrbr�rmrmrn�read_private_key�s

�
r�cCs&tt|�||�\}}|�|�||fS)z=Read a private key and optional certificate chain from a file)r�r.r
)rrUrbr�rrmrmrn�read_private_key_and_certs
s

�
r�cCstt|��}|�|�|S)awRead a public key from a file

       This function reads a public key from a file. See the function
       :func:`import_public_key` for information about the formats
       supported.

       :param filename:
           The file to read the key from.
       :type filename: :class:`PurePath <pathlib.PurePath>` or `str`

       :returns: An :class:`SSHKey` public key

    )rr.r
)rr�rmrmrn�read_public_key
s
r�cC�tt|��S)a�Read a certificate from a file

       This function reads an SSH certificate from a file. See the
       function :func:`import_certificate` for information about the
       formats supported.

       :param filename:
           The file to read the certificate from.
       :type filename: :class:`PurePath <pathlib.PurePath>` or `str`

       :returns: An :class:`SSHCertificate` object

    )r(r.�rrmrmrnr2
�rcCs(tt|�||�}|D]}|�|�q
|S)a�Read a list of private keys from a file

       This function reads a list of private keys from a file. See the
       function :func:`import_private_key` for information about the
       formats supported. If any of the keys are encrypted, they must
       all be encrypted with the same passphrase.

       :param filename:
           The file to read the keys from.
       :param passphrase: (optional)
           The passphrase to use to decrypt the keys.
       :param unsafe_skip_rsa_key_validation: (optional)
           Whether or not to skip key validation when loading RSA private
           keys, defaulting to performing these checks unless changed by
           calling :func:`set_default_skip_rsa_key_validation`.
       :type filename: :class:`PurePath <pathlib.PurePath>` or `str`
       :type passphrase: `str` or `bytes`
       :type unsafe_skip_rsa_key_validation: bool

       :returns: A list of :class:`SSHKey` private keys

    )r�r.r
)rrUrbr�r�rmrmrn�read_private_key_listD
s
�r�cCs$tt|��}|D]}|�|�q|S)a�Read a list of public keys from a file

       This function reads a list of public keys from a file. See the
       function :func:`import_public_key` for information about the
       formats supported.

       :param filename:
           The file to read the keys from.
       :type filename: :class:`PurePath <pathlib.PurePath>` or `str`

       :returns: A list of :class:`SSHKey` public keys

    )r�r.r
)rr�r�rmrmrn�read_public_key_listh
sr�cCr�)a�Read a list of certificates from a file

       This function reads a list of SSH certificates from a file. See
       the function :func:`import_certificate` for information about
       the formats supported.

       :param filename:
           The file to read the certificates from.
       :type filename: :class:`PurePath <pathlib.PurePath>` or `str`

       :returns: A list of :class:`SSHCertificate` certificates

    )r�r.r�rmrmrn�read_certificate_list
r�r�rm�keylist�certlist�skip_public�ignore_encrypted�loopcCs�g}t|�}dd�|D�}t|ttf�rSz2t|�r |t|��}	n|}	|r1t�|	�r1t�|	|��	�}	t
||	|�}
t|
�dkrC|g}|	}n|
}Wn"tyR|g}Ynwt|t
tttf�rctt|�g}n|rg|ng}|D�]�}d}
d}d}d}d}d}t|tttf�r�d}
n	t|t
�r�|\}}z\t|ttf�r�t|�}t|�r�||�}	n|}	|r�t�|	�r�t�|	|��	�}	|
r�t||	|�\}}|s�|d}nt||	|�}|d}nt|t�r�|
r�t|||�\}}n	t|||�}n|}Wn"t�y}z|�s|�rt|��d	��rWYd}~qk�d}~ww|�r:zt|�}Wntttf�y0}z
|}d}WYd}~nd}~ww|�s9tt|�}n|�rRzt|�}Wnttf�yQd}Ynwd}|�r�zt|ttf��ret|�}n
t|t��rpt|�}n|}Wnttf�y�d}Ynwd}nd}|�r�|�|�s�t|t��r�|j}n|j}|�|�}|�r�|j �r�t!�"|�}nt|�dk�r�|d
j �s�|d
}nt!�"|�}t|t��r�|�r�|�#|�|�$|�qk|�r�|�$t%|||��|�$t%||��qk|S)a�Load SSH private keys and optional matching certificates

       This function loads a list of SSH keys and optional matching
       certificates.

       When certificates are specified, the private key is added to
       the list both with and without the certificate.

       :param keylist:
           The list of private keys and certificates to load.
       :param passphrase: (optional)
           The passphrase to use to decrypt the keys, or a `callable` which
           takes a filename and returns the passphrase to decrypt it.
       :param certlist: (optional)
           A list of certificates to attempt to pair with the provided
           list of private keys.
       :param skip_public: (optional)
           An internal parameter used to skip public keys and certificates
           when IdentitiesOnly and IdentityFile are used to specify a
           mixture of private and public keys.
       :param unsafe_skip_rsa_key_validation: (optional)
           Whether or not to skip key validation when loading RSA private
           keys, defaulting to performing these checks unless changed by
           calling :func:`set_default_skip_rsa_key_validation`.
       :type keylist: *see* :ref:`SpecifyingPrivateKeys`
       :type passphrase: `str` or `bytes`
       :type certlist: *see* :ref:`SpecifyingCertificates`
       :type skip_public: `bool`
       :type unsafe_skip_rsa_key_validation: bool

       :returns: A list of :class:`SSHKeyPair` objects

    cSsi|]}|jj|�qSrm)r�r�)rwrrmrmrn�
<dictcomp>�
sz!load_keypairs.<locals>.<dictcomp>rFNT�	-cert.pub�.pub�
Passphraser)&�load_certificatesrar	re�callable�inspect�isawaitable�asyncio�run_coroutine_threadsafer0r�rr�rmr�r>rAr�_KeyPairArgr�r�r�r�r%r�r
�_KeyArgr�rr2r�r�r�rr,r:r�r=)r�rUr�r�r�rbr�r0�certdict�resolved_passphrase�	priv_keys�keys_to_load�key_to_load�allow_certs�
key_prefix�	saved_exc�pubkey_or_certs�pubkey_to_load�
certs_to_loadr�rrr?�pubdatarrmrmrn�
load_keypairs�
s*����
�


�����


�������	��
��

��

�


r�c	CsXg}tD]%\}}|r)ztdd|���}|�t|||dd��Wqty(Yqwq|S)z<Return a list of default keys from the user's home directory�~�.sshT)r�)�_DEFAULT_KEY_FILESr�
expanduserr�r�r
)rUr�r0�file�	conditionrrmrmrn�load_default_keypairsVs���r�cCs\t|ttf�rt|�Sg}|D]}t|ttf�rt|�}n	t|t�r&t|�}|�|�q|S)z�Load public keys

       This function loads a list of SSH public keys.

       :param keylist:
           The list of public keys to load.
       :type keylist: *see* :ref:`SpecifyingPublicKeys`

       :returns: A list of :class:`SSHKey` objects

    )rar	rer�r�r�rr�)r�r0r�rmrmrn�load_public_keysis


r�cCs�g}tD]#}tD]}ztt||d��}Wnttfy Yqw|�|�qqtD]#}tD]}ztt||d��}WnttfyFYq.w|�|�q.q*|S)z9Return a list of default host public keys or certificatesr�r�)�_DEFAULT_HOST_KEY_DIRS�_DEFAULT_HOST_KEY_FILESrrr
r�r�r�)r0�host_key_dirr�rr�rmrmrn�load_default_host_public_keys�s(����r�cCs�t|t�r|gSt|tttf�r|g}g}|D](}t|ttf�r%t|�}nt|t�r/t|�}nt|t�r8|g}n|}|�|�q|S)aLoad certificates

       This function loads a list of OpenSSH or X.509 certificates.

       :param certlist:
           The list of certificates to load.
       :type certlist: *see* :ref:`SpecifyingCertificates`

       :returns: A list of :class:`SSHCertificate` objects

    )rar?r	rer�r�r�r�)r�r0rrrmrmrnr��s





r��skip_privatecCs�t|tttttf�r|g}n|}g}|D]A}t|ttf�rCzt|�j}Wn+tyBzt	|�j}Wn
ty?|r>YYq�wYnwt|ttf�rN|j}n|}|�
|�q|S)z*Load public key and certificate identities)rar�rer	r>r?rr�r�r�r�)r�r��
identitiesr0�identityr�rmrmrn�load_identities�s.���r�c
Cs�g}tD]B\}}|rFzttdd|d��}Wnttfy!Ynw|�|j�zttdd|d��}Wnttfy?Yqw|�|j�q|S)z>Return a list of default public key and certificate identitiesr�r�r�r�)r�rrr
r�r�r�r�)r0r�r�rr�rmrmrn�load_default_identities�s"���r�zssh:)�application�userr�pinr�r�rc
Cs�|rtnd}d}zt|||�}Wnty#}ztt|��d�d}~wwg}|D]$\}	}
}}t|	\}
}||||||f7}|
�|�}|�|
�|�|�q(|S)a�Load keys resident on attached FIDO2 security keys

       This function loads keys resident on any FIDO2 security keys
       currently attached to the system. The user name associated
       with each key is returned in the key's comment field.

       :param pin:
           The PIN to use to access the security keys, defaulting to `None`.
       :param application: (optional)
           The application name associated with the keys to load,
           defaulting to `'ssh:'`.
       :param user: (optional)
           The user name associated with the keys to load. By default,
           keys for all users are loaded.
       :param touch_required: (optional)
           Whether or not to require the user to touch the security key
           when authenticating with it, defaulting to `True`.
       :type application: `str`
       :type user: `str`
       :type pin: `str`
       :type touch_required: `bool`

    rr�N)	r<r=rkr�rerZr�rr�)r�r�r�r�flags�reserved�
resident_keysrr0r�r��public_value�
key_handlerfr�r�rmrmrn�load_resident_keys�s ��

r�)rp)FrurA)NrmFFNN)Nrm)�r�r�r{r�rmrVrfr�hashlibrrrrr�pathlibrr	�typingr
rrr
rrrrrrr�typing_extensionsr�cryptorr�
encryptionr�skrrrrr��ImportErrorrr�hasattrrp�asn1rr r!r"r#r$r%r&r'r(�miscr)r*r+r,r-r.r/r0r�r1r2r3r4r5r6�pber7r8r9r:r;r<r=r�rer�rbrcr�r��
_PubKeyAlgMap�_CertAlgMap�_CertSigAlgMap�_CertVersionMap�_PEMMap�_PKCS8OIDMapr��	_SKAlgMapr�r�r�r�r��_IdentityArg�IdentityListArgr��
KeyListArg�_CertArg�CertListArgr��KeyPairListArgr�r�r�rrNr�rOrPrQrRrSrTrUrVrWrXrYrZrWrgrj�
IGNORECASEr�rErHrlrurqrvror�rkr�r�r�r�r�r>r?r@r�r�rrAr=rErMrPrZr�rargrirorqr|r}r~rr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r/r�r�r�r�rr(r�r�r�r�r�rr�r�r��AbstractEventLoopr�r�r�r�r�r�r�r�rmrmrmrn�<module>s�$��
�� ���

�	
bCs@hV; 1"%�

�

�-���
���
� ���
�d���
� ��
��
����
�8���
�"&
����
�	��
�
�
����
���
�
�e����
�(����
�����
�"����
�����
�$��������
�F��
�$��
�!����