U
    gE                 
   @   sf  d 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 ddlZddl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 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( ddl)m*Z* ddl+m,Z, ddl-m.Z.m/Z/ ddl0m1Z1 ddl2m3Z3 ddl4m5Z5 ddl6m7Z7m8Z8m9Z9 ddl:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@ ddlAmBZB ddlmCZCmDZDmEZEmFZFmGZG ddlHmIZI ddd d!d"d#d$d%d&d'g
ZJdd(lKmLZL dd)lMmNZNmOZO ePeQZRed*d+G d,d- d-ZSed*d+G d.d! d!eSZTd/d0 ZUeeVejWf d1d2d3ZXd*e1jYdfeeeZej[ej\f eVd4d5d6Z]dTee7 e
ej^ e_ej^d9d:d"Z`dUeZee7 ej^d<d=d#ZaG d>d dZbd?d$ ZcG d@d debZddVeOeeZ dAdBd&ZedWeNeeZ dCdDd'ZfG dEd  d ebZgG dFdG dGe8ZhG dHdI dIehZiG dJdK dKe8ZjG dLdM dMe9ZkdNdOgZldPdQgZmejneVdRdSd%ZodS )XzV
This module defines utility classes to format CMS objects for use in PDF
signatures.
    N)	dataclass)datetime)IOCallableIterableListOptionalUnion)algoscmscorekeys)pdf)x509)SignedDigestAlgorithm)hashesserialization)DSAPrivateKey)ECDSAEllipticCurvePrivateKey)Ed448PrivateKey)Ed25519PrivateKey)PKCS1v15)RSAPrivateKey)pkcs12	to_thread)CertificateStoreSimpleCertificateStore)misc)
attributes)CAdESSignedAttrSpec)CMSAttributeProviderSignedAttributeProviderSpecUnsignedAttributeProviderSpec)SigningErrorget_cms_hash_algo_for_mechanismget_pyca_cryptography_hashoptimal_pss_paramsprocess_pss_paramssimple_cms_attribute)TimeStamper   ))_translate_pyca_cryptography_cert_to_asn1(_translate_pyca_cryptography_key_to_asn1load_cert_from_pemderload_certs_from_pemderload_private_key_from_pemder   )	constantsSignerSimpleSignerExternalSignerPdfCMSSignedAttributesformat_attributesformat_signed_attributesasyncify_signerselect_suitable_signing_mdsigner_from_p12_configsigner_from_pemder_config)ConfigurationError)PemDerSignatureConfigPKCS12SignatureConfigT)frozenc                   @   s2   e Zd ZU dZdZee ed< dZee	 ed< dS )CMSSignedAttributesz
    .. versionadded:: 0.14.0

    Serialisable container class describing input for various signed attributes
    in a signature CMS object.
    Nsigning_timecades_signed_attrs)
__name__
__module____qualname____doc__rC   r   r   __annotations__rD   r!    rJ   rJ   @/tmp/pip-unpacked-wheel-owvgwkas/pyhanko/sign/signers/pdf_cms.pyrB   Q   s   
rB   c                   @   s$   e Zd ZU dZdZeej ed< dS )r7   z
    .. versionadded:: 0.7.0

    .. versionchanged:: 0.14.0
        Split off some fields into :class:`.CMSSignedAttributes`.


    Serialisable container class describing input for various signed attributes
    in a CMS object for a PDF signature.
    Nadobe_revinfo_attr)	rE   rF   rG   rH   rL   r   asn1_pdfRevocationInfoArchivalrI   rJ   rJ   rJ   rK   r7   f   s   
c                 C   s8   | p
ddi} t | tjr$| d j}n| dd}| |fS )Ncontent_typedata)
isinstancer   Sequencenativeget)encap_content_inforO   rJ   rJ   rK   _ensure_content_typey   s
    rV   )rO   c                 C   s*   |rdS t | tjr| j} | dkr&dS dS )NZv4rP   v1Zv3)rQ   r   ObjectIdentifierrS   )rO   Zhas_attribute_certsrJ   rJ   rK   _cms_version   s
    rY   )
input_datadigest_algorithmc           
      C   s   t t|}d }t| tjtjfrN|t| d  |rHd| d i}q| }nbt| trr||  |sd| d}n>|s| 	|}|| d|d}nt
|}tj|| ||d | }	||	fS )NcontentrO   rP   rO   r\   )max_read)r   ZHashr'   rQ   r   ContentInfoEncapsulatedContentInfoupdatebytesread	bytearrayr   Zchunked_digestfinalize)
rZ   r[   detached
chunk_sizer^   hrU   Zinput_bytesZtemp_bufdigest_bytesrJ   rJ   rK   _prepare_encap_content   s&    



rj   rJ   F)
attr_provsother_attrsdry_runreturnc                    sP   t |} fdd| D }t|D ] }|I dH }|dk	r$|| q$t|S )ac  
    Format CMS attributes obtained from attribute providers.

    :param attr_provs:
        List of attribute providers.
    :param other_attrs:
        Other (predetermined) attributes to include.
    :param dry_run:
        Whether to invoke the attribute providers in dry-run mode or not.
    :return:
        A :class:`cms.CMSAttributes` value.
    c                    s   g | ]}|j  d qS )rm   )Zget_attribute).0Zprovro   rJ   rK   
<listcomp>   s     z%format_attributes.<locals>.<listcomp>N)listasyncioZas_completedappendr   CMSAttributes)rk   rl   rm   attrsjobsZ	attr_coroattrrJ   ro   rK   r8      s    
rP   )data_digestrk   rn   c                    s(   t d|t d| g}t|||dI dH S )a  
    Format signed attributes for a CMS ``SignerInfo`` value.

    :param data_digest:
        The byte string to put in the ``messageDigest`` attribute.
    :param attr_provs:
        List of attribute providers to source attributes from.
    :param content_type:
        The content type of the data being signed (default is ``data``).
    :param dry_run:
        Whether to invoke the attribute providers in dry-run mode or not.
    :return:
        A :class:`cms.CMSAttributes` value representing the signed attributes.
    rO   message_digest)rm   rl   N)r*   r8   )ry   rk   rO   rm   rv   rJ   rJ   rK   r9      s      c                   @   s  e Zd ZdZdddddddeeee eej ee	 e
ej dddZeee d	d
dZeeej d	ddZee	d	ddZee
ej d	ddZee edddZeee d	ddZedIee ee dddZdJedddZdKeeedddZdLee d d!d"ZdMeeejee d#d$d%Z ed&d'd(Z!eejeejej"d)d*d+Z#ed&d,d-Z$dNeeed.d/d0Z%dOeeejeej d1d2d3Z&dPeeee dd5d6Z'dQeeee ej"d7d8d9Z(dReejej"d;d<d=Z)ddde*j+ddfe,e-eej"ej.f eee ej"d>d?d@Z/dSeeee0 ee1 ej"dAdBdCZ2dTeejej"d;dDdEZ3ddddde*j+dfe,e-eej"ej.f eee0 ee1 ej"dFdGdHZ4dS )Ur4   a6	  
    Abstract signer object that is agnostic as to where the cryptographic
    operations actually happen.

    As of now, pyHanko provides two implementations:

    * :class:`.SimpleSigner` implements the easy case where all the key material
      can be loaded into memory.
    * :class:`~pyhanko.sign.pkcs11.PKCS11Signer` implements a signer that is
      capable of interfacing with a PKCS#11 device.

    :param prefer_pss:
        When signing using an RSA key, prefer PSS padding to legacy PKCS#1 v1.5
        padding. Default is ``False``. This option has no effect on non-RSA
        signatures.
    :param embed_roots:
        .. versionadded:: 0.9.0

        Option that controls whether or not additional self-signed certificates
        should be embedded into the CMS payload. The default is ``True``.

        .. note::
            The signer's certificate is always embedded, even if it is
            self-signed.

        .. note::
            Trust roots are configured by the validator, so embedding them
            doesn't affect the semantics of a typical validation process.
            Therefore, they can be safely omitted in most cases.
            Nonetheless, embedding the roots can be useful for documentation
            purposes. In addition, some validators are poorly implemented,
            and will refuse to build paths if the roots are not present
            in the file.

        .. warning::
            To be precise, if this flag is ``False``, a certificate will be
            dropped if (a) it is not the signer's, (b) it is self-issued and
            (c) its subject and authority key identifiers match (or either is
            missing). In other words, we never validate the actual
            self-signature. This heuristic is sufficiently accurate
            for most applications.
    :param signature_mechanism:
        The (cryptographic) signature mechanism to use for all signing
        operations. If unset, the default behaviour is to try to impute
        a reasonable one given the preferred digest algorithm and public key.
    :param signing_cert:
        See :attr:`signing_cert`.
    :param attribute_certs:
        See :attr:`attribute_certs`.
    :param cert_registry:
        Initial value for :attr:`cert_registry`. If unset, an empty certificate
        store will be initialised.
    FTNrJ   )
prefer_pssembed_rootssignature_mechanismsigning_certcert_registryattribute_certsc                C   s:   || _ || _d | _d | _|| _|| _|p,t | _|| _d S N)	r{   r|   signed_attr_prov_specunsigned_attr_prov_spec_signature_mechanism_signing_certr   _cert_registry_attribute_certs)selfr{   r|   r}   r~   r   r   rJ   rJ   rK   __init__*  s    
zSigner.__init__)rn   c                 C   s   | j S )z
        .. versionchanged:: 0.18.0
            Turned into a property instead of a class attribute.

        The (cryptographic) signature mechanism to use for all signing
        operations.
        )r   r   rJ   rJ   rK   r}   ?  s    	zSigner.signature_mechanismc                 C   s   | j S )a  
        .. versionchanged:: 0.14.0
            Made optional (see note)

        .. versionchanged:: 0.18.0
            Turned into a property instead of a class attribute.

        The certificate that will be used to create the signature.

        .. note::
            This is an optional field only to a limited extent. Subclasses may
            require it to be present, and not setting it at the beginning of
            the signing process implies that certain high-level convenience
            features will no longer work or be limited in function (e.g.,
            automatic hash selection, appearance generation, revocation
            information collection, ...).

            However, making :attr:`signing_cert` optional enables certain
            signing workflows where the certificate of the signer is not known
            until the signature has actually been produced. This is most
            relevant in certain types of remote signing scenarios.
        )r   r   rJ   rJ   rK   r~   J  s    zSigner.signing_certc                 C   s   | j S )a  
        .. versionchanged:: 0.18.0
            Turned into a property instead of a class attribute.

        Collection of certificates associated with this signer.
        Note that this is simply a bookkeeping tool; in particular it
        doesn't care about trust.
        )r   r   rJ   rJ   rK   r   d  s    
zSigner.cert_registryc                 C   s   | j S )z
        .. versionchanged:: 0.18.0
            Turned into a property instead of a class attribute.

        Attribute certificates to include with the signature.

        .. note::
            Only ``v2`` attribute certificates are supported.
        )r   r   rJ   rJ   rK   r   p  s    zSigner.attribute_certs)r[   rn   c                 C   s   | j dk	r| j S | jdkr"td| jjj}d}|dkrR|dkrHtd|d }n|dkrt|dkrjtd|d }nf|d	kr| jrd
}|dkrtdt| j|}q|dk	r|d }qd}n|dkr|}ntd| dd|i}|dk	r||d< t|S )a  
        Get the signature mechanism for this signer to use.
        If :attr:`signature_mechanism` is set, it will be used.
        Otherwise, this method will attempt to put together a default
        based on mechanism used in the signer's certificate.

        :param digest_algorithm:
            Digest algorithm to use as part of the signature mechanism.
            Only used if a signature mechanism object has to be put together
            on-the-fly.
        :return:
            A :class:`.SignedDigestAlgorithm` object.
        Nz/Could not set up a default signature mechanism.ecz#Digest algorithm required for ECDSAZ_ecdsadsaz!Digest algorithm required for DSAZ_dsarsa
rsassa_pssz(Digest algorithm required for RSASSA-PSSZ_rsarsassa_pkcs1v15)ed25519ed448zSignature mechanism z is unsupported.	algorithm
parameters)	r}   r~   r%   Z
public_keyr   
ValueErrorr{   r(   r   )r   r[   algoparamsmechZ
sda_kwargsrJ   rJ   rK   "get_signature_mechanism_for_digest}  s@    





z)Signer.get_signature_mechanism_for_digestc                 C   sx   | j dkrdS | j j}z|jd }W n tk
rB   |jd }Y nX z|jd }d||f }W n tk
rr   Y nX |S )z
        :return:
            The subject's common name as a string, extracted from
            :attr:`signing_cert`, or ``None`` if no signer's certificate is
            available
        NZcommon_nameZorganization_nameZemail_addressz%s <%s>)r~   subjectrS   KeyError)r   nameresultemailrJ   rJ   rK   subject_name  s    

zSigner.subject_name)ocsp_responsescrlsc                 C   s.   i }| r| |d< |r||d< |r*t |S dS )z
        Format Adobe-style revocation information for inclusion into a CMS
        object.

        :param ocsp_responses:
            A list of OCSP responses to include.
        :param crls:
            A list of CRLs to include.
        ZocspZcrlN)rM   rN   )r   r   Zrevinfo_dictrJ   rJ   rK   format_revinfo  s    zSigner.format_revinfo)attr_settingsc                 C   sV   | j dk	r| j S |r&t|| j||dS |r>t|| j| j|dS t|| j| j|dS dS )zs
        Internal method to select a default attribute provider spec if none
        is available already.
        Nr   r~   is_padestimestamperr   r~   r}   r   )r    CAdESSignedAttributeProviderSpecr~   %GenericPdfSignedAttributeProviderSpecr   %GenericCMSSignedAttributeProviderSpec)r   r   r   	use_cades
is_pdf_sigrJ   rJ   rK   _signed_attr_provider_spec  s,    
z!Signer._signed_attr_provider_spec)ry   r[   r   c                 C   s    | j ||||d}|j||dS )zN
        Prepare "standard" signed attribute providers. Internal API.
        )r   r   r   r   ry   r[   )r   signed_attr_providers)r   ry   r[   r   r   r   r   specrJ   rJ   rK   _signed_attr_providers  s    zSigner._signed_attr_providersr   c                 C   s   | j d k	r| j S t|dS d S )Nr   )r   DefaultUnsignedAttributesr   r   rJ   rJ   rK   _unsigned_attr_provider_spec*  s    
z#Signer._unsigned_attr_provider_spec)r[   	signaturesigned_attrsr   c                 C   s   |  |}|j|||dS )zP
        Prepare "standard" unsigned attribute providers. Internal API.
        )r[   r   r   )r   unsigned_attr_providers)r   r[   r   r   r   r   rJ   rJ   rK   _unsigned_attr_providers2  s    

zSigner._unsigned_attr_providers)r[   c                 C   s`   t d|i}| j}|dkr$tdtdtdt|j|j	di|| 
|||d}|S )a  
        Format the ``SignerInfo`` entry for a CMS signature.

        :param digest_algorithm:
            Digest algorithm to use.
        :param signed_attrs:
            Signed attributes (see :meth:`signed_attrs`).
        :param signature:
            The raw signature to embed (see :meth:`sign_raw`).
        :return:
            An :class:`.asn1crypto.cms.SignerInfo` object.
        r   NzNThe signer's certificate must be available for SignerInfo assembly to proceed.rW   Zissuer_and_serial_number)issuerserial_number)versionZsidr[   signature_algorithmr   r   )r
   DigestAlgorithmr~   r%   r   Z
SignerInfoZSignerIdentifierZIssuerAndSerialNumberr   r   r   )r   r[   r   r   digest_algorithm_objr~   sig_inforJ   rJ   rK   signer_infoC  s8     
zSigner.signer_info)r[   r   r   unsigned_attrsrn   c                C   s   |p
ddi}t d|i}| |||}|d k	r8||d< | jp@d}	| jrXdd |	D }
ndd |	D }
|
tjd	| jd
 | j	D ]}|
tjd|d
 q|t
|f||
|gd}ttdt|dS )NrO   rP   r   r   rJ   c                 S   s   h | ]}t jd |dqS )certificater   value)r   CertificateChoicesrp   certrJ   rJ   rK   	<setcomp>  s   z,Signer._package_signature.<locals>.<setcomp>c                 S   s$   h | ]}|j d krtjd|dqS )nor   r   )Zself_signedr   r   r   rJ   rJ   rK   r     s   
r   r   Zv2_attr_cert)r   Zdigest_algorithmsrU   ZcertificatesZsigner_infossigned_datar]   )r
   r   r   r   r|   addr   r   r~   r   ZDigestAlgorithmsr_   ZContentTypeZ
SignedData)r   r[   cms_versionr   r   r   rU   r   r   r   certsacr   rJ   rJ   rK   _package_signatures  s>    




zSigner._package_signaturec                 C   s   d }z|  d }W n tk
r*   d }Y nX z|d k	r>t|}W n tk
rT   Y nX |d k	r|||kr|td| d| dd S )Nz6Selected signature mechanism specifies message digest z, but z was requested.)r   r   r&   r%   )r   r[   Zimplied_hash_algor   rJ   rJ   rK   _check_digest_algorithm  s"    
zSigner._check_digest_algorithmrP   r[   rn   c                    s   t dS )aW  
        Compute the raw cryptographic signature of the data provided, hashed
        using the digest algorithm provided.

        :param data:
            Data to sign.
        :param digest_algorithm:
            Digest algorithm to use.

            .. warning::
                If :attr:`signature_mechanism` also specifies a digest, they
                should match.
        :param dry_run:
            Do not actually create a signature, but merely output placeholder
            bytes that would suffice to contain an actual signature.
        :return:
            Signature bytes.
        N)NotImplementedErrorr   rP   r[   rm   rJ   rJ   rK   async_sign_raw  s    zSigner.async_sign_raw)r[   r   r   rn   c                    s0   | j ||||d}tt||dI dH }|p.dS )a  
        .. versionchanged:: 0.9.0
            Made asynchronous _(breaking change)_

        .. versionchanged:: 0.14.0
            Added ``signed_attrs`` parameter _(breaking change)_

        Compute the unsigned attributes to embed into the CMS object.
        This function is called after signing the hash of the signed attributes
        (see :meth:`signed_attrs`).

        By default, this method only handles timestamp requests, but other
        functionality may be added by subclasses

        If this method returns ``None``, no unsigned attributes will be
        embedded.

        :param digest_algorithm:
            Digest algorithm used to hash the signed attributes.
        :param signed_attrs:
            Signed attributes of the signature.
        :param signature:
            Signature of the signed attribute hash.
        :param timestamper:
            Timestamp supplier to use.
        :param dry_run:
            Flag indicating "dry run" mode. If ``True``, only the approximate
            size of the output matters, so cryptographic
            operations can be replaced by placeholders.
        :return:
            The unsigned attributes to add, or ``None``.
        )r   r   r[   r   ro   N)r   r8   rr   )r   r[   r   r   r   rm   provsrv   rJ   rJ   rK   r     s    (zSigner.unsigned_attrsrP   c	           
         s:   |pt  }| j||||||d}	t|t|	||dI dH S )a  
        .. versionchanged:: 0.4.0
            Added positional ``digest_algorithm`` parameter _(breaking change)_.
        .. versionchanged:: 0.5.0
            Added ``dry_run``, ``timestamper`` and ``cades_meta`` parameters.
        .. versionchanged:: 0.9.0
            Made asynchronous, grouped some parameters under ``attr_settings``
            _(breaking change)_

        Format the signed attributes for a CMS signature.

        :param data_digest:
            Raw digest of the data to be signed.
        :param digest_algorithm:
            .. versionadded:: 0.4.0

            Name of the digest algorithm used to compute the digest.
        :param use_pades:
            Respect PAdES requirements.
        :param dry_run:
            .. versionadded:: 0.5.0

            Flag indicating "dry run" mode. If ``True``, only the approximate
            size of the output matters, so cryptographic
            operations can be replaced by placeholders.
        :param attr_settings:
            :class:`.PdfCMSSignedAttributes` object describing the attributes
            to be added.
        :param timestamper:
            .. versionadded:: 0.5.0

            Timestamper to use when creating timestamp tokens.
        :param content_type:
            CMS content type of the encapsulated data. Default is `data`.

            .. danger::
                This parameter is internal API, and non-default values must not
                be used to produce PDF signatures.
        :param is_pdf_sig:
            Whether the signature being generated is for use in a PDF document.

            .. danger::
                This parameter is internal API.
        :return:
            An :class:`.asn1crypto.cms.CMSAttributes` object.
        )ry   r[   r   r   r   r   )rk   rO   rm   N)r7   r   r9   rr   )
r   ry   r[   r   rO   	use_padesr   rm   r   r   rJ   rJ   rK   r     s    :
	zSigner.signed_attrs)ry   r[   signed_attr_settingsrn   c	              
      sT   t |\}}	| j|||||||	|dI dH }
| j||
t|	t| j|||dI dH S )a  
        .. versionadded:: 0.9.0

        Produce a detached CMS signature from a raw data digest.

        :param data_digest:
            Digest of the actual content being signed.
        :param digest_algorithm:
            Digest algorithm to use. This should be the same digest method
            as the one used to hash the (external) content.
        :param dry_run:
            If ``True``, the actual signing step will be replaced with
            a placeholder.

            In a PDF signing context, this is necessary to estimate the size
            of the signature container before computing the actual digest of
            the document.
        :param signed_attr_settings:
            :class:`.PdfCMSSignedAttributes` object describing the attributes
            to be added.
        :param use_pades:
            Respect PAdES requirements.
        :param timestamper:
            :class:`~.timestamps.TimeStamper` used to obtain a trusted timestamp
            token that can be embedded into the signature container.

            .. note::
                If ``dry_run`` is true, the timestamper's
                :meth:`~.timestamps.TimeStamper.dummy_response` method will be
                called to obtain a placeholder token.
                Note that with a standard :class:`~.timestamps.HTTPTimeStamper`,
                this might still hit the timestamping server (in order to
                produce a realistic size estimate), but the dummy response will
                be cached.
        :param is_pdf_sig:
            Whether the signature being generated is for use in a PDF document.

            .. danger::
                This parameter is internal API.
        :param encap_content_info:
            Data to encapsulate in the CMS object.

            .. danger::
                This parameter is internal API, and must not be used to produce
                PDF signatures.
        :return:
            An :class:`~.asn1crypto.cms.ContentInfo` object.
        )r   r   r   rm   rO   r   N)r   rm   r   rU   )rV   r    async_sign_prescribed_attributesrY   boolr   )r   ry   r[   rm   r   r   r   r   rU   rO   r   rJ   rJ   rK   
async_signa  s*    <
zSigner.async_signrW   )r[   r   rn   c           	         s^   |  }| | | | |  |I dH }| j|||||dI dH }| j||||||dS )a  
        .. versionadded:: 0.9.0

        Start the CMS signing process with the prescribed set of signed
        attributes.

        :param digest_algorithm:
            Digest algorithm to use. This should be the same digest method
            as the one used to hash the (external) content.
        :param signed_attrs:
            CMS attributes to sign.
        :param dry_run:
            If ``True``, the actual signing step will be replaced with
            a placeholder.

            In a PDF signing context, this is necessary to estimate the size
            of the signature container before computing the actual digest of
            the document.
        :param timestamper:
            :class:`~.timestamps.TimeStamper` used to obtain a trusted timestamp
            token that can be embedded into the signature container.

            .. note::
                If ``dry_run`` is true, the timestamper's
                :meth:`~.timestamps.TimeStamper.dummy_response` method will be
                called to obtain a placeholder token.
                Note that with a standard :class:`~.timestamps.HTTPTimeStamper`,
                this might still hit the timestamping server (in order to
                produce a realistic size estimate), but the dummy response will
                be cached.
        :param cms_version:
            CMS version to use.
        :param encap_content_info:
            Data to encapsulate in the CMS object.

            .. danger::
                This parameter is internal API, and must not be used to produce
                PDF signatures.
        :return:
            An :class:`~.asn1crypto.cms.ContentInfo` object.
        N)r   r   rm   )r[   r   r   r   r   rU   )lowerr   r   dumpr   r   )	r   r[   r   r   rm   r   rU   r   r   rJ   rJ   rK   r     s,    3
  
z'Signer.async_sign_prescribed_attributes)rZ   r[   r   rn   c	              	      s4   t |||||d\}	}
| j|
||d||	|dI dH S )a<	  
        .. versionadded:: 0.9.0

        Produce a CMS signature for an arbitrary data stream
        (not necessarily PDF data).

        :param input_data:
            The input data to sign. This can be either a :class:`bytes` object
            a file-type object, a :class:`cms.ContentInfo` object or
            a :class:`cms.EncapsulatedContentInfo` object.

            .. warning::
                ``asn1crypto`` mandates :class:`cms.ContentInfo` for CMS v1
                signatures. In practical terms, this means that you need to
                use :class:`cms.ContentInfo` if the content type is ``data``,
                and :class:`cms.EncapsulatedContentInfo` otherwise.

            .. warning::
                We currently only support CMS v1, v3 and v4 signatures.
                This is only a concern if you need certificates or CRLs
                of type 'other', in which case you can change the version
                yourself (this will not invalidate any signatures).
                You'll also need to do this if you need support for version 1
                attribute certificates, or if you want to sign with
                ``subjectKeyIdentifier`` in the ``sid`` field.
        :param digest_algorithm:
            The name of the digest algorithm to use.
        :param detached:
            If ``True``, create a CMS detached signature (i.e. an object where
            the encapsulated content is not embedded in the signature object
            itself). This is the default. If ``False``, the content to be
            signed will be embedded as encapsulated content.
        :param signed_attr_settings:
            :class:`.PdfCMSSignedAttributes` object describing the attributes
            to be added.
        :param use_cades:
            Construct a CAdES-style CMS object.
        :param timestamper:
            :class:`.PdfTimeStamper` to use to create a signature timestamp

            .. note::
                If you want to create a *content* timestamp (as opposed to
                a *signature* timestamp), see :class:`.CAdESSignedAttrSpec`.
        :param chunk_size:
            Chunk size to use when consuming input data.
        :param max_read:
            Maximal number of bytes to read from the input stream.
        :return:
            A CMS ContentInfo object of type signedData.
        )rZ   r[   rf   rg   r^   F)ry   r[   r   r   r   rU   r   N)rj   r   )r   rZ   r[   rf   r   r   rg   r   r^   rU   ri   rJ   rJ   rK   async_sign_general_data  s     @
zSigner.async_sign_general_data)ry   r[   	timestampcades_signed_attr_metarn   c
              	   C   s<   t dt t|||d}
| j||||||
|	d}t|S )a	  
        .. deprecated:: 0.9.0
            Use :meth:`async_sign` instead.
            The implementation of this method will invoke :meth:`async_sign`
            using ``asyncio.run()``.

        Produce a detached CMS signature from a raw data digest.

        :param data_digest:
            Digest of the actual content being signed.
        :param digest_algorithm:
            Digest algorithm to use. This should be the same digest method
            as the one used to hash the (external) content.
        :param timestamp:
            Signing time to embed into the signed attributes
            (will be ignored if ``use_pades`` is ``True``).

            .. note::
                This timestamp value is to be interpreted as an unfounded
                assertion by the signer, which may or may not be good enough
                for your purposes.
        :param dry_run:
            If ``True``, the actual signing step will be replaced with
            a placeholder.

            In a PDF signing context, this is necessary to estimate the size
            of the signature container before computing the actual digest of
            the document.
        :param revocation_info:
            Revocation information to embed; this should be the output
            of a call to :meth:`.Signer.format_revinfo`
            (ignored when ``use_pades`` is ``True``).
        :param use_pades:
            Respect PAdES requirements.
        :param timestamper:
            :class:`~.timestamps.TimeStamper` used to obtain a trusted timestamp
            token that can be embedded into the signature container.

            .. note::
                If ``dry_run`` is true, the timestamper's
                :meth:`~.timestamps.TimeStamper.dummy_response` method will be
                called to obtain a placeholder token.
                Note that with a standard :class:`~.timestamps.HTTPTimeStamper`,
                this might still hit the timestamping server (in order to
                produce a realistic size estimate), but the dummy response will
                be cached.
        :param cades_signed_attr_meta:
            .. versionadded:: 0.5.0

            Specification for CAdES-specific signed attributes.
        :param encap_content_info:
            Data to encapsulate in the CMS object.

            .. danger::
                This parameter is internal API, and must not be used to produce
                PDF signatures.
        :return:
            An :class:`~.asn1crypto.cms.ContentInfo` object.
        z<'Signer.sign' is deprecated, use 'Signer.async_sign' instead)rC   rL   rD   )ry   r[   rm   r   r   r   rU   )warningswarnDeprecationWarningr7   r   rs   run)r   ry   r[   r   rm   Zrevocation_infor   r   r   rU   r   	sign_cororJ   rJ   rK   signM  s&    G	zSigner.signc                 C   s,   t dt | j||||||d}t|S )a  
        .. versionadded: 0.7.0

        .. deprecated:: 0.9.0
            Use :meth:`async_sign_prescribed_attributes` instead.
            The implementation of this method will invoke
            :meth:`async_sign_prescribed_attributes` using
            ``asyncio.run()``.

        Start the CMS signing process with the prescribed set of signed
        attributes.

        :param digest_algorithm:
            Digest algorithm to use. This should be the same digest method
            as the one used to hash the (external) content.
        :param signed_attrs:
            CMS attributes to sign.
        :param dry_run:
            If ``True``, the actual signing step will be replaced with
            a placeholder.

            In a PDF signing context, this is necessary to estimate the size
            of the signature container before computing the actual digest of
            the document.
        :param timestamper:
            :class:`~.timestamps.TimeStamper` used to obtain a trusted timestamp
            token that can be embedded into the signature container.

            .. note::
                If ``dry_run`` is true, the timestamper's
                :meth:`~.timestamps.TimeStamper.dummy_response` method will be
                called to obtain a placeholder token.
                Note that with a standard :class:`~.timestamps.HTTPTimeStamper`,
                this might still hit the timestamping server (in order to
                produce a realistic size estimate), but the dummy response will
                be cached.
        :param cms_version:
            CMS version to use.
        :param encap_content_info:
            Data to encapsulate in the CMS object.

            .. danger::
                This parameter is internal API, and must not be used to produce
                PDF signatures.
        :return:
            An :class:`~.asn1crypto.cms.ContentInfo` object.
        zh'Signer.sign_prescribed_attributes' is deprecated, use 'Signer.async_sign_prescribed_attributes' instead)r[   r   r   rm   r   rU   )r   r   r   r   rs   r   )r   r[   r   r   rm   r   rU   r   rJ   rJ   rK   sign_prescribed_attributes  s    8z!Signer.sign_prescribed_attributes)rZ   r[   r   r   rn   c
              
   C   s<   t dt t||d}
| j|||||||
|	d}t|S )aT  
        .. versionadded:: 0.7.0

        .. deprecated:: 0.9.0
            Use :meth:`async_sign_general_data` instead.
            The implementation of this method will invoke
            :meth:`async_sign_general_data` using ``asyncio.run()``.

        Produce a CMS signature for an arbitrary data stream
        (not necessarily PDF data).


        :param input_data:
            The input data to sign. This can be either a :class:`bytes` object
            a file-type object, a :class:`cms.ContentInfo` object or
            a :class:`cms.EncapsulatedContentInfo` object.

            .. warning::
                ``asn1crypto`` mandates :class:`cms.ContentInfo` for CMS v1
                signatures. In practical terms, this means that you need to
                use :class:`cms.ContentInfo` if the content type is ``data``,
                and :class:`cms.EncapsulatedContentInfo` otherwise.

            .. warning::
                We currently only support CMS v1, v3 and v4 signatures.
                This is only a concern if you need certificates or CRLs
                of type 'other', in which case you can change the version
                yourself (this will not invalidate any signatures).
                You'll also need to do this if you need support for version 1
                attribute certificates, or if you want to sign with
                ``subjectKeyIdentifier`` in the ``sid`` field.
        :param digest_algorithm:
            The name of the digest algorithm to use.
        :param detached:
            If ``True``, create a CMS detached signature (i.e. an object where
            the encapsulated content is not embedded in the signature object
            itself). This is the default. If ``False``, the content to be
            signed will be embedded as encapsulated content.

        :param timestamp:
            Signing time to embed into the signed attributes
            (will be ignored if ``use_cades`` is ``True``).

            .. note::
                This timestamp value is to be interpreted as an unfounded
                assertion by the signer, which may or may not be good enough
                for your purposes.
        :param use_cades:
            Construct a CAdES-style CMS object.
        :param timestamper:
            :class:`.PdfTimeStamper` to use to create a signature timestamp

            .. note::
                If you want to create a *content* timestamp (as opposed to
                a *signature* timestamp), see :class:`.CAdESSignedAttrSpec`.
        :param cades_signed_attr_meta:
            Specification for CAdES-specific signed attributes.
        :param chunk_size:
            Chunk size to use when consuming input data.
        :param max_read:
            Maximal number of bytes to read from the input stream.
        :return:
            A CMS ContentInfo object of type signedData.
        zV'Signer.sign_general_data' is deprecated, use 'Signer.async_sign_general_data' instead)rC   rD   )rZ   r[   rf   r   r   rg   r   r^   )r   r   r   r7   r   rs   r   )r   rZ   r[   rf   r   r   r   r   rg   r^   r   r   rJ   rJ   rK   sign_general_data  s&    N 
zSigner.sign_general_data)NN)NFT)NFT)N)N)F)NF)NrP   FNFT)FFNNTN)rW   FNN)NFNFNNN)rW   FNN)5rE   rF   rG   rH   r   r   r   r   Certificater   r   r   AttributeCertificateV2r   propertyr}   r~   r   r   strr   r   staticmethodrr   r   r7   r   rb   r   r+   r   ru   r   r   r_   r   r   r   r   r   r   r   r   DEFAULT_CHUNK_SIZEr	   r   r`   r   r   r!   r   r   r   rJ   rJ   rJ   rK   r4      sN  9
A       )     3=    5      P      V    OU       _    Mc                    s"   dt tt d fdd}| _ S )zm
    Decorator to turn a legacy :class:`Signer` subclass into one that works
    with the new async API.
    Fr   c                    s"   t  fdd}|I d H S )Nc                      s   j  dS )N)rP   r[   rm   sign_rawrJ   )rP   r[   rm   r   
signer_clsrJ   rK   <lambda>\  s
   z9asyncify_signer.<locals>.async_sign_raw.<locals>.<lambda>r   )r   rP   r[   rm   coror   )rP   r[   rm   r   rK   r   X  s    z'asyncify_signer.<locals>.async_sign_raw)F)rb   r   r   )r   r   rJ   r   rK   r:   R  s      c                
       s   e Zd ZU dZejed< dejeje	e
e eee
eej  d fddZdeeed	d
dZeeed	ddZedddZedddZedddZ  ZS )r5   z_
    Simple signer implementation where the key material is available in local
    memory.
    signing_keyNFT)r~   r   r   r}   r{   r|   r   c                    s2   || _ t j|||||d |d k	r.t|| _d S )N)r{   r|   r   r}   r~   )r   superr   rr   r   )r   r~   r   r   r}   r{   r|   r   	__class__rJ   rK   r   t  s    
zSimpleSigner.__init__r   c                    s   |  ||S r   r   r   rJ   rJ   rK   r     s    zSimpleSigner.async_sign_rawc           	      C   sF  |  |}|j}tj| j dd}|dkrVt }t|}t|t	sHt
||||S |dkr|d }t||\}}t|t	st
||||S |dkrt|}t|tst
|j|t|dS |dkrt|}t|tst
|||S |d	krt|tst
||S |d
kr2t|ts(t
||S td| ddS )a1  
        Synchronous raw signature implementation.

        :param data:
            Data to be signed.
        :param digest_algorithm:
            Digest algorithm to use.
        :return:
            Raw signature encoded according to the conventions of the
            signing algorithm used.
        N)passwordr   r   r   Zecdsa)r   r   r   r   zThe signature mechanism z is unsupported by this signer.)r   signature_algor   Zload_der_private_keyr   r   r   r'   rQ   r   AssertionErrorr   r)   r   r   r   r   r   r%   )	r   rP   r[   r}   Z	mechanismZpriv_keypaddingZ	hash_algor   rJ   rJ   rK   r     sF     




zSimpleSigner.sign_rawc              
   C   sN   zt t|W S  ttfk
rH } ztjd|d W Y d S d }~X Y nX d S )NzCould not load CA chainexc_info)setr0   IOErrorr   loggererror)clsca_chain_fileserJ   rJ   rK   _load_ca_chain  s
    zSimpleSigner._load_ca_chainc              
   C   s4  z"t |d}| }W 5 Q R X W n> tk
r` }	 z tjd| d|	d W Y dS d}	~	X Y nX |rp| |nt }
|
dkrdS zt||\}}}W n< tt	t
fk
r }	 ztjd|	d W Y dS d}	~	X Y nX t|}t|}ttt|}t }|
|B }|dk	r|t|O }|| t|||||dS )a  
        Load certificates and key material from a PCKS#12 archive
        (usually ``.pfx`` or ``.p12`` files).

        :param pfx_file:
            Path to the PKCS#12 archive.
        :param ca_chain_files:
            Path to (PEM/DER) files containing other relevant certificates
            not included in the PKCS#12 file.
        :param other_certs:
            Other relevant certificates, specified as a list of
            :class:`.asn1crypto.x509.Certificate` objects.
        :param passphrase:
            Passphrase to decrypt the PKCS#12 archive, if required.
        :param signature_mechanism:
            Override the signature mechanism to use.
        :param prefer_pss:
            Prefer PSS signature mechanism over RSA PKCS#1 v1.5 if
            there's a choice.
        :return:
            A :class:`.SimpleSigner` object initialised with key material loaded
            from the PKCS#12 file provided.
        rbzCould not open PKCS#12 file .r   Nz-Could not load key material from PKCS#12 file)r   r~   r   r}   r{   )openrc   r   r   r  r  r   r   Zload_key_and_certificatesr   	TypeErrorr.   r-   mapr   register_multipler5   )r  pfx_filer  other_certs
passphraser}   r{   fZ	pfx_bytesr  ca_chainZprivate_keyr   Zother_certs_pkcs12ZkinfocsZcerts_to_registerrJ   rJ   rK   load_pkcs12  sP    #
 

zSimpleSigner.load_pkcs12c              
   C   s   zt ||d}t|}	W n< tttfk
rT }
 ztjd|
d W Y dS d}
~
X Y nX |rd| |ng }|dkrtdS |dkr|n|| }t }|	| t
|	||||dS )a  
        Load certificates and key material from PEM/DER files.

        :param key_file:
            File containing the signer's private key.
        :param cert_file:
            File containing the signer's certificate.
        :param ca_chain_files:
            File containing other relevant certificates.
        :param key_passphrase:
            Passphrase to decrypt the private key (if required).
        :param other_certs:
            Other relevant certificates, specified as a list of
            :class:`.asn1crypto.x509.Certificate` objects.
        :param signature_mechanism:
            Override the signature mechanism to use.
        :param prefer_pss:
            Prefer PSS signature mechanism over RSA PKCS#1 v1.5 if
            there's a choice.
        :return:
            A :class:`.SimpleSigner` object initialised with key material loaded
            from the files provided.
        )r  z%Could not load cryptographic materialr   N)r~   r   r   r}   r{   )r1   r/   r   r   r	  r   r  r  r   r  r5   )r  key_file	cert_filer  key_passphraser  r}   r{   r   r~   r  r  Zcert_regrJ   rJ   rK   load  s.    " 
zSimpleSigner.load)NFTN)F)N)NNNNF)NNNNF)rE   rF   rG   rH   r   ZPrivateKeyInforI   r   r   r   r   r   r   r   r   r   r   rb   r   r   r   classmethodr  r  r  __classcell__rJ   rJ   r   rK   r5   i  sL   


      2     L     )configprovided_pfx_passphrasec                 C   s6   | j p|}tj| j|| j| jd}|d kr2td|S )N)r  r  r  r{    Error while loading key material)Zpfx_passphraser5   r  r  r  r{   r>   )r  r  r  r   rJ   rJ   rK   r<   T  s    
)r  provided_key_passphrasec                 C   s:   | j p|}tj| j| j| j| j|d}|d kr6td|S )N)r  r  r  r{   r  r  )r  r5   r  r  r  r  r{   r>   )r  r  r  r   rJ   rJ   rK   r=   d  s    
c                       s^   e Zd ZdZdeej ee ee	e
df ee eed fddZde	ee	dd	d
Z  ZS )r6   a)  
    Class to help formatting CMS objects for use with remote signing.
    It embeds a fixed signature value into the CMS, set at initialisation.

    Intended for use with :ref:`interrupted-signing`.

    :param signing_cert:
        The signer's certificate.
    :param cert_registry:
        The certificate registry to use in CMS generation.
    :param signature_value:
        The value of the signature as a byte string, a placeholder length,
        or ``None``.
    :param signature_mechanism:
        The signature mechanism used by the external signing service.
    :param prefer_pss:
        Switch to prefer PSS when producing RSA signatures, as opposed to
        RSA with PKCS#1 v1.5 padding.
    :param embed_roots:
        Whether to embed relevant root certificates into the CMS payload.
    NFT)r~   r   signature_valuer}   r{   r|   c                    s:   t |tr|| _nt|pd| _t j|||||d d S )N   )r{   r|   r~   r   r}   )rQ   rb   _signature_valuer   r   )r   r~   r   r  r}   r{   r|   r   rJ   rK   r     s    	
zExternalSigner.__init__r   c                    s   | j S )z1
        Return a fixed signature value.
        )r  r   rJ   rJ   rK   r     s    zExternalSigner.async_sign_raw)NNFT)F)rE   rF   rG   rH   r   r   r   r   r	   rb   intr   r   r   r   r   r  rJ   rJ   r   rK   r6   u  s&         c                   @   sX   e Zd ZdZeeej ee	e
gejf df ee dddZee
ee dddZdS )	r   zD
    Signed attribute provider spec for generic CMS signatures.
    Nr   c                 C   s   || _ || _|| _|| _d S r   )r~   r   r}   r   r   r   r~   r}   r   rJ   rJ   rK   r     s    	z.GenericCMSSignedAttributeProviderSpec.__init__ry   r[   rn   c                 c   s   | j }| jd k	r tj| jdV  |j}|d k	r<tj|dV  |jd k	r`|jj||| jdE d H  | j	d k	r| 	|}tj
||dV  d S )Nr~   r   rz   Zmd_algorithmr   )Zdigest_algor   )r   r~   r    SigningCertificateV2ProviderrC   SigningTimeProviderrD   prepare_providersr   r}   ZCMSAlgorithmProtectionProvider)r   ry   r[   r   rC   r   rJ   rJ   rK   r     s(    



 z;GenericCMSSignedAttributeProviderSpec.signed_attr_providers)rE   rF   rG   rH   rB   r   r   r   r	   r   r   r
   r   r+   r   rb   r   r"   r   rJ   rJ   rJ   rK   r     s    r   c                       sd   e Zd ZdZeeej ee	e
gejf df ee d fddZee
ee d fddZ  ZS )	r   zD
    Signed attribute provider spec for generic PDF signatures.
    Nr   c                    s   t  j||||d d S )Nr   )r   r   r!  r   rJ   rK   r     s    	z.GenericPdfSignedAttributeProviderSpec.__init__r"  c                 #   sH   t  j||dE d H  | j}t|ts*t|jd k	rDtj|jdV  d S )Nr   )r   )	r   r   r   rQ   r7   r   rL   r    ZAdobeRevinfoProvider)r   ry   r[   r   r   rJ   rK   r     s     
z;GenericPdfSignedAttributeProviderSpec.signed_attr_providers)rE   rF   rG   rH   r7   r   r   r   r	   r   r   r
   r   r+   r   rb   r   r"   r   r  rJ   rJ   r   rK   r     s    r   c                   @   s@   e Zd ZdZeejeee	 dddZ
eeee dddZdS )	r   zH
    Signed attribute provider spec for CAdES and PAdES signatures.
    r   c                 C   s   || _ || _|| _|| _d S r   )r~   r   r   r   )r   r   r~   r   r   rJ   rJ   rK   r     s    z)CAdESSignedAttributeProviderSpec.__init__r"  c                 c   sz   t j| jdV  | j}| jsP|j}|d kr:tjt	 d}|d k	rPt j
|dV  |j}|d k	rv|j||| jdE d H  d S )Nr#  )tzr$  r%  )r    r&  r~   r   r   rC   r   nowtzlocalZget_localzoner'  rD   r(  r   )r   ry   r[   r   rC   Z
cades_metarJ   rJ   rK   r     s"    z6CAdESSignedAttributeProviderSpec.signed_attr_providersN)rE   rF   rG   rH   rB   r   r   r   r   r+   r   rb   r   r   r"   r   rJ   rJ   rJ   rK   r     s    r   c                   @   s<   e Zd ZdZee dddZeej	e
ee dddZdS )	r   z3
    Default unsigned attribute provider spec.
    r   c                 C   s
   || _ d S r   r   r   rJ   rJ   rK   r   -  s    z"DefaultUnsignedAttributes.__init__)r   r   r[   rn   c                 c   s$   | j }|d k	r tj|||dV  d S )N)r[   Z
data_to_tsr   )r   r    ZTSTProvider)r   r   r   r[   r   rJ   rJ   rK   r   0  s    z1DefaultUnsignedAttributes.unsigned_attr_providersN)rE   rF   rG   rH   r   r+   r   rb   r   ru   r   r   r"   r   rJ   rJ   rJ   rK   r   (  s   r   )i   sha256)i   sha384)r  r,  )i  r-  )keyrn   c                 C   sT   dd }| j }|dkr"|| jtS |dkr6|| jtS |dkrBdS |dkrNdS tjS )	a*  
    Choose a reasonable default signing message digest given the properties of
    (the public part of) a key.

    The fallback value is :const:`constants.DEFAULT_MD`.

    :param key:
        A :class:`keys.PublicKeyInfo` object.
    :return:
        The name of a message digest algorithm.
    c                 S   s"   |D ]\}}| |kr|  S qdS )Nsha512rJ   )Zkey_sizeZ
thresholdsszZmdrJ   rJ   rK   _with_thresholdsQ  s    
z4select_suitable_signing_md.<locals>._with_thresholdsr   r   r   r/  r   Zshake256)r   Zbit_sizeRSA_THRESHOLDSECC_THRESHOLDSr3   Z
DEFAULT_MD)r.  r1  Zkey_algorJ   rJ   rK   r;   D  s    )rJ   F)rP   F)N)N)prH   rs   loggingr   Zdataclassesr   r   typingr   r   r   r   r   r	   r+  Z
asn1cryptor
   r   r   r   r   rM   r   Zasn1crypto.algosr   Zcryptography.hazmat.primitivesr   r   Z-cryptography.hazmat.primitives.asymmetric.dsar   Z,cryptography.hazmat.primitives.asymmetric.ecr   r   Z/cryptography.hazmat.primitives.asymmetric.ed448r   Z1cryptography.hazmat.primitives.asymmetric.ed25519r   Z1cryptography.hazmat.primitives.asymmetric.paddingr   Z-cryptography.hazmat.primitives.asymmetric.rsar   Z,cryptography.hazmat.primitives.serializationr   Z%pyhanko_certvalidator._asyncio_compatr   Zpyhanko_certvalidator.registryr   r   Zpyhanko.pdf_utilsr   Zpyhanko.signr    Zpyhanko.sign.ades.apir!   Zpyhanko.sign.attributesr"   r#   r$   Zpyhanko.sign.generalr%   r&   r'   r(   r)   r*   Zpyhanko.sign.timestampsr+   r-   r.   r/   r0   r1    r3   __all__Zconfig.errorsr>   Zconfig.local_keysr?   r@   	getLoggerrE   r   rB   r7   rV   r   rX   rY   r   rb   r_   r`   rj   ru   r   r8   r9   r4   r:   r5   r<   r=   r6   r   r   r   r   r2  r3  ZPublicKeyInfor;   rJ   rJ   rJ   rK   <module>   s     
'            g n  50
%)