o
    Œõ±jµE  ã                   @   s$  d dl mZmZmZmZ d dlZd dlmZ ddlmZm	Z	m
Z
 ddlmZ ddlmZmZmZ g d¢Zd	d
„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Z d'd(„ Z!d)d*„ Z"d+d,„ Z#d-d.„ Z$d/d0„ Z%d1d2„ Z&d3d4„ Z'd5d6„ Z(dS )7é    )Úunicode_literalsÚdivisionÚabsolute_importÚprint_functionN)Údatetimeé   )ÚCertificateÚint_from_bytesÚtimezone)ÚCIPHER_SUITE_MAP)ÚTLSVerificationErrorÚTLSDisconnectErrorÚTLSError)Údetect_client_auth_requestÚextract_chainÚget_dh_params_lengthÚparse_alertÚparse_handshake_messagesÚparse_session_infoÚparse_tls_recordsÚraise_client_authÚraise_dh_paramsÚraise_disconnectionÚraise_expired_not_yet_validÚraise_handshakeÚraise_hostnameÚraise_no_issuerÚraise_protocol_errorÚraise_revokedÚraise_self_signedÚraise_verificationÚraise_weak_signaturec                 C   s¸   g }d}t | ƒD ]\}}}|dkrqt|ƒD ]\}}|dkr"|} nq|r' nq|rZd}|t|ƒk rZt|||d … ƒ}	|d }
|
|	 }|}||
|… }| t |¡¡ |t|ƒk s2|S )a  
    Extracts the X.509 certificates from the server handshake bytes for use
    when debugging

    :param server_handshake_bytes:
        A byte string of the handshake data received from the server

    :return:
        A list of asn1crypto.x509.Certificate objects
    Nó   ó   é   )r   r   Úlenr	   Úappendr   Úload)Úserver_handshake_bytesÚoutputÚchain_bytesÚrecord_typeÚ_Úrecord_dataÚmessage_typeÚmessage_dataÚpointerÚcert_lengthÚ
cert_startÚcert_endÚ
cert_bytes© r5   ú€/root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/oscrypto/_tls.pyr   #   s0   þÿúr   c                 C   sD   t | ƒD ]\}}}|dkrqt|ƒD ]\}}|dkr  dS qqdS )a)  
    Determines if a CertificateRequest message is sent from the server asking
    the client for a certificate

    :param server_handshake_bytes:
        A byte string of the handshake data received from the server

    :return:
        A boolean - if a client certificate request was found
    r"   ó   TF)r   r   )r(   r+   r,   r-   r.   r/   r5   r5   r6   r   K   s   ÿÿr   c                 C   sl   d}d}t | ƒD ]\}}}|dkrqt|ƒD ]\}}|dkr"|} nq|r' nq|r4t|dd… ƒd }|S )a  
    Determines the length of the DH params from the ServerKeyExchange

    :param server_handshake_bytes:
        A byte string of the handshake data received from the server

    :return:
        None or an integer of the bit size of the DH parameters
    Nr"   ó   r   é   é   )r   r   r	   )r(   r)   Údh_params_bytesr+   r,   r-   r.   r/   r5   r5   r6   r   `   s    þÿr   c                 C   sV   t | ƒD ]$\}}}|dkrqt|ƒdkr dS t|dd… ƒt|dd… ƒf  S dS )aV  
    Parses the handshake for protocol alerts

    :param server_handshake_bytes:
        A byte string of the handshake data received from the server

    :return:
        None or an 2-element tuple of integers:
         0: 1 (warning) or 2 (fatal)
         1: The alert description (see https://tools.ietf.org/html/rfc5246#section-7.2)
    ó   r9   Nr   r   )r   r%   r	   )r(   r+   r,   r-   r5   r5   r6   r      s   $r   c                 C   s2  d}d}d}d}d}d}d}t | ƒD ]s\}	}
}|	dkrqt|ƒD ]d\}}|dkr)q ddddd	d
œ|dd…  }t|dd… ƒ}|dkrK|dd| … }d| }|||d … }t| }|d }|||d … dk}|d }||d… }t|ƒD ]\}}|dkrƒd} nqw qt |ƒD ]o\}	}
}|	dkr”qŠt|ƒD ]`\}}|dkr¡q˜t|dd… ƒ}|dkrµ|dd| … }d| }t|||d … ƒ}|d | }t|||d … ƒ}|du rø|du rø|d | }||d… }t|ƒD ]\}}|dkr÷d} nqë qŠ|du�r|du �rd}n
||k�rd}nd}|||||dœS )a´  
    Parse the TLS handshake from the client to the server to extract information
    including the cipher suite selected, if compression is enabled, the
    session id and if a new or reused session ticket exists.

    :param server_handshake_bytes:
        A byte string of the handshake data received from the server

    :param client_handshake_bytes:
        A byte string of the handshake data sent to the server

    :return:
        A dict with the following keys:
         - "protocol": unicode string
         - "cipher_suite": unicode string
         - "compression": boolean
         - "session_id": "new", "reused" or None
         - "session_ticket: "new", "reused" or None
    NFr"   ó   ÚSSLv3ÚTLSv1zTLSv1.1zTLSv1.2zTLSv1.3)s    s   s   s   s   r   r9   é"   é#   r   ó    Únewó   Úreused)ÚprotocolÚcipher_suiteÚcompressionÚ
session_idÚsession_ticket)r   r   r	   r   Ú_parse_hello_extensions)r(   Úclient_handshake_bytesrF   rG   rH   rI   rJ   Úserver_session_idÚclient_session_idr+   r,   r-   r.   r/   Úsession_id_lengthÚcipher_suite_startÚcipher_suite_bytesÚcompression_startÚextensions_length_startÚextensions_dataÚextension_typeÚextension_dataÚcipher_suite_lengthÚcompression_lengthr5   r5   r6   r   •   s’   û
úþ€þ€


ûr   c                 c   sž   � d}t | ƒ}||k rM| ||d … dkrdS t| |d |d … ƒ}| ||d … | |d |d … | |d |d | … fV  |d| 7 }||k sdS dS )aÜ  
    Creates a generator returning tuples of information about each record
    in a byte string of data from a TLS client or server. Stops as soon as it
    find a ChangeCipherSpec message since all data from then on is encrypted.

    :param data:
        A byte string of TLS records

    :return:
        A generator that yields 3-element tuples:
        [0] Byte string of record type
        [1] Byte string of protocol version
        [2] Byte string of record data
    r   r   ó   r$   é   N©r%   r	   ©Údatar0   Údata_lenÚlengthr5   r5   r6   r     s   €ýör   c                 c   st   � d}t | ƒ}||k r8t| |d |d … ƒ}| ||d … | |d |d | … fV  |d| 7 }||k sdS dS )a`  
    Creates a generator returning tuples of information about each message in
    a byte string of data from a TLS handshake record

    :param data:
        A byte string of a TLS handshake record data

    :return:
        A generator that yields 2-element tuples:
        [0] Byte string of message type
        [1] Byte string of message data
    r   r   é   Nr[   r\   r5   r5   r6   r   #  s   €þúr   c                 c   sœ   � | dkrdS t | dd… ƒ}d}d| }|}||k rLt | ||d … ƒ}t | |d |d … ƒ}|| |d |d | … fV  |d| 7 }||k sdS dS )a¹  
    Creates a generator returning tuples of information about each extension
    from a byte string of extension data contained in a ServerHello ores
    ClientHello message

    :param data:
        A byte string of a extension data from a TLS ServerHello or ClientHello
        message

    :return:
        A generator that yields 2-element tuples:
        [0] Byte string of extension type
        [1] Byte string of extension data
    ó    Nr   r9   r`   )r	   )r]   Úextentions_lengthÚextensions_startÚextensions_endr0   rU   Úextension_lengthr5   r5   r6   rK   <  s   €þùrK   c                 C   sŠ   t  d|¡p| d¡dk}|rd| }nd| }d| }d | j¡}d | j¡}|r0|d| 7 }|r8|r8|d	7 }|r@|d
| 7 }t|| ƒ‚)z´
    Raises a TLSVerificationError due to a hostname mismatch

    :param certificate:
        An asn1crypto.x509.Certificate object

    :raises:
        TLSVerificationError
    z^\d+\.\d+\.\d+\.\d+$ú:éÿÿÿÿzIP address %szdomain name %sz:Server certificate verification failed - %s does not matchz, z valid domains: %sz orz valid IP addresses: %s)ÚreÚmatchÚfindÚjoinÚ	valid_ipsÚvalid_domainsr   )ÚcertificateÚhostnameÚis_ipÚhostname_typeÚmessagerl   rm   r5   r5   r6   r   ^  s   

r   c                 C   ó   d}t || ƒ‚)z¡
    Raises a generic TLSVerificationError

    :param certificate:
        An asn1crypto.x509.Certificate object

    :raises:
        TLSVerificationError
    z&Server certificate verification failed©r   ©rn   rr   r5   r5   r6   r    z  ó   
r    c                 C   rs   )zÐ
    Raises a TLSVerificationError when a certificate uses a weak signature
    algorithm

    :param certificate:
        An asn1crypto.x509.Certificate object

    :raises:
        TLSVerificationError
    zMServer certificate verification failed - weak certificate signature algorithmrt   ru   r5   r5   r6   r!   ‰  ó   
r!   c                  C   s   d} t | ƒ‚)zg
    Raises a TLSError indicating client authentication is required

    :raises:
        TLSError
    z5TLS handshake failed - client authentication required©r   )rr   r5   r5   r6   r   ™  s   r   c                 C   rs   )z¾
    Raises a TLSVerificationError due to the certificate being revoked

    :param certificate:
        An asn1crypto.x509.Certificate object

    :raises:
        TLSVerificationError
    zEServer certificate verification failed - certificate has been revokedrt   ru   r5   r5   r6   r   ¥  rv   r   c                 C   rs   )zÏ
    Raises a TLSVerificationError due to no issuer certificate found in trust
    roots

    :param certificate:
        An asn1crypto.x509.Certificate object

    :raises:
        TLSVerificationError
    zgServer certificate verification failed - certificate issuer not found in trusted root certificate storert   ru   r5   r5   r6   r   ´  rw   r   c                 C   rs   )zÄ
    Raises a TLSVerificationError due to a self-signed certificate
    roots

    :param certificate:
        An asn1crypto.x509.Certificate object

    :raises:
        TLSVerificationError
    zCServer certificate verification failed - certificate is self-signedrt   ru   r5   r5   r6   r   Ä  rw   r   c                 C   rs   )zî
    Raises a TLSVerificationError due to a certificate lifetime exceeding
    the CAB forum certificate lifetime limit

    :param certificate:
        An asn1crypto.x509.Certificate object

    :raises:
        TLSVerificationError
    zIServer certificate verification failed - certificate lifetime is too longrt   ru   r5   r5   r6   Úraise_lifetime_too_longÔ  rw   ry   c                 C   sl   | d d }|d j }|d j }t tj¡}||kr$| d¡}d| }n||k r1| d¡}d| }t|| ƒ‚)zÖ
    Raises a TLSVerificationError due to certificate being expired, or not yet
    being valid

    :param certificate:
        An asn1crypto.x509.Certificate object

    :raises:
        TLSVerificationError
    Útbs_certificateÚvalidityÚ	not_afterÚ
not_beforez%Y-%m-%d %H:%M:%SZzGServer certificate verification failed - certificate not valid until %sz?Server certificate verification failed - certificate expired %s)Únativer   Únowr
   ÚutcÚstrftimer   )rn   r{   r|   r}   r   Úformatted_beforerr   Úformatted_afterr5   r5   r6   r   ä  s   





r   c                   C   ó   t dƒ‚)ze
    Raises a TLSDisconnectError due to a disconnection

    :raises:
        TLSDisconnectError
    z$The remote end closed the connection)r   r5   r5   r5   r6   r      ó   r   c                 C   s    t | ƒ}|rtd| ƒ‚tdƒ‚)z»
    Raises a TLSError due to a protocol error

    :param server_handshake_bytes:
        A byte string of the handshake data received from the server

    :raises:
        TLSError
    z.TLS protocol error - server responded using %sz@TLS protocol error - server responded using a different protocol)Údetect_other_protocolr   )r(   Úother_protocolr5   r5   r6   r     s   r   c                   C   r„   )zS
    Raises a TLSError due to a handshake error

    :raises:
        TLSError
    zTLS handshake failedrx   r5   r5   r5   r6   r     r…   r   c                   C   r„   )z_
    Raises a TLSError due to a TLS version incompatibility

    :raises:
        TLSError
    z-TLS handshake failed - protocol version errorrx   r5   r5   r5   r6   Úraise_protocol_version)  r…   rˆ   c                   C   r„   )zP
    Raises a TLSError due to weak DH params

    :raises:
        TLSError
    z)TLS handshake failed - weak DH parametersrx   r5   r5   r5   r6   r   4  r…   r   c                 C   sŒ   | dd… dkr
dS | dd… dkrt  d| t j¡rdS d	S | dd… d
kr(dS | dd… dkr2dS | dd… dksB| dd… dkrDdS dS )a  
    Looks at the server handshake bytes to try and detect a different protocol

    :param server_handshake_bytes:
        A byte string of the handshake data received from the server

    :return:
        None, or a unicode string of "ftp", "http", "imap", "pop3", "smtp"
    r   rZ   s   HTTP/ÚHTTPr`   s   220 s
   ^[^
]*ftpÚFTPÚSMTPs   220-s   +OK ÚPOP3s   * OKé	   s	   * PREAUTHÚIMAPN)rh   ri   ÚI)r(   r5   r5   r6   r†   ?  s    r†   ))Ú
__future__r   r   r   r   rh   r   Ú_asn1r   r	   r
   Ú_cipher_suitesr   Úerrorsr   r   r   Ú__all__r   r   r   r   r   r   r   rK   r   r    r!   r   r   r   r   ry   r   r   r   r   rˆ   r   r†   r5   r5   r5   r6   Ú<module>   s<   (o"