o
    h                     @   sh   d Z ddlZddlmZmZmZ ddlmZ ddlm	Z	 ddl
mZmZmZmZ dgZG d	d dZdS )
z
Module to handle the timestamping functionality in pyHanko.

Many PDF signature profiles require trusted timestamp tokens.
The tools in this module allow pyHanko to obtain such tokens from
:rfc:`3161`-compliant time stamping
authorities.
    N)algoscmstsp)CertificateValidator)SimpleCertificateStore   )dummy_digestextract_ts_certs	get_noncehandle_tsp_responseTimeStamperc                   @   sp   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zde	j
fddZdejdejfddZde	j
fddZdS )r   z
    .. versionchanged:: 0.9.0
        Made API more asyncio-friendly _(breaking change)_

    Class to make :rfc:`3161` timestamp requests.
    Tc                 C   s   i | _ i | _t | _|| _d S N)_dummy_response_cache_certsr   cert_registryinclude_nonce)selfr    r   R/var/www/html/pos/venv/lib/python3.10/site-packages/pyhanko/sign/timestamps/api.py__init__#   s   
zTimeStamper.__init__c                 C   sP   dt td|i|ddd}| jrt }t||d< nd}|t |fS )a&  
        Format the body of an :rfc:`3161` request as a CMS object.
        Subclasses with more specific needs may want to override this.

        :param message_digest:
            Message digest to which the timestamp will apply.
        :param md_algorithm:
            Message digest algorithm to use.

            .. note::
                As per :rfc:`8933`, ``md_algorithm`` should also be the
                algorithm used to compute ``message_digest``.
        :return:
            An :class:`.asn1crypto.tsp.TimeStampReq` object.
        r   	algorithm)hash_algorithmhashed_messageT)versionmessage_imprintcert_reqnonceN)	r   MessageImprintr   DigestAlgorithmr   r
   r   IntegerTimeStampReq)r   message_digestmd_algorithmreqr   r   r   r   request_cms)   s   	zTimeStamper.request_cmsc                   sN      I dH   fdd}t| j }t|D ]}|I dH V  qdS )a+  
        Produce validation paths for the certificates gathered by this
        :class:`.TimeStamper`.

        This is internal API.

        :param validation_context:
            The validation context to apply.
        :return:
            An asynchronous generator of validation paths.
        Nc                    s    t |  jd}|t dhS )N)intermediate_certsvalidation_contexttime_stamping)r   r   async_validate_usageset)cert	validatorr   r&   r   r   _validation_job[   s   z5TimeStamper.validation_paths.<locals>._validation_job)_ensure_dummymapr   valuesasyncioas_completed)r   r&   r-   jobsjobr   r,   r   validation_pathsM   s   zTimeStamper.validation_pathsc                 C   s,   || j |< t|| jD ]}|| j|j< qd S r   )r   r	   r   r   issuer_serial)r   r"   dummyr*   r   r   r   _register_dummyh   s   
zTimeStamper._register_dummyc                    s,   | j sddlm} | |I d H  d S d S )Nr   )
DEFAULT_MD)r   pyhanko.signr9   async_dummy_response)r   r9   r   r   r   r.   m   s
   zTimeStamper._ensure_dummyreturnc                    sH   z| j | W S  ty   | t||I dH }Y nw | || |S )a9  
        Return a dummy response for use in CMS object size estimation.

        For every new ``md_algorithm`` passed in, this method will call
        the :meth:`timestamp` method exactly once, with a dummy digest.
        The resulting object will be cached and reused for future invocations
        of :meth:`dummy_response` with the same ``md_algorithm`` value.

        :param md_algorithm:
            Message digest algorithm to use.
        :return:
            A timestamp token, encoded as an
            :class:`.asn1crypto.cms.ContentInfo` object.
        N)r   KeyErrorasync_timestampr   r8   )r   r"   r7   r   r   r   r;   t   s   z TimeStamper.async_dummy_responser#   c                    s   t )aF  
        Submit the specified timestamp request to the server.

        :param req:
            Request body to submit.
        :return:
            A timestamp response from the server.
        :raises IOError:
            Raised in case of an I/O issue in the communication with the
            timestamping server.
        )NotImplementedError)r   r#   r   r   r   async_request_tsa_response   s   z&TimeStamper.async_request_tsa_responsec                    s,   |  ||\}}| |I dH }t||S )a+  
        Request a timestamp for the given message digest.

        :param message_digest:
            Message digest to which the timestamp will apply.
        :param md_algorithm:
            Message digest algorithm to use.

            .. note::
                As per :rfc:`8933`, ``md_algorithm`` should also be the
                algorithm used to compute ``message_digest``.
        :return:
            A timestamp token, encoded as an
            :class:`.asn1crypto.cms.ContentInfo` object.
        :raises IOError:
            Raised in case of an I/O issue in the communication with the
            timestamping server.
        :raises TimestampRequestError:
            Raised if the timestamp server did not return a success response,
            or if the server's response is invalid.
        N)r$   r@   r   )r   r!   r"   r   r#   resr   r   r   r>      s   
zTimeStamper.async_timestampN)T)__name__
__module____qualname____doc__r   r$   r5   r8   r.   r   ContentInfor;   r   r    TimeStampRespr@   r>   r   r   r   r   r      s     
$
)rE   r1   
asn1cryptor   r   r   pyhanko_certvalidatorr   pyhanko_certvalidator.registryr   common_utilsr   r	   r
   r   __all__r   r   r   r   r   <module>   s    	