o
    Œõ±j¢æ  ã                   @   s  d dl mZmZmZmZ d dlZd dlZd dlZd dl	Z	d dl
Z
ddlmZ ddlmZ ddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZ ddlm Z m!Z!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,m-Z- ddl.m/Z/m0Z0m1Z1m2Z2 ddl3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZF ddlGmHZHmZ ddlImJZJ ejKdk rÁeLZMejNZOnePZOejKdk rÌejQZRnejRZRddgZSe Td¡ZUe V¡ ZWeWd  eWd fZXG dd„ de0ƒZYG dd„ de/ƒZZG dd„ de[ƒZ\G dd„ de[ƒZ]dS )é    )Úunicode_literalsÚdivisionÚabsolute_importÚprint_functionNé   )ÚCertificate)Úpretty_message)Úbuffer_from_bytesÚbuffer_from_unicodeÚbytes_from_bufferÚcastÚderefÚis_nullÚnativeÚnewÚnullÚrefÚsizeofÚstructÚunwrapÚwrite_to_bufferé   )Úsecur32ÚSecur32ConstÚhandle_error)Úcrypt32ÚCrypt32Constr   )Úkernel32)Ú	type_nameÚstr_clsÚbyte_clsÚ	int_types)ÚTLSErrorÚTLSVerificationErrorÚTLSDisconnectErrorÚTLSGracefulDisconnectError)Údetect_client_auth_requestÚdetect_other_protocolÚextract_chainÚget_dh_params_lengthÚparse_alertÚparse_session_infoÚraise_client_authÚraise_dh_paramsÚraise_disconnectionÚraise_expired_not_yet_validÚraise_handshakeÚraise_hostnameÚraise_no_issuerÚraise_protocol_errorÚraise_protocol_versionÚraise_revokedÚraise_self_signedÚraise_verificationÚraise_weak_signature)Úload_certificater   )Úparse_certificate)é   )r;   é   Ú
TLSSessionÚ	TLSSockets   (
||
)c                   @   s   e Zd ZdS )Ú_TLSDowngradeErrorN)Ú__name__Ú
__module__Ú__qualname__© rC   rC   ú„/root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/oscrypto/_win/tls.pyr?   Q   s    r?   c                   @   s   e Zd ZdZdS )Ú_TLSRetryErrorzè
    TLSv1.2 on Windows 7 and 8 seems to have isuses with some DHE_RSA
    ServerKeyExchange messages due to variable length integer encoding. This
    exception is used to trigger a reconnection to attempt the handshake again.
    N)r@   rA   rB   Ú__doc__rC   rC   rC   rD   rE   V   s    rE   c                   @   s>   e Zd ZdZdZdZdZdZdZd
dd„Z	dd„ Z
dd	„ ZdS )r=   zj
    A TLS session object that multiple TLSSocket objects can share for the
    sake of session reuse
    NFc              	   C   sD  t |tƒsttdt|ƒƒƒ‚|| _|du rtg d¢ƒ}t |tƒr&t|gƒ}nt |tƒs4ttdt|ƒƒƒ‚|tg d¢ƒ }|rGttdt	|ƒƒƒ‚|| _
g | _|rœ|D ]J}t |tƒr\|j}n9t |tƒrft|ƒ}n/t |tƒr‡t|dƒ�}t| ¡ ƒ}W d  ƒ n1 s�w   Y  nt |tƒs•ttdt|ƒƒƒ‚| j |¡ qQ|  ¡  dS )	a]  
        :param protocol:
            A unicode string or set of unicode strings representing allowable
            protocols to negotiate with the server:

             - "TLSv1.2"
             - "TLSv1.1"
             - "TLSv1"
             - "SSLv3"

            Default is: {"TLSv1", "TLSv1.1", "TLSv1.2"}

        :param manual_validation:
            If certificate and certificate path validation should be skipped
            and left to the developer to implement

        :param extra_trust_roots:
            A list containing one or more certificates to be treated as trust
            roots, in one of the following formats:
             - A byte string of the DER encoded certificate
             - A unicode string of the certificate filename
             - An asn1crypto.x509.Certificate object
             - An oscrypto.asymmetric.Certificate object

        :raises:
            ValueError - when any of the parameters contain an invalid value
            TypeError - when any of the parameters are of the wrong type
            OSError - when an error is returned by the OS crypto library
        zM
                manual_validation must be a boolean, not %s
                N)ÚTLSv1úTLSv1.1úTLSv1.2zu
                protocol must be a unicode string or set of unicode strings,
                not %s
                ©ÚSSLv3rG   rH   rI   z�
                protocol must contain only the unicode strings "SSLv3", "TLSv1",
                "TLSv1.1", "TLSv1.2", not %s
                Úrbzû
                        extra_trust_roots must be a list of byte strings, unicode
                        strings, asn1crypto.x509.Certificate objects or
                        oscrypto.asymmetric.Certificate objects, not %s
                        )Ú
isinstanceÚboolÚ	TypeErrorr   r   Ú_manual_validationÚsetr   Ú
ValueErrorÚreprÚ
_protocolsÚ_extra_trust_rootsr   Úasn1r    r:   ÚopenÚreadÚAsn1CertificateÚappendÚ_obtain_credentials)ÚselfÚprotocolÚmanual_validationÚextra_trust_rootsÚunsupported_protocolsÚextra_trust_rootÚfrC   rC   rD   Ú__init__m   sR   
ü

ûû



ÿ€
úzTLSSession.__init__c                 C   sš  t jt jt jt jdœ}d}| ¡ D ]\}}|| jv r||O }qt jt jt j	t j
t jt jt jt jt jt jg
}d| jv rE| t jt jt jg¡ ttdt|ƒ ƒ}t|ƒD ]\}}|||< qRt jt jB }	| jsm| jsm|	t jO }	n|	t jO }	ttdƒ}
t |
ƒ}t j!|_"d|_#t$ƒ |_%t$ƒ |_&d|_'t$ƒ |_(t|ƒ|_)||_*||_+d|_,d|_-d|_.|	|_/d|_0ttdƒ}t 1t$ƒ t j2t j3t$ƒ |
t$ƒ t$ƒ |t$ƒ ¡	}t4|ƒ || _5dS )zU
        Obtains a credentials handle from secur32.dll for use with SChannel
        rJ   r   rI   z
ALG_ID[%s]ÚSCHANNEL_CREDzCredHandle *N)6r   ÚSP_PROT_SSL3_CLIENTÚSP_PROT_TLS1_CLIENTÚSP_PROT_TLS1_1_CLIENTÚSP_PROT_TLS1_2_CLIENTÚitemsrT   ÚCALG_AES_128ÚCALG_AES_256Ú	CALG_3DESÚ	CALG_SHA1Ú
CALG_ECDHEÚCALG_DH_EPHEMÚCALG_RSA_KEYXÚCALG_RSA_SIGNÚ
CALG_ECDSAÚCALG_DSS_SIGNÚextendÚCALG_SHA512ÚCALG_SHA384ÚCALG_SHA256r   r   ÚlenÚ	enumerateÚSCH_USE_STRONG_CRYPTOÚSCH_CRED_NO_DEFAULT_CREDSrP   rU   ÚSCH_CRED_AUTO_CRED_VALIDATIONÚSCH_CRED_MANUAL_CRED_VALIDATIONr   r   ÚSCHANNEL_CRED_VERSIONÚ	dwVersionÚcCredsr   ÚpaCredÚ
hRootStoreÚcMappersÚ
aphMappersÚcSupportedAlgsÚpalgSupportedAlgsÚgrbitEnabledProtocolsÚdwMinimumCipherStrengthÚdwMaximumCipherStrengthÚdwSessionLifespanÚdwFlagsÚdwCredFormatÚAcquireCredentialsHandleWÚ
UNISP_NAMEÚSECPKG_CRED_OUTBOUNDr   Ú_credentials_handle)r\   Úprotocol_valuesÚprotocol_bit_maskÚkeyÚvalueÚalgsÚ	alg_arrayÚindexÚalgÚflagsÚschannel_cred_pointerÚschannel_credÚcred_handle_pointerÚresultrC   rC   rD   r[   Ç   s€   ü
€ö
ý




÷
zTLSSession._obtain_credentialsc                 C   s(   | j rt | j ¡}t|ƒ d | _ d S d S ©N)r�   r   ÚFreeCredentialsHandler   )r\   r�   rC   rC   rD   Ú__del__  s
   
ýzTLSSession.__del__)NFN)r@   rA   rB   rF   rT   Ú_ciphersrP   rU   r�   rc   r[   r    rC   rC   rC   rD   r=   a   s    
ZQc                   @   sŠ  e Zd ZdZdZdZdZdZdZdZ	dZ
dZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZed=dd„ƒZd>dd„Zd	d
„ Zdd„ Z d?dd„Z!dd„ Z"d=dd„Z#dd„ Z$dd„ Z%dd„ Z&dd„ Z'd=dd„Z(dd„ Z)dd „ Z*d!d"„ Z+d#d$„ Z,e-d%d&„ ƒZ.e-d'd(„ ƒZ/e-d)d*„ ƒZ0e-d+d,„ ƒZ1e-d-d.„ ƒZ2e-d/d0„ ƒZ3e-d1d2„ ƒZ4e-d3d4„ ƒZ5e-d5d6„ ƒZ6e-d7d8„ ƒZ7e-d9d:„ ƒZ8d;d<„ Z9dS )@r>   z8
    A wrapper around a socket.socket that adds TLS
    NFc              
   C   sÖ   t |tjƒsttdt|ƒƒƒ‚t |tƒsttdt|ƒƒƒ‚|dur/t |tƒs/ttdt|ƒƒƒ‚| dd|d�}||_||_	z| 
¡  W |S  tyX } z	t|j|jƒ}|‚d}~w tyj } zt|jƒ}|‚d}~ww )az  
        Takes an existing socket and adds TLS

        :param socket:
            A socket.socket object to wrap with TLS

        :param hostname:
            A unicode string of the hostname or IP the socket is connected to

        :param session:
            An existing TLSSession object to allow for session reuse, specific
            protocol or manual certificate validation

        :raises:
            ValueError - when any of the parameters contain an invalid value
            TypeError - when any of the parameters are of the wrong type
            OSError - when an error is returned by the OS crypto library
        zU
                socket must be an instance of socket.socket, not %s
                zK
                hostname must be a unicode string, not %s
                Nú`
                session must be an instance of oscrypto.tls.TLSSession, not %s
                )Úsession)rM   Úsocket_ÚsocketrO   r   r   r   r=   Ú_socketÚ	_hostnameÚ
_handshaker?   r#   ÚmessageÚcertificaterE   r"   )Úclsr¥   Úhostnamer£   Ú
new_socketÚeÚnew_erC   rC   rD   ÚwrapE  s<   ü
üü
ù€
€þzTLSSocket.wrapé
   c                 C   s¢  d| _ d| _|du r|du rd| _n>t|tƒs ttdt|ƒƒƒ‚t|tƒs.ttdt|ƒƒƒ‚|durAt|t	j
ƒsAttdt|ƒƒƒ‚t ||f|¡| _| j |¡ |du rXtƒ }nt|tƒsfttdt|ƒƒƒ‚|| _| jrÏ|| _z|  ¡  W dS  ty¯   |  ¡  t|jtdgƒ |j|jƒ}| ¡  d| _ || _t ||f|¡| _| j |¡ |  ¡  Y dS  tyÎ   d| _ t ||f|¡| _| j |¡ |  ¡  Y dS w dS )a®  
        :param address:
            A unicode string of the domain name or IP address to connect to

        :param port:
            An integer of the port number to connect to

        :param timeout:
            An integer timeout to use for the socket

        :param session:
            An oscrypto.tls.TLSSession object to allow for session reuse and
            controlling the protocols and validation performed
        ó    NzR
                    address must be a unicode string, not %s
                    zI
                    port must be an integer, not %s
                    zJ
                    timeout must be a number, not %s
                    r¢   rI   )Ú_received_bytesÚ_decrypted_bytesr¦   rM   r   rO   r   r   r!   ÚnumbersÚNumberr¤   Úcreate_connectionÚ
settimeoutr=   Ú_sessionr§   r¨   r?   ÚcloserT   rQ   rP   rU   r    rE   )r\   ÚaddressÚportÚtimeoutr£   Únew_sessionrC   rC   rD   rc   „  sj   
ü
üü
üýüîzTLSSocket.__init__c                 C   sn   t td| ƒ}td|ƒD ]}d|| _tj|| _tƒ || _qt	tdƒ}t
|ƒ}tj|_||_||_||fS )zù
        Creates a SecBufferDesc struct and contained SecBuffer structs

        :param number:
            The number of contains SecBuffer objects to create

        :return:
            A tuple of (SecBufferDesc pointer, SecBuffer array)
        zSecBuffer[%d]r   ÚSecBufferDesc)r   r   ÚrangeÚcbBufferr   ÚSECBUFFER_EMPTYÚ
BufferTyper   ÚpvBufferr   r   ÚSECBUFFER_VERSIONÚ	ulVersionÚcBuffersÚpBuffers)r\   ÚnumberÚbuffersr—   Úsec_buffer_desc_pointerÚsec_buffer_descrC   rC   rD   Ú_create_buffersÛ  s   

zTLSSocket._create_buffersc           (   
   C   s6  d}d}�zt  tjtjtƒ dtƒ ¡}t|ƒrtdƒ tƒ }| j	j
D ]!}| ¡ }t  |tj|t|ƒtjtƒ ¡}|s=tdƒ | |j¡ q"tt dƒ}t | jtj|¡}t|ƒ t|ƒ}tt d|ƒ}ttdƒ}	t |	¡ tt d|	ƒ}
tt dƒ}tt dtjƒ|d< tt dtjƒ|d< tt dtjƒ|d	< tt d
ƒ}t|ƒ}d|_ tt d|ƒ|_!tt dƒ}t|ƒ}tj"|_#||_$tt dƒ}t|ƒ}||_%t&t |ƒ}||_'tt dƒ}t  (tƒ ||
||tj)tj*B tƒ |¡}t|ƒ tj+}t|ƒ}t|ƒ}t,t-|j.ƒ}|dk�r1t|j/ƒ}t|ƒ}t,t-|j0ƒ}|j1|d  }t|ƒ}t|j2ƒ}t3|j4t,t-|j5ƒƒ}t6 7|¡}|j|v �r1|tj8O }tt dƒ}t|ƒ} t&t | ƒ| _'tj9| _:d| _;tt dt<| j=ƒƒ| _>tt dƒ}!t|!ƒ}"t&t |"ƒ|"_'||"_?tt d|ƒ|"_@tt dƒ}#t|#ƒ}$t&t |$ƒ|$_'t  AtjB||!|#¡}t|ƒ t|ƒ}%t3|%j4t,t-|%j5ƒƒ}t6 7|¡}|$jC}&|&�rä|&tjDk�r©tE|ƒ |&tjFk�rÀtG|ƒ}'|'jH�r¼tI|ƒ ntJ|ƒ |&tjKk�rÌtL|| j=ƒ |&tjMk�rÖtN|ƒ |&tjOk�ràtP|ƒ tQ|ƒ |jRtddgƒv �ròtN|ƒ W |�rüt  S|d¡ |�rt  T|¡ dS dS |�rt  S|d¡ |�rt  T|¡ w w )z¤
        Manually invoked windows certificate chain builder and verification
        step when there are extra trust roots to include in the search process
        Nr   zPCERT_CONTEXT *ÚPCERT_CONTEXTz
FILETIME *z	char *[3]zchar *r   r   ÚCERT_ENHKEY_USAGEr;   zchar **ÚCERT_USAGE_MATCHÚCERT_CHAIN_PARAzPCERT_CHAIN_CONTEXT *Ú SSL_EXTRA_CERT_CHAIN_POLICY_PARAz	wchar_t *ÚCERT_CHAIN_POLICY_PARAzvoid *ÚCERT_CHAIN_POLICY_STATUSÚmd5Úmd2)Ur   ÚCertOpenStorer   ÚCERT_STORE_PROV_MEMORYÚX509_ASN_ENCODINGr   r   Úhandle_crypt32_errorrQ   r¹   rU   ÚdumpÚ CertAddEncodedCertificateToStorerx   ÚCERT_STORE_ADD_USE_EXISTINGÚaddÚsha256r   r   ÚQueryContextAttributesWÚ_context_handle_pointerr   ÚSECPKG_ATTR_REMOTE_CERT_CONTEXTr   r   r   r   ÚGetSystemTimeAsFileTimeÚPKIX_KP_SERVER_AUTHÚSERVER_GATED_CRYPTOÚSGC_NETSCAPEr   ÚcUsageIdentifierÚrgpszUsageIdentifierÚUSAGE_MATCH_TYPE_ORÚdwTypeÚUsageÚRequestedUsager   ÚcbSizeÚCertGetCertificateChainÚCERT_CHAIN_CACHE_END_CERTÚ&CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLYÚ.CERT_CHAIN_POLICY_IGNORE_ALL_REV_UNKNOWN_FLAGSr   ÚintÚcChainÚrgpChainÚcElementÚ
rgpElementÚpCertContextr   ÚpbCertEncodedÚcbCertEncodedrY   ÚloadÚ'CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAGÚAUTHTYPE_SERVERÚ
dwAuthTypeÚ	fdwChecksr
   r§   ÚpwszServerNamer‹   ÚpvExtraPolicyParaÚ CertVerifyCertificateChainPolicyÚCERT_CHAIN_POLICY_SSLÚdwErrorÚCERT_E_EXPIREDr/   ÚCERT_E_UNTRUSTEDROOTr9   Úself_signedr6   r2   ÚCERT_E_CN_NO_MATCHr1   ÚTRUST_E_CERT_SIGNATUREr8   ÚCRYPT_E_REVOKEDr5   r7   Ú	hash_algoÚCertCloseStoreÚCertFreeCertificateChain)(r\   ÚstoreÚcert_chain_context_pointerÚcert_hashesÚcertÚ	cert_datar�   Úcert_context_pointer_pointerÚcert_context_pointerÚorig_now_pointerÚnow_pointerÚusage_identifiersÚcert_enhkey_usage_pointerÚcert_enhkey_usageÚcert_usage_match_pointerÚcert_usage_matchÚcert_chain_para_pointerÚcert_chain_paraÚcert_chain_para_sizeÚ"cert_chain_context_pointer_pointerÚcert_chain_policy_para_flagsÚcert_chain_contextÚ
num_chainsÚfirst_simple_chain_pointerÚfirst_simple_chainÚnum_elementsÚlast_element_pointerÚlast_elementÚlast_element_certÚlast_element_cert_dataÚ	last_certÚ(ssl_extra_cert_chain_policy_para_pointerÚ ssl_extra_cert_chain_policy_paraÚcert_chain_policy_para_pointerÚcert_chain_policy_paraÚ cert_chain_policy_status_pointerÚcert_chain_policy_statusÚcert_contextÚerrorÚoscrypto_certrC   rC   rD   Ú_extra_trust_root_validationö  s  ûú
ý








ø




þ


ý

ü

€ÿþÿz&TLSSocket._extra_trust_root_validationc           !      C   sF  d}d}d}�zî�z¬|r| j }nttdƒ}|}tjdtjdtjdtjdtjdtj	dtj
d	i}d
| _|D ]	}|  j|O  _q3|  d¡\}}tj|d
 _|  d¡\}	}tj|d
 _tj|d _ttdƒ}
|rj|}tƒ }ntƒ }|}t | jj|| j| jd
d
tƒ d
||	|
tƒ ¡}|ttjtjgƒvr”t|tƒ |s™|}n|}d}d}|d
 jd
krÎt|d
 j|d
 jƒ}||7 }| j |¡ d
|d
 _t |d
 j¡ tƒ |d
 _t dƒ}t!td|ƒ|d
 _d}|tjk�rþzd}| j "d¡}|dkrót#ƒ  W n t$yÿ   d}Y nw ||7 }|  j%|7  _%t&| j%ƒ|d
 _t'|| j%ƒ t | jj|| j| jd
d
|d
tƒ |	|
tƒ ¡}|tj(k�rltj|d
 _|d jtj)k�retj)|d _d
|d _t*|d jƒ�set |d j¡ tƒ |d _|�rkt#ƒ  qÝ|tj+k�rŒt,|ƒ�rzt-ƒ  t.|ƒ}|�r‰|dk�r‰t/ƒ  t0ƒ  |tj1k�ržt2|ƒ}t3|d
 | jƒ |tj4k�r®t2|ƒ}t5|d
 ƒ |tj6k�rÌt2|ƒ}|d
 }t7|ƒ}|j8�sÈt9|ƒ t:|ƒ |tj;k�rÜt<|ƒdk �rÜt=ƒ  |tj>k�råt-ƒ  |t?j@k�rïtA|ƒ |tjBk�rK|d jd
k�r7t|d j|d jƒ}||7 }|dd… }|dk�s|dk�r7d| jjCv �r7t&| jjCƒdk�r7t2|ƒ}tDd|d
 ƒ‚t,|ƒ�r?t-ƒ  tE|ƒ�rHtF|ƒ t0ƒ  |tjGk�sW|tjHk�rbd| jjCv �rbtIdƒ‚|�rht#ƒ  |tjJk�rxt<|ƒdk �rxt=ƒ  |ttjtjgƒv�rˆt|tƒ |d
 jd
k�r¸t|d
 j|d
 jƒ}||7 }| j |¡ d
|d
 _t |d
 j¡ tƒ |d
 _|d jtjKk�rö|d j}| j%| d… | _%tj)|d _d
|d _t |d j¡ tƒ |d _|tjk�rõ|| d… }nd| _%|tjksãtLtdƒ}t M|tjN|¡}t|tƒ tO|ƒ}tjPdtjQdtjRd tjSd!tjTdi UtVtW|jXƒtY|jXƒ¡| _Z| jZtg d"¢ƒv �rTt[||ƒ}|d# | _\|d$ | _]|d% | _^|d& | __t`|
ƒ}|D ]}||B d
k�rltatbd'|| ƒƒ‚�qZ|�s«|| _ d}tLtd(ƒ}t M| j tjc|¡}t|ƒ tO|ƒ} tVtW| jdƒ| _etVtW| jfƒ| _gtVtW| jhƒ| _i| je| jg | ji | _j| jjk�r´|  l¡  W n tatmjnf�yÅ   |  o¡  ‚ w W |�rêt*|d
 jƒ�sÚt |d
 j¡ t*|d jƒ�sêt |d j¡ |�rôt p|¡ dS dS |�rt*|d
 jƒ�s	t |d
 j¡ t*|d jƒ�st |d j¡ |�r"t p|¡ w w ))z—
        Perform an initial TLS handshake, or a renegotiation

        :param renegotiate:
            If the handshake is for a renegotiation
        NzCtxtHandle *zreplay detectionzsequence detectionÚconfidentialityzmemory allocationÚ	integrityzstream orientationzdisable automatic client authr   r   r   úULONG *r²   i €  úBYTE *Fé    T)r   éF   i   é   r<   ó   (ó   +rI   zMServer certificate verification failed - weak certificate signature algorithmzTLS handshake failedÚSecPkgContext_ConnectionInfoÚSSLv2rK   rG   rH   rJ   Úcipher_suiteÚcompressionÚ
session_idÚsession_ticketzl
                        Unable to obtain a credential context with the property %s
                        ÚSecPkgContext_StreamSizes)qrá   r   r   r   ÚISC_REQ_REPLAY_DETECTÚISC_REQ_SEQUENCE_DETECTÚISC_REQ_CONFIDENTIALITYÚISC_REQ_ALLOCATE_MEMORYÚISC_REQ_INTEGRITYÚISC_REQ_STREAMÚISC_REQ_USE_SUPPLIED_CREDSÚ_context_flagsrÍ   ÚSECBUFFER_TOKENrÃ   ÚSECBUFFER_ALERTr   ÚInitializeSecurityContextWr¹   r�   r§   rQ   ÚSEC_E_OKÚSEC_I_CONTINUE_NEEDEDr   r"   rÁ   r   rÄ   r¦   ÚsendÚFreeContextBufferr	   r   Úrecvr.   Úsocket_error_clsr³   rx   r   ÚSEC_E_INCOMPLETE_MESSAGErÂ   r   ÚSEC_E_ILLEGAL_MESSAGEr&   r,   r*   r4   r0   ÚSEC_E_WRONG_PRINCIPALr(   r1   ÚSEC_E_CERT_EXPIREDr/   ÚSEC_E_UNTRUSTED_ROOTr9   r  r2   r6   ÚSEC_E_INTERNAL_ERRORr)   r-   ÚSEC_I_INCOMPLETE_CREDENTIALSr   r  r8   ÚSEC_E_INVALID_TOKENrT   r?   r'   r3   ÚSEC_E_BUFFER_TOO_SMALLÚSEC_E_MESSAGE_ALTEREDrE   ÚSEC_E_INVALID_PARAMETERÚSECBUFFER_EXTRAr   rà   ÚSECPKG_ATTR_CONNECTION_INFOr   ÚSP_PROT_SSL2_CLIENTre   rf   rg   rh   Úgetr   rò   Ú
dwProtocolr   Ú	_protocolr+   Ú_cipher_suiteÚ_compressionÚ_session_idÚ_session_ticketr   ÚOSErrorr   ÚSECPKG_ATTR_STREAM_SIZESÚcbHeaderÚ_header_sizeÚcbMaximumMessageÚ_message_sizeÚ	cbTrailerÚ_trailer_sizeÚ_buffer_sizerU   r3  r¤   r1  rº   ÚDeleteSecurityContext)!r\   ÚrenegotiateÚ
in_buffersÚout_buffersÚnew_context_handle_pointerÚtemp_context_handle_pointerÚrequested_flagsÚflagÚin_sec_buffer_desc_pointerÚout_sec_buffer_desc_pointerÚoutput_context_flags_pointerÚfirst_handleÚsecond_handler�   Úhandshake_server_bytesÚhandshake_client_bytesÚtokenÚin_data_bufferÚ
bytes_readÚ	fail_lateÚ
alert_infoÚchainr  r2  Úalert_bytesÚalert_numberÚextra_amountÚconnection_info_pointerÚconnection_infoÚsession_infoÚoutput_context_flagsÚstream_sizes_pointerÚstream_sizesrC   rC   rD   r¨   ¨  sè  
ù

ô

€ÿô

 þ





€ �
ð 
ý
ûú




üÿ
ý
€ý€ÿûÿzTLSSocket._handshakec                    sF  t |tƒsttdt|ƒƒƒ‚ˆjdu r-ˆjdkr)ˆjd|… }ˆj|d… ˆ_|S ˆ ¡  ˆjsQt	ˆj
ƒˆ_ˆ d¡\ˆ_ˆ_tjˆjd _ttdˆjƒˆjd _t|ˆj
ƒ}tƒ ‰ˆjd ‰ ˆjd ‰ˆjd ‰ˆjd	 ‰‡ ‡‡‡‡‡fd
d„}ˆj}t|ƒ}dˆ_|dkr‘ˆ d¡s‘dˆ_|S tˆjƒdk}||k �r�|r´ˆ jˆj |¡7  _tˆjƒdkr´tƒ  ttˆjƒˆj
ƒ}|dkrÂnË|ˆjd _tˆjˆjd|… ƒ t ˆjˆjdtƒ ¡}d}|tj krë|ƒ  d}q˜|tj!krødˆ_"ˆ #¡  n•|tj$k�r	ˆj%dd� ˆ &|¡S |tj'k�rt(|t)ƒ t*tj+tj,tj-gƒ}	d}
ˆ ˆˆˆfD ]5}|j}|tjk�r@|t.|j|jƒ7 }t|ƒ}�q&|tj/k�rNt0t1|jƒ}
�q&||	v�rZt2td|ƒƒ‚�q&|
�rjˆj||
 d… ˆ_nˆj|d… ˆ_|ƒ  ˆ d¡�r}d}|�s‰tˆjƒdk�r‰n||k s�t|ƒ|k�r¡||d… ˆ_|d|… }|S )a0  
        Reads data from the TLS-wrapped socket

        :param max_length:
            The number of bytes to read

        :raises:
            socket.socket - when a non-TLS socket error occurs
            oscrypto.errors.TLSError - when a TLS-related error occurs
            ValueError - when any of the parameters contain an invalid value
            TypeError - when any of the parameters are of the wrong type
            OSError - when an error is returned by the OS crypto library

        :return:
            A byte string of the data read
        zG
                max_length must be an integer, not %s
                Nr²   r   é   r7  r   r   r;   c                      s^   t jˆ _ttdˆjƒˆ _dˆ _t jˆ_ˆˆ_dˆ_t jˆ_ˆˆ_dˆ_t jˆ_ˆˆ_dˆ_d S )Nr7  r   )	r   ÚSECBUFFER_DATArÃ   r   r   Ú_decrypt_data_bufferrÄ   rÁ   rÂ   rC   ©Úbuf0Úbuf1Úbuf2Úbuf3Ú
null_valuer\   rC   rD   Ú_reset_buffers  s   
z&TLSSocket.read.<locals>._reset_buffersFT)rt  z]
                        Unexpected decrypt output buffer of type %s
                        )3rM   r!   rO   r   r   rá   r´   Ú_raise_closedr“  r	   rr  rÍ   Ú_decrypt_descÚ_decrypt_buffersr   r’  rÃ   r   r   rÄ   Úmaxr   rx   Úselect_readr³   r¦   rS  r.   ÚminrÁ   r   ÚDecryptMessagerU  ÚSEC_I_CONTEXT_EXPIREDÚ_remote_closedÚshutdownÚSEC_I_RENEGOTIATEr¨   rX   rO  r   r"   rQ   rÂ   ÚSECBUFFER_STREAM_HEADERÚSECBUFFER_STREAM_TRAILERr   r`  r   rò   rj  )r\   Ú
max_lengthÚoutputÚto_recvrš  Ú
output_lenÚdo_readÚdata_lenr�   Úvalid_buffer_typesrŠ  ÚbufÚbuffer_typerC   r”  rD   rX   Ö  s¸   
ü






ü



ý
üÿ·MzTLSSocket.readc                 C   s8   t | jƒdkr	dS t | jgg g |¡\}}}t |ƒdkS )aZ  
        Blocks until the socket is ready to be read from, or the timeout is hit

        :param timeout:
            A float - the period of time to wait for data to be read. None for
            no time limit.

        :return:
            A boolean - if data is ready to be read. Will only be False if
            timeout is not None.
        r   T)rx   r´   Úselectr¦   )r\   r½   Ú
read_readyÚ_rC   rC   rD   rŸ  €  s   zTLSSocket.select_readc           	      C   sè   t |tƒst |tƒsttdt|ƒƒƒ‚d}t |tƒ}	 t| jƒdkr)| j}d| _n|  d¡}t|ƒ}||7 }|rG| 	|¡}|durF| 
¡ }nntd|t|ƒ d ƒ}| ||¡}|dkrc|t|ƒ }nq||d… | j | _|d|… S )	aÜ  
        Reads data from the socket until a marker is found. Data read may
        include data beyond the marker.

        :param marker:
            A byte string or regex object from re.compile(). Used to determine
            when to stop reading. Regex objects are more inefficient since
            they must scan the entire byte string of read data each time data
            is read off the socket.

        :return:
            A byte string of the data read
        z_
                marker must be a byte string or compiled regex object, not %s
                r²   Tr   r8  Nr   éÿÿÿÿ)rM   r    ÚPatternrO   r   r   rx   r´   rX   ÚsearchÚendrž  Úfind)	r\   Úmarkerr©  Úis_regexÚchunkÚoffsetÚmatchr·  ÚstartrC   rC   rD   Ú
read_until”  s8   ü


þézTLSSocket.read_untilc                 C   s
   |   t¡S )z·
        Reads a line from the socket, including the line ending of "\r\n", "\r",
        or "\n"

        :return:
            A byte string of the next line from the socket
        )r¿  Ú_line_regex©r\   rC   rC   rD   Ú	read_lineË  s   
	zTLSSocket.read_linec                 C   s6   d}|}|dkr||   |¡7 }|t|ƒ }|dks|S )zé
        Reads exactly the specified number of bytes from the socket

        :param num_bytes:
            An integer - the exact number of bytes to read

        :return:
            A byte string of the data that was read
        r²   r   )rX   rx   )r\   Ú	num_bytesr©  Ú	remainingrC   rC   rD   Úread_exactlyÖ  s   þzTLSSocket.read_exactlyc              
   C   sö  | j du r	|  ¡  | jsht| j| j | j ƒ| _|  d¡\| _| _	t
j| j	d _| j| j	d _ttd| jƒ| j	d _t
j| j	d _t| j| jƒ| j	d _t
j| j	d _| j| j	d _t| j| j| j ƒ| j	d _t|ƒdkrùtt|ƒ| jƒ}t| j|d|… | jƒ || j	d _t| j| j| ƒ| j	d _t | j d| jd¡}|t
jkr©t|tƒ tt| j	d jƒ}|tt| j	d jƒ7 }|tt| j	d jƒ7 }z| j t| j|ƒ¡ W n t j!yê } z	|j"dkråt#ƒ  ‚ d}~ww ||d… }t|ƒdksndS dS )aõ  
        Writes data to the TLS-wrapped socket

        :param data:
            A byte string to write to the socket

        :raises:
            socket.socket - when a non-TLS socket error occurs
            oscrypto.errors.TLSError - when a TLS-related error occurs
            ValueError - when any of the parameters contain an invalid value
            TypeError - when any of the parameters are of the wrong type
            OSError - when an error is returned by the OS crypto library
        Nr‘  r   r7  r   r   iE'  )$rá   r›  Ú_encrypt_data_bufferr	   rm  ro  rq  rÍ   Ú_encrypt_descÚ_encrypt_buffersr   r¦  rÃ   rÁ   r   r   rÄ   r’  r   r§  rx   r   r   ÚEncryptMessagerO  r   r"   r   rò   r¦   rQ  r   r¤   r1  Úerrnor.   )r\   ÚdataÚto_writer�   Úto_sendr®   rC   rC   rD   Úwriteé  sN   
ü


€ýåzTLSSocket.writec                 C   s&   t   g | jgg |¡\}}}t|ƒdkS )aw  
        Blocks until the socket is ready to be written to, or the timeout is hit

        :param timeout:
            A float - the period of time to wait for the socket to be ready to
            written to. None for no time limit.

        :return:
            A boolean - if the socket is ready for writing. Will only be False
            if timeout is not None.
        r   )r±  r¦   rx   )r\   r½   r³  Úwrite_readyrC   rC   rD   Úselect_write'  s   zTLSSocket.select_writec           
      C   sR  | j du rdS d}zßtdkrHttdƒ}d|d _tj|d _ttdt	dƒƒ|d _
ttdƒ}t|ƒ}tj|_d	|_||_t | j |¡}t|tƒ |  d
¡\}}tj|d _tj|d	 _ttdƒ}t | jj| j | j| jddtƒ dtƒ ||tƒ ¡}ttjtjtjgƒ}||vr‹t|tƒ t |d j
|d jƒ}	z| j! "|	¡ W n
 t#j$y¨   Y nw W |rÊt%|d j
ƒs»t &|d j
¡ t%|d	 j
ƒsÊt &|d	 j
¡ t '| j ¡ d| _ z
| j! (t#j)¡ W dS  t#j$yè   Y dS w |�rt%|d j
ƒsût &|d j
¡ t%|d	 j
ƒ�st &|d	 j
¡ t '| j ¡ d| _ z	| j! (t#j)¡ W w  t#j$�y(   Y w w )z±
        Shuts down the TLS session and then shuts down the underlying socket

        :raises:
            OSError - when an error is returned by the OS crypto library
        N)r:  r   zSecBuffer[1]r‘  r   r7  s      r¿   r   r   r6  )*rá   Ú_win_version_infor   r   rÁ   r   rL  rÃ   r   r	   rÄ   r   r   rÅ   rÆ   rÇ   rÈ   ÚApplyControlTokenr   r"   rÍ   rM  rN  r¹   r�   r§   rK  r   rQ   rO  ÚSEC_E_CONTEXT_EXPIREDrP  r   r¦   rQ  r¤   r1  r   rR  rs  r¤  Ú	SHUT_RDWR)
r\   rv  rÊ   rË   rÌ   r�   r|  r}  Úacceptable_resultsr‚  rC   rC   rD   r¤  7  s�   





ôý
ÿ€ÿõÿzTLSSocket.shutdownc                 C   sv   z!|   ¡  W | jr z| j ¡  W n
 tjy   Y nw d| _dS dS | jr:z| j ¡  W n
 tjy6   Y nw d| _w )zN
        Shuts down the TLS session and socket and forcibly closes it
        N)r¤  r¦   rº   r¤   r1  rÁ  rC   rC   rD   rº   ‹  s    
ÿ

ûÿzTLSSocket.closec           
   
   C   s  t tdƒ}t | jtj|¡}t|tƒ t	|ƒ}t
td|ƒ}t	|ƒ}t|jtt|jƒƒ}t |¡| _g | _d}z@|j}t |tƒ ¡}t|ƒsjt	|ƒ}t|jtt|jƒƒ}	|	|kr`| j t |	¡¡ t ||¡}t|ƒrEW |rut |d¡ dS dS |r€t |d¡ w w )zh
        Reads end-entity and intermediate certificate information from the
        TLS session
        zCERT_CONTEXT **zCERT_CONTEXT *Nr   )r   r   r   rà   rá   r   râ   r   r"   r   r   r   rø   r   rò   rù   rY   rú   Ú_certificateÚ_intermediatesÚ
hCertStoreÚCertEnumCertificatesInStorer   r   rZ   r  )
r\   r  r�   r  r0  r  Ústore_handleÚcontext_pointerÚcontextrË  rC   rC   rD   Ú_read_certificates›  s<   
ý
ù€
ÿÿzTLSSocket._read_certificatesc                 C   s   | j rtdƒ‚tdƒ‚)zi
        Raises an exception describing if the local or remote end closed the
        connection
        z$The remote end closed the connectionz!The connection was already closed)r£  r%   r$   rÁ  rC   rC   rD   r›  Ã  s   zTLSSocket._raise_closedc                 C   s*   | j du r	|  ¡  | jdu r|  ¡  | jS )zu
        An asn1crypto.x509.Certificate object of the end-entity certificate
        presented by the server
        N)rá   r›  rÖ  rÝ  rÁ  rC   rC   rD   rª   Î  ó
   

zTLSSocket.certificatec                 C   s*   | j du r	|  ¡  | jdu r|  ¡  | jS )zz
        A list of asn1crypto.x509.Certificate objects that were presented as
        intermediates by the server
        N)rá   r›  rÖ  rÝ  r×  rÁ  rC   rC   rD   ÚintermediatesÝ  rÞ  zTLSSocket.intermediatesc                 C   ó   | j S )zg
        A unicode string of the IANA cipher suite name of the negotiated
        cipher suite
        )rf  rÁ  rC   rC   rD   r?  ì  s   zTLSSocket.cipher_suitec                 C   rà  )zM
        A unicode string of: "TLSv1.2", "TLSv1.1", "TLSv1", "SSLv3"
        )re  rÁ  rC   rC   rD   r]   õ  ó   zTLSSocket.protocolc                 C   rà  )z5
        A boolean if compression is enabled
        )rg  rÁ  rC   rC   rD   r@  ý  rá  zTLSSocket.compressionc                 C   rà  ©zM
        A unicode string of "new" or "reused" or None for no ticket
        )rh  rÁ  rC   rC   rD   rA    rá  zTLSSocket.session_idc                 C   rà  râ  )ri  rÁ  rC   rC   rD   rB    rá  zTLSSocket.session_ticketc                 C   rà  )zM
        The oscrypto.tls.TLSSession object used for this connection
        )r¹   rÁ  rC   rC   rD   r£     rá  zTLSSocket.sessionc                 C   rà  )zN
        A unicode string of the TLS server domain name or IP address
        )r§   rÁ  rC   rC   rD   r¬     rá  zTLSSocket.hostnamec                 C   s   | j  ¡ d S )zJ
        An integer of the port number the socket is connected to
        r   )r¥   ÚgetpeernamerÁ  rC   rC   rD   r¼   %  s   zTLSSocket.portc                 C   s   | j du r	|  ¡  | jS )z9
        The underlying socket.socket connection
        N)rá   r›  r¦   rÁ  rC   rC   rD   r¥   -  s   
zTLSSocket.socketc                 C   s   |   ¡  d S rž   )rº   rÁ  rC   rC   rD   r    8  s   zTLSSocket.__del__rž   )r±   N)F):r@   rA   rB   rF   r¦   r¹   rá   rK  r§   rm  ro  rq  r³   r´   rÇ  rÈ  rÆ  rœ  r�  r“  rÖ  r×  re  rf  rg  rh  ri  r£  Úclassmethodr°   rc   rÍ   r3  r¨   rX   rŸ  r¿  rÂ  rÅ  rÎ  rÐ  r¤  rº   rÝ  r›  Úpropertyrª   rß  r?  r]   r@  rA  rB  r£   r¬   r¼   r¥   r    rC   rC   rC   rD   r>     sŒ    
>W 
3  0 
+7
>T(











)^Ú
__future__r   r   r   r   ÚsysÚrer¥   r¤   r±  rµ   Ú_asn1r   rY   Ú_errorsr   Ú_ffir	   r
   r   r   r   r   r   r   r   r   r   r   r   r   Ú_secur32r   r   r   Ú_crypt32r   r   rÚ   Ú	_kernel32r   Ú_typesr   r   r    r!   Úerrorsr"   r#   r$   r%   Ú_tlsr&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r8   Ú
asymmetricr9   Úkeysr:   Úversion_infoÚxrangerÀ   r1  rT  ÚWindowsErrorÚ_pattern_typerµ  Ú__all__ÚcompilerÀ  ÚgetwindowsversionÚ_gwvrÑ  r?   rE   Úobjectr=   r>   rC   rC   rC   rD   Ú<module>   sF   @T

þ
 ?