o
    RDiD                     @  sl  d dl mZ d dlZd dlmZmZ d dlmZ d dlmZm	Z	 d dl
mZ d dlmZ d dlmZ d d	lmZmZ d d
lmZmZmZmZmZmZmZmZ d dlmZ d dlmZ d dl m!Z! d dl"m#Z#m$Z$ d dl%m&Z&m'Z' d dl(m)Z) d dl*m+Z+m,Z, d dl-m.Z. d dl/m0Z0 d dl1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7 d dl8m9Z9 d dl:m;Z;m<Z< ee=Z>G dd de;Z?dS )    )annotationsN)	b64decode	b64encode)OrderedDict)datetimetimezone)	getLogger)getenv)DigestAlgorithm)IntegerOctetString)CertIdOCSPRequestOCSPResponseRequestRequestsSingleResponse
TBSRequestVersion)Certificate)InvalidSignature)default_backend)hashesserialization)paddingutils)DSAPublicKey)ECDSAEllipticCurvePublicKey)RSAPublicKey)
Connection)&ER_OCSP_RESPONSE_ATTACHED_CERT_EXPIRED&ER_OCSP_RESPONSE_ATTACHED_CERT_INVALID$ER_OCSP_RESPONSE_CERT_STATUS_INVALID"ER_OCSP_RESPONSE_INVALID_SIGNATUREER_OCSP_RESPONSE_LOAD_FAILURE$ER_OCSP_RESPONSE_STATUS_UNSUCCESSFUL)RevocationCheckError)SnowflakeOCSPgenerate_cache_keyc                      s   e Zd ZdZejejejdZdd Z	d>d	d
Z
dd Zdd Zd?d@ddZdAddZdd Zdd Zdd ZdBd"d#Zd$d% ZdC fd*d+Z	 dDd-d.Zd/d0 Zd1d2 ZdEd6d7ZdFd:d;ZdGd<d=Z  ZS )HSnowflakeOCSPAsn1CryptozOCSP checks by asn1crypto.)sha256sha384sha512c                 C  sH   |\}}}t |}t |}t|}ttdd d|||d}|S )Nsha1	algorithm
parametershash_algorithmissuer_name_hashissuer_key_hashserial_number)r   loadr   r   r
   )selfhkeyr4   r5   r6   cert_id r;   \/var/www/Datamplify/venv/lib/python3.10/site-packages/snowflake/connector/ocsp_asn1crypto.pyencode_cert_id_key9   s   




z*SnowflakeOCSPAsn1Crypto.encode_cert_id_keyr:   r   returntuple[bytes, bytes, bytes]c                 C  s   t |S N)r)   )r8   r:   r;   r;   r<   decode_cert_id_keyJ      z*SnowflakeOCSPAsn1Crypto.decode_cert_id_keyc                 C  s   t t|S r@   )r   r7   r   )r8   cert_id_base64r;   r;   r<   decode_cert_id_base64M   s   z-SnowflakeOCSPAsn1Crypto.decode_cert_id_base64c                 C  s   t | | dS Nascii)r   r=   dumpdecode)r8   r9   r;   r;   r<   encode_cert_id_base64P   s   z-SnowflakeOCSPAsn1Crypto.encode_cert_id_base64NNonec           
      C  s   |du rt j}td| t|d/}ddlm} |j| dd}|D ]\}}}|dkr8t	
|}	|	||	jj< q$W d   dS 1 sDw   Y  dS )	z>Reads a certificate file including certificates in PEM format.Nzreading certificate bundle: %srbr   )pemT)multipleCERTIFICATE)r(   ROOT_CERTIFICATES_DICTloggerdebugopen
asn1cryptorL   unarmorreadr   r7   subjectr+   )
r8   ca_bundle_filestorage	all_certsrL   	pem_certs	type_name_	der_bytescrtr;   r;   r<   read_cert_bundleS   s   
"z(SnowflakeOCSPAsn1Crypto.read_cert_bundleissuerr   rV   tuple[CertId, OCSPRequest]c                 C  s^   t tdddt|jjt|jj|jd}tdtt	dt
td|igdi}||fS )	zCreates CertId and OCSPRequest.r.   Nr/   r2   tbs_requestr   req_cert)versionrequest_list)r   r
   r   r`   r.   
public_keyr6   r   r   r   r   r   )r8   r`   rV   r:   ocsp_requestr;   r;   r<   create_ocsp_requestb   s0   


z+SnowflakeOCSPAsn1Crypto.create_ocsp_requestc                 C  s   |j }|r|d }|S d }|S )Nr   )	ocsp_urls)r8   certurlsocsp_urlr;   r;   r<   extract_ocsp_url   s
   z(SnowflakeOCSPAsn1Crypto.extract_ocsp_urlc                 C  s   |  S r@   )rG   )r8   rg   r;   r;   r<   decode_ocsp_request   rB   z+SnowflakeOCSPAsn1Crypto.decode_ocsp_requestc                 C  s   |  |}t|d}|S rE   )rn   r   rH   )r8   rg   datab64datar;   r;   r<   decode_ocsp_request_b64   s   
z/SnowflakeOCSPAsn1Crypto.decode_ocsp_request_b64single_responser   tuple[datetime, datetime]c                 C  s   |d j }|d j }||fS )zExtracts GOOD status.this_updatenext_updatenative)r8   rr   this_update_nativenext_update_nativer;   r;   r<   extract_good_status   s   

z+SnowflakeOCSPAsn1Crypto.extract_good_statusc                 C  s$   |d }|j d }|j d }||fS )zExtracts REVOKED status.cert_statusrevocation_timerevocation_reasonrv   )r8   rr   revoked_infor|   r}   r;   r;   r<   extract_revoked_status   s   

z.SnowflakeOCSPAsn1Crypto.extract_revoked_statuscur_timer   	ocsp_certtuple[bool, str | None]c                   sT   |d d d j }|d d d j }||ks||k r(d|||t j}d|fS dS )Ntbs_certificatevalidity
not_before	not_afterzCertificate attached to OCSP response is invalid. OCSP response current time - {} certificate not before time - {} certificate not after time - {}. Consider running curl -o ocsp.der {}F)TN)rw   formatsuperdebug_ocsp_failure_url)r8   r   r   	val_startval_end	debug_msg	__class__r;   r<   check_cert_time_validity   s   z0SnowflakeOCSPAsn1Crypto.check_cert_time_validityboolc              
   C  s
  t |}|d jdkrtd|d jtd|j}|d jrK|d d }td|d d	 d
 j t	
tj}	 | ||\}}|sKt| dS |d }	|	d d }
|
d j}z|dkri| |
|| W dS W dS  ty } ztd| W Y d }~dS d }~ww )Nresponse_status
successfulInvalid Status: {}msgerrnocertsr   zOVerifying the attached certificate is signed by the issuer. Valid Not After: %sr   r   r   Ftbs_response_data	responsesr{   goodz#Failed to validate ocsp response %sT)r   r7   rw   r'   r   r&   basic_ocsp_responserP   rQ   r   nowr   utcr   name_process_good_status	Exception)r8   r:   ocsp_responseresr   r   r   
cert_validr   r   rr   r{   exr;   r;   r<   is_valid_time   sB   



z%SnowflakeOCSPAsn1Crypto.is_valid_timec              
   C  s  zt |}| jd urtd}|d urtdtdW n ty'   tdtdw |d jdkr;td|d jt	d|j
}|d	 jrtd
 |d	 d }td td|d d d j ttj}z	 | |j|j||d  W n ty }	 zt|	jtdd }	~	ww | ||\}
}|
st|tdntd |}|d }td z| |d j|d j|| W n ty }	 zt|	jtdd }	~	ww |d d }|d j}| jd urtd}|dkrd}n|dkrd}n|dkrd}z5|dkr| ||| W d S |dkr| || W d S |dkr!| | W d S d|}t|td tyG } zd|j| j}t||jdd }~ww )N$SF_TEST_OCSP_FORCE_BAD_OCSP_RESPONSEz
Force fail)r   zInvalid OCSP Responser   r   r   r   r   z.Certificate is attached in Basic OCSP Responser   z:Verifying the attached certificate is signed by the issuerzValid Not After: %sr   r   r   zNCertificate is NOT attached in Basic OCSP Response. Using issuer's certificater   z4Verifying the OCSP response is signed by the issuer.signature_algorithm	signaturer   r{   SF_TEST_OCSP_CERT_STATUSrevokedunknownr   zJUnknown revocation status was returned.OCSP response may be malformed: {}.z'{} Consider running curl -o ocsp.der {}) r   r7   	test_moder	   r'   r%   r   rw   r   r&   r   rP   rQ   r   r   r   r   verify_signature	hash_algor   r   r"   r   r!   r$   r   r   _process_revoked_status_process_unknown_statusr#   r   r   )r8   r`   r:   r   r   ocsp_load_failurer   r   r   rcer   r   r   rr   r{   test_cert_statusop_err;   r;   r<   process_ocsp_response   s   









z-SnowflakeOCSPAsn1Crypto.process_ocsp_responsec                 C  s   t  }tj|j t  d}|tjv rtj|  }nt }t	||}|
|  | }	t }
t|trEt |
d< t||
d< nt|trRt||
d< nt|tr`tt||
d< z|j||	fi |
 W d S  tyy   tddw )N)backendr   r0   r   zFailed to verify the signaturer   )r   r   load_der_public_keyrf   rG   r*   #SIGNATURE_ALGORITHM_TO_DIGEST_CLASSr   SHA1Hashupdatefinalizedict
isinstancer   r   PKCS1v15r   	Prehashedr   r   r   verifyr   r'   )r8   r   r   rj   ro   r   rf   chosen_hashhasherdigestadditional_kwargsr;   r;   r<   r   a  sD   



z(SnowflakeOCSPAsn1Crypto.verify_signature
connectionr    %list[tuple[Certificate, Certificate]]c           	      C  s   ddl m}m} t }| }tdt| |   |D ].}|||}t	
|}td|jj|jj |||jj< |jjtjv rKtd|jj  nq| |S )zHGets certificate chain and extract the key info from OpenSSL connection.r   )FILETYPE_ASN1dump_certificatez# of certificates: %szsubject: %s, issuer: %szCA trusted root certificate found: %s, stopping chain traversal here)OpenSSL.cryptor   r   r   get_peer_cert_chainrP   rQ   len_lazy_read_ca_bundler   r7   rV   rw   r`   r+   r(   rO   create_pair_issuer_subject)	r8   r   r   r   cert_map
cert_chaincert_opensslcert_derrj   r;   r;   r<   extract_certificate_chain  s(   


z1SnowflakeOCSPAsn1Crypto.extract_certificate_chainr   r   c                 C  s   g }|D ]?}|| }|j s|jr|jsq|jj}||vr8|   td|jj |t	j
vr2tddt	j
| }n|| }|||f q|S )z1Creates pairs of issuer and subject certificates.znot found issuer_der: %szCA certificate is NOT found in the root certificate list. Make sure you use the latest Python Connector package and the URL is valid.r   )ocsp_no_check_valuecari   r`   r+   r   rP   rQ   rw   r(   rO   r'   append)r8   r   issuer_subjectsubject_derrV   issuer_hashr`   r;   r;   r<   r     s"   
z2SnowflakeOCSPAsn1Crypto.create_pair_issuer_subjectc                 C  s   |j jS r@   )rV   rw   )r8   rV   r;   r;   r<   subject_name  rB   z$SnowflakeOCSPAsn1Crypto.subject_name)r:   r   r>   r?   r@   )r>   rJ   )r`   r   rV   r   r>   ra   )rr   r   r>   rs   )r   r   r   r   r>   r   )r>   r   )r   r    r>   r   )r   r   r>   r   )rV   r   r>   r   )__name__
__module____qualname____doc__r   SHA256SHA384SHA512r   r=   rA   rD   rI   r_   rh   rm   rn   rq   rz   r   r   r   r   r   r   r   r   __classcell__r;   r;   r   r<   r*   /   s2    

$
	
2n
%
r*   )@
__future__r   typingbase64r   r   collectionsr   r   r   loggingr   osr	   asn1crypto.algosr
   asn1crypto.corer   r   asn1crypto.ocspr   r   r   r   r   r   r   r   asn1crypto.x509r   cryptography.exceptionsr   cryptography.hazmat.backendsr   cryptography.hazmat.primitivesr   r   )cryptography.hazmat.primitives.asymmetricr   r   -cryptography.hazmat.primitives.asymmetric.dsar   ,cryptography.hazmat.primitives.asymmetric.ecr   r   -cryptography.hazmat.primitives.asymmetric.rsar   OpenSSL.SSLr    snowflake.connector.errorcoder!   r"   r#   r$   r%   r&   snowflake.connector.errorsr'   "snowflake.connector.ocsp_snowflaker(   r)   r   rP   r*   r;   r;   r;   r<   <module>   s0   (
 