o
    ɶd1H                     @   s   d dl mZ d dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
Zd dlZd dlmZ d dlZd dlZd dlZej    ZG dd	 d	eZG d
d deZG dd deZG dd deZG dd deZdS )    )x509)default_backend)requests)	HTTPError)ServiceErrorN)sixc                   @   sD   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dS )AbstractCertificateRetrieverc                 K   s   d d d d| _ d S )N)certificateprivate_key_pemprivate_keycertificate_and_private_keyselfkwargs r   Busr/lib/python3.10/site-packages/oci/auth/certificate_retriever.py__init__*   s   z%AbstractCertificateRetriever.__init__c                 C      t dNz Subclasses should implement thisNotImplementedErrorr   r   r   r   refresh2      z$AbstractCertificateRetriever.refreshc                 C   r   r   r   r   r   r   r   get_certificate_and_private_key6   r   z<AbstractCertificateRetriever.get_certificate_and_private_keyc                 C   r   r   r   r   r   r   r   get_certificate_as_certificate:   r   z;AbstractCertificateRetriever.get_certificate_as_certificatec                 C   r   r   r   r   r   r   r   get_certificate_raw>   r   z0AbstractCertificateRetriever.get_certificate_rawc                 C   r   r   r   r   r   r   r   get_private_key_pemB   r   z0AbstractCertificateRetriever.get_private_key_pemc                 C   r   r   r   r   r   r   r   get_private_keyF   r   z,AbstractCertificateRetriever.get_private_keyN)
__name__
__module____qualname__r   r   r   r   r   r   r   r   r   r   r   r   )   s    r   c                       sd   e Zd ZdZdZ f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  ZS )UrlBasedCertificateRetrievera  
    A certificate retriever which reads PEM-format strings from URLs.

    :param str certificate_url:
        The URL from which to retrieve a certificate. It is assumed that what we retrieve is the PEM-formatted string for the certificate.
        This is mandatory

    :param str private_key_url: (optional)
        The URL from which to retrieve the private key corresponding to certificate_url (if any). It is assumed that what we retrieve is the PEM-formatted string for
        the private key.

    :param str passphrase: (optional)
        The passphrase of the private key (if any).

    :param obj retry_strategy: (optional)
        A retry strategy to use when retrieving the certificate and private key from the URLs provided to this class. This should be one of the strategies available in
        the :py:mod:`~oci.retry` module. By default this retriever will not perform any retries.

    :param bool log_requests: (optional)
        log_request if set to True will log the request url and response data when retrieving
        the certificate & corresponding private key (if there is one defined for this retriever)

    **Note:** This class is used internally, it is not recommended for user's direct use.
    i   c                    s   t t|   d|vrtd|d | _|d| _|d| _|d| _t	
dtt| | _| jt	  |drKd| j_| jt	j nd	| j_| jr`t| jtjr`| jd
| _t | _t | _|dd rz| jj|d |    d S )NZcertificate_urlz6certificate_url must be supplied as a keyword argumentprivate_key_url
passphraseretry_strategyz{}.{}Zlog_requestsFTasciiheaders)!superr#   r   	TypeErrorcert_urlgetr$   r%   r&   logging	getLoggerformatr    idlogger
addHandlerNullHandlerdisabledsetLevelDEBUG
isinstancer   	text_typeencode	threadingLock_refresh_lockr   ZSessionrequests_sessionr(   updater   r   	__class__r   r   r   f   s(   



z%UrlBasedCertificateRetriever.__init__c                 C   sV   | j   z| jr| j| j n|   W | j   dS W | j   dS | j   w )zp
        Refresh the token by making a call to Identity for a new token.
        Returns the new token.
        N)r<   acquirer&   Zmake_retrying_call_refresh_innerreleaser   r   r   r   r      s   

z$UrlBasedCertificateRetriever.refreshc                 C   s"   | j   | j }| j   |S z]
        Returns the certificate_and_private_key dictionary contained by this object
        r<   rA   r   copyrC   )r   Zret_valr   r   r   r      s   


z<UrlBasedCertificateRetriever.get_certificate_and_private_keyc                 C   s   |   }|rt|t S dS )N
        Retrieves the certificate as a cryptography.x509.Certificate
        N)r   r   load_pem_x509_certificater   )r   Zraw_certr   r   r   r      s   z;UrlBasedCertificateRetriever.get_certificate_as_certificatec                 C   &   | j   | j d }| j   |S zH
        Retrieves a string containing the certificate contents
        r	   rE   )r   r	   r   r   r   r         

z0UrlBasedCertificateRetriever.get_certificate_rawc                 C   rI   )zK
        Retrievea a string containing the PEM-encoded private key
        r
   rE   r   r   r   r   r   r      rK   z0UrlBasedCertificateRetriever.get_private_key_pemc                 C   rI   zI
        Retrieves the private key as a cryptography private key
        r   rE   rL   r   r   r   r      rK   z,UrlBasedCertificateRetriever.get_private_keyc              
   C   s  ddl }t }| jd| j  | jj| jddd}| jdt	j
|j|jt|j |jdd	d
 z|  W n tyV } zt|jj|j|jjt|d}~ww |jj| jddD ]}|| q`|  | jd< |  t| jd tj r| jd !d| jd< | "| jd  | j#r@t }| jd| j#  | jj| j#ddd}| jdt	j
|j|jt|j |jdd	d
 z|  W n ty } zt|jj|j|jjt|d}~ww |jj| jddD ]}|| q|  | jd< |  t| jd tj r| jd !d| jd< z|j$%| jd | j&| jd< W dS  |j'j(y?   t)d| jd dw dS )af  
        Refreshes the certificate and its corresponding private key (if there is one defined for this retriever).
        This method represents the unit of retrying for the certificate retriever. It is intentionally coarse
        grained (e.g. if we retrieve the certificate but fail to retrieve the private key then we'll retry and
        retrieve both the certificate and private key again) to try and best maintain consistency in the data.

        For example, if we had separate retries for the certificate and the private key, in the scenario where
        a certificate was successfully retrieved but the private key failed, the private key we successfully
        retrieved upon retry may not relate to the certificate that we retrieved (e.g. because of rotation). This
        is still a risk in coarse grained retries, but hopefully a smaller one.
        r   Nz!Requesting certificate from : %s T)
   <   )streamtimeoutz(Receiving certificate response......
{}
)status_codeurlheaderreason   )indentF)Zdecode_contentr	   r'   z!Requesting private key from : %s z(Receiving private key response......
{}
r
   r   certificate_typecertificate_raw)*
oci.signerr   BytesIOr1   debugr+   r=   r,   r/   pprintpformatrR   rS   dictr(   itemsrU   Zraise_for_statusr   r   responseerrnostrrawrP   READ_CHUNK_BYTESwritegetvaluestripr   closer7   r8   r9   _check_valid_certificate_stringr$   signerload_private_keyr%   
exceptionsZInvalidPrivateKey+InvalidCertificateFromInstanceMetadataError)r   ociZdownloaded_certificaterb   echunkZdownloaded_private_key_rawr   r   r   rB      sr   

z+UrlBasedCertificateRetriever._refresh_innerc                 C   s0   z
t |t  W dS  ty   td|dw )a  
        Determines whether a given string is a valid certificate. Valid in this context means that it
        can be parsed into a cryptography.io X509 certificate object. If the string is not valid then
        this method will throw an exception.

        :param str certificate_string_to_check:
            The certificate string to check. If it is valid then it should be a PEM-formatted string
            and able to be parsed into a cryptography.io X509 certificate object
        r	   rX   N)r   rH   r   
ValueErrorro   )r   Zcertificate_string_to_checkr   r   r   rk   
  s   
z<UrlBasedCertificateRetriever._check_valid_certificate_string)r    r!   r"   __doc__rf   r   r   r   r   r   r   r   rB   rk   __classcell__r   r   r?   r   r#   J   s    




Fr#   c                       sP   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Zdd Z	dd Z
  ZS )PEMStringCertificateRetrievera?  
    A certificate retriever which is provided PEM format strings directly. This retriever is non-refreshable, and calling refresh() is a no-op.

    :param str certificate_pem:
        The PEM-formatted string of the certificate. This is mandatory.

    :param str private_key_pem (optional):
        The PEM-formatted string of the private key corresponding to certificate_pem (if any).

    :param str passphrase (optional):
        The passphrase of the private key (if any).

    **Note:** This class is used internally, it is not recommended for user's direct use.
    c                    s   dd l }tt|   d|vrtdt|d tjr&|d d| j	d< n|d | j	d< d|v rp|d rrt|d tjrH|d d| j	d< n|d | j	d< d|v r_|d r_|d d}nd }|j
| j	d || j	d< d S d S d S )	Nr   certificate_pemz6certificate_pem must be supplied as a keyword argumentr'   r	   r
   r%   r   )r[   r)   rv   r   r*   r7   r   r8   r9   r   rl   rm   )r   r   rp   r%   r?   r   r   r   -  s&   z&PEMStringCertificateRetriever.__init__c                 C   s   dS )z
        Since these are just the string, there is no refresh as such. A new object should be created
        if the strings change
        Nr   r   r   r   r   r   J  s   z%PEMStringCertificateRetriever.refreshc                 C   s
   | j  S rD   )r   rF   r   r   r   r   r   Q     
z=PEMStringCertificateRetriever.get_certificate_and_private_keyc                 C   s   t | jd t S )rG   r	   )r   rH   r   r   r   r   r   r   r   W  s   z<PEMStringCertificateRetriever.get_certificate_as_certificatec                 C   
   | j d S rJ   r   r   r   r   r   r   ]  rx   z1PEMStringCertificateRetriever.get_certificate_rawc                 C   ry   )zL
        Retrieve a a string containing the PEM-encoded private key
        r
   r   r   r   r   r   r   c  rx   z1PEMStringCertificateRetriever.get_private_key_pemc                 C   ry   rM   r   r   r   r   r   r   i  rx   z-PEMStringCertificateRetriever.get_private_key)r    r!   r"   rt   r   r   r   r   r   r   r   ru   r   r   r?   r   rv     s    rv   c                       s(   e Zd ZdZ fddZdd Z  ZS )FileBasedCertificateRetrievera/  
    A specialization of PEMStringCertificateRetriever which reads certificates from a file. This retriever is non-refreshable, and calling refresh() is a no-op.

    :param str certificate_file_path:
        The file path from which to retrieve a certificate. It is assumed that what we retrieve is the PEM-formatted string for the certificate.
        This is mandatory

    :param str private_key_pem_file_path (optional):
        The file path from which to retrieve the private key corresponding to certificate_file_path (if any). It is assumed that what we retrieve is the PEM-formatted string for
        the private key.

    :param str passphrase (optional):
        The passphrase of the private key (if any).

    **Note:** This class is used internally, it is not recommended for user's direct use.
    c                    sb   d|vrt dd|v r| |d }nd }| |d ||dd}tt| jdi | d S )NZcertificate_file_pathz<certificate_file_path must be supplied as a keyword argumentZprivate_key_pem_file_pathr%   )rw   r
   r%   r   )r*   _load_data_from_filer,   r)   rz   r   )r   r   r
   Zparent_class_kwargsr?   r   r   r     s   z&FileBasedCertificateRetriever.__init__c                 C   sJ   t j|}t|dd}|  }W d    |S 1 sw   Y  |S )Nrb)mode)ospath
expanduseropenreadri   )r   filenamefZ	cert_datar   r   r   r{     s   
z2FileBasedCertificateRetriever._load_data_from_file)r    r!   r"   rt   r   r{   ru   r   r   r?   r   rz   p  s    rz   c                       s   e Zd Zd fdd	Z  ZS )ro   r	   Nc                    s,   || _ || _tt| d| j| j d d S )NzTInvalid certificate returned from instance metadata. Expected a PEM-formatted string)messagerY   rZ   )rZ   rY   r)   ro   r   )r   rY   rZ   r?   r   r   r     s   
z4InvalidCertificateFromInstanceMetadataError.__init__)r	   N)r    r!   r"   r   ru   r   r   r?   r   ro     s    ro   )Zcryptographyr   Zcryptography.hazmat.backendsr   Zoci._vendorr   Zoci._vendor.requests.exceptionsr   Zoci.exceptionsr   Z	oci.retryrp   os.pathr~   r   r:   r-   r^   retryZRetryStrategyBuilderZadd_max_attemptsZadd_total_elapsed_timeZget_retry_strategyZ:INSTANCE_METADATA_URL_CERTIFICATE_RETRIEVER_RETRY_STRATEGYobjectr   r#   rv   rz   	Exceptionro   r   r   r   r   <module>   s*   ! TS+