o
    -׾gE                     @   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   W/var/www/html/backend_erp/backend_erp_env/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rd} nqw qt |D ]o\}	}
}|	dkrqt|D ]`\}}|dkrqt|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rd} 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"