o
    Þý°j¢W  ã                   @   s  g d ¢Z ddlZddlZddlZddlmZmZmZ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mZmZmZmZ ddlmZ dd	lmZmZmZ dd
lmZmZm Z  G dd„ de!ƒZ"dd„ Z#d!dd„Z$d"dd„Z%dd„ Z&dd„ Z'dd„ Z(dd„ Z)dd„ Z*d#dd„Z+e+Z,d Z-dS )$)ÚgenerateÚ	constructÚDsaKeyÚ
import_keyé    N)ÚbchrÚbordÚtobytesÚtostrÚ
iter_range)ÚRandom)ÚPKCS8ÚPEM)ÚSHA256)Ú	DerObjectÚDerSequenceÚ
DerIntegerÚDerObjectIdÚDerBitString)ÚInteger)Útest_probable_primeÚ	COMPOSITEÚPROBABLY_PRIME)Ú_expand_subject_public_key_infoÚ_create_subject_public_key_infoÚ _extract_subject_public_key_infoc                   @   sÎ   e Zd ZdZg 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dd„ Zdd„ Zdd„ Zdd„ Zdd„ Z		d/dd „ZeZeZd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ ZdS )0r   a¼  Class defining an actual DSA key.
    Do not instantiate directly.
    Use :func:`generate`, :func:`construct` or :func:`import_key` instead.

    :ivar p: DSA modulus
    :vartype p: integer

    :ivar q: Order of the subgroup
    :vartype q: integer

    :ivar g: Generator
    :vartype g: integer

    :ivar y: Public key
    :vartype y: integer

    :ivar x: Private key
    :vartype x: integer

    :undocumented: exportKey, publickey
    ©ÚyÚgÚpÚqÚxc                 C   sp   t | ¡ ƒ}t dƒ}| |¡stdt|| ƒ ƒ‚|| }|r1|t dƒkr1tdt|t dƒ ƒ ƒ‚t|ƒ| _d S )N©r   r   r   r   z$Some DSA components are missing = %s©r    zUnknown DSA components = %s)ÚsetÚkeysÚissubsetÚ
ValueErrorÚstrÚdictÚ_key)ÚselfÚkey_dictÚ	input_setÚ
public_setÚ	extra_set© r/   ú‹/root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/Cryptodome/PublicKey/DSA.pyÚ__init__g   s   

ÿÿzDsaKey.__init__c                    sª   ˆ   ¡ stdƒ‚d|  k rˆ jk stdƒ‚ tdƒ‚‡ fdd„dD ƒ\}}}}tjd|d�}||  |¡}|| }	t|||ƒ| }
||| |	|
   | }tt	|
|fƒS )Nz)DSA public key cannot be used for signingé   zk is not between 2 and q-1c                    ó   g | ]}ˆ j | ‘qS r/   ©r)   ©Ú.0Úcomp©r*   r/   r0   Ú
<listcomp>y   ó    z DsaKey._sign.<locals>.<listcomp>)r    r   r   r   )Úmin_inclusiveÚmax_exclusive)
Úhas_privateÚ	TypeErrorr   r&   r   Úrandom_rangeÚinverseÚpowÚmapÚint)r*   ÚmÚkr    r   r   r   Úblind_factorÚinv_blind_kÚblind_xÚrÚsr/   r8   r0   Ú_signs   s   ÿÿzDsaKey._signc                    s¦   |\}}‡ fdd„dD ƒ\}}}}d|  k r|k r*n dS d|  k r)|k s,dS  dS t |ƒ |¡}	|	| | }
|	| | }t||
|ƒt|||ƒ | | }||kS )Nc                    r3   r/   r4   r5   r8   r/   r0   r9   †   r:   z"DsaKey._verify.<locals>.<listcomp>)r   r   r   r   r   F)r   r@   rA   )r*   rD   ÚsigrI   rJ   r   r   r   r   ÚwÚu1Úu2Úvr/   r8   r0   Ú_verify„   s   ÿÿ zDsaKey._verifyc                 C   s
   d| j v S )z!Whether this is a DSA private keyr    r4   r8   r/   r/   r0   r=   �   s   
zDsaKey.has_privatec                 C   ó   dS )NFr/   r8   r/   r/   r0   Úcan_encrypt”   ó   zDsaKey.can_encryptc                 C   rR   )NTr/   r8   r/   r/   r0   Úcan_sign—   rT   zDsaKey.can_signc                    s   t ‡ fdd„dD ƒƒ}t|ƒS )z^A matching DSA public key.

        Returns:
            a new :class:`DsaKey` object
        c                 3   s   � | ]
}|ˆ j | fV  qd S ©Nr4   )r6   rE   r8   r/   r0   Ú	<genexpr>¡   s   € z$DsaKey.public_key.<locals>.<genexpr>r!   )r(   r   )r*   Úpublic_componentsr/   r8   r0   Ú
public_keyš   s   zDsaKey.public_keyc                 C   sP   t |  ¡ ƒt | ¡ ƒkrdS d}| jD ]}|o$t| j|d ƒt|j|d ƒk}q|S )NFT)Úboolr=   Ú_keydataÚgetattrr)   )r*   ÚotherÚresultr7   r/   r/   r0   Ú__eq__¤   s   
ÿzDsaKey.__eq__c                 C   s   |   |¡ S rV   )r_   )r*   r]   r/   r/   r0   Ú__ne__®   s   zDsaKey.__ne__c                 C   s   ddl m} |‚)Nr   )ÚPicklingError)Úpicklera   )r*   ra   r/   r/   r0   Ú__getstate__±   s   zDsaKey.__getstate__c                    s   ‡ fdd„dD ƒS )zPThe DSA domain parameters.

        Returns
            tuple : (p,q,g)
        c                    s   g | ]	}t ˆ j| ƒ‘qS r/   )rC   r)   r5   r8   r/   r0   r9   ½   ó    z!DsaKey.domain.<locals>.<listcomp>)r   r   r   r/   r8   r/   r8   r0   Údomain¶   s   zDsaKey.domainc                 C   sz   g }| j D ] }|dkrt| jƒ ¡ }| d|f ¡ qt| |ƒr%| |¡ q|  ¡ r/| d¡ d| jjt	| ƒd 
|¡f S )Nr   zp(%d)Úprivatez<%s @0x%x %s>ú,)r[   r   r   Úsize_in_bitsÚappendÚhasattrr=   Ú	__class__Ú__name__ÚidÚjoin)r*   ÚattrsrE   Úbitsr/   r/   r0   Ú__repr__¿   s   


€
zDsaKey.__repr__c                 C   s(   zt | j| ƒW S  ty   t|ƒ‚w rV   )rC   r)   ÚKeyErrorÚAttributeError)r*   Úitemr/   r/   r0   Ú__getattr__Ì   s
   ÿzDsaKey.__getattr__r   Nc                    s�  |durt |ƒ}|du rtj}|dkrC‡fdd„dD ƒ}dd„ ‰ ‡ fdd„|D ƒ}d	g| }d
 dd„ |D ƒ¡}	dt |	¡dd…  S tˆjˆjˆj	gƒ}
ˆ 
¡ r™|du rWd}|ry|s]d}tˆjƒ ¡ }tj|t|||
|d�}|rtd}nd}d}n1|dkrƒ|rƒtdƒ‚dˆjˆjˆj	ˆjˆjg}t|ƒ ¡ }d}n|rŸtdƒ‚tttˆjƒ|
ƒ}d}|dkr°|S |dkrÂt ||d ||¡}t |ƒS td| ƒ‚)a·  Export this DSA key.

        Args:
          format (string):
            The encoding for the output:

            - *'PEM'* (default). ASCII as per `RFC1421`_/ `RFC1423`_.
            - *'DER'*. Binary ASN.1 encoding.
            - *'OpenSSH'*. ASCII one-liner as per `RFC4253`_.
              Only suitable for public keys, not for private keys.

          passphrase (string):
            *Private keys only*. The pass phrase to protect the output.

          pkcs8 (boolean):
            *Private keys only*. If ``True`` (default), the key is encoded
            with `PKCS#8`_. If ``False``, it is encoded in the custom
            OpenSSL/OpenSSH container.

          protection (string):
            *Only in combination with a pass phrase*.
            The encryption scheme to use to protect the output.

            If :data:`pkcs8` takes value ``True``, this is the PKCS#8
            algorithm to use for deriving the secret and encrypting
            the private DSA key.
            For a complete list of algorithms, see :mod:`Cryptodome.IO.PKCS8`.
            The default is *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC*.

            If :data:`pkcs8` is ``False``, the obsolete PEM encryption scheme is
            used. It is based on MD5 for key derivation, and Triple DES for
            encryption. Parameter :data:`protection` is then ignored.

            The combination ``format='DER'`` and ``pkcs8=False`` is not allowed
            if a passphrase is present.

          randfunc (callable):
            A function that returns random bytes.
            By default it is :func:`Cryptodome.Random.get_random_bytes`.

        Returns:
          byte string : the encoded key

        Raises:
          ValueError : when the format is unknown or when you try to encrypt a private
            key with *DER* format and OpenSSL/OpenSSH.

        .. warning::
            If you don't provide a pass phrase, the private key will be
            exported in the clear!

        .. _RFC1421:    http://www.ietf.org/rfc/rfc1421.txt
        .. _RFC1423:    http://www.ietf.org/rfc/rfc1423.txt
        .. _RFC4253:    http://www.ietf.org/rfc/rfc4253.txt
        .. _`PKCS#8`:   http://www.ietf.org/rfc/rfc5208.txt
        NÚOpenSSHc                    s   g | ]	}ˆ j |  ¡ ‘qS r/   )r)   Úto_bytes©r6   r    r8   r/   r0   r9     rd   z%DsaKey.export_key.<locals>.<listcomp>)r   r   r   r   c                 S   s    t | d ƒd@ rtdƒ|  S | S )Nr   é€   )r   r   r"   r/   r/   r0   Úfunc  s   zDsaKey.export_key.<locals>.funcc                    s   g | ]}ˆ |ƒ‘qS r/   r/   rx   )rz   r/   r0   r9     ó    ó   ssh-dssó    c                 S   s    g | ]}t  d t|ƒ¡| ‘qS )ú>I)ÚstructÚpackÚlen)r6   Úkpr/   r/   r0   r9     ó     ó   ssh-dss éÿÿÿÿTz"PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC)Ú
key_paramsÚrandfunczENCRYPTED PRIVATEÚPRIVATEr   z#DSA private key cannot be encryptedr   zDSA PRIVATEz*PKCS#8 is only meaningful for private keysÚPUBLICÚDERz KEYz3Unknown key format '%s'. Cannot export the DSA key.)r   r   Úget_random_bytesrn   ÚbinasciiÚ
b2a_base64r   r   r   r   r=   r   r    Úencoder   ÚwrapÚoidr&   r   r   r   )r*   ÚformatÚpkcs8Ú
passphraseÚ
protectionr‡   Útup1Útup2ÚkeypartsÚ	keystringÚparamsÚprivate_keyÚ
binary_keyÚkey_typeÚintsÚpem_strr/   )rz   r*   r0   Ú
export_keyÒ   sd   ;
ÿý
ÿþzDsaKey.export_keyc                 C   ó   t dƒ‚©Nz+Use module Cryptodome.Signature.DSS instead©ÚNotImplementedError)r*   ÚMÚKr/   r/   r0   ÚsignU  ó   zDsaKey.signc                 C   r    r¡   r¢   )r*   r¤   Ú	signaturer/   r/   r0   ÚverifyX  r§   zDsaKey.verifyc                 C   ó   t ‚rV   r¢   )r*   Ú	plaintextr¥   r/   r/   r0   Úencrypt[  rT   zDsaKey.encryptc                 C   rª   rV   r¢   )r*   Ú
ciphertextr/   r/   r0   Údecrypt^  rT   zDsaKey.decryptc                 C   rª   rV   r¢   ©r*   r¤   ÚBr/   r/   r0   Úblinda  rT   zDsaKey.blindc                 C   rª   rV   r¢   r¯   r/   r/   r0   Úunblindd  rT   zDsaKey.unblindc                 C   rª   rV   r¢   r8   r/   r/   r0   Úsizeg  rT   zDsaKey.size)r   NNNN)rl   Ú
__module__Ú__qualname__Ú__doc__r[   r1   rK   rQ   r=   rS   rU   rY   r_   r`   rc   re   rq   ru   rŸ   Ú	exportKeyÚ	publickeyr¦   r©   r¬   r®   r±   r²   r³   r/   r/   r/   r0   r   N   s8    

	
ÿ~r   c                    s  ddddœ  | ¡}|du rtd|  ƒ‚tjd ‰| ˆ d ˆ d }| d |ˆ  }td	ƒ}d|d > }t||ƒtkrZ|d
ƒ‰t t ˆ¡ 	¡ ¡|d @ }||B dB }t||ƒtks;| 
¡ |ksbJ ‚d‰d| d > }	 ‡‡fdd„t|d ƒD ƒ‰ dd„ ˆ D ƒ‰ t‡ ‡fdd„t|ƒD ƒˆ | d|> d @ d|ˆ >  ƒ}t|| ƒ}	|	 
¡ | ks«J ‚|	|d  }
|	|
d  }| 
¡ | krÅt||ƒtkrÅnˆ|d 7 ‰qk|d | }t d¡D ]&}ˆd tdƒ t|ƒ ¡  }t t |¡ 	¡ ¡}t|||ƒ}|dkrý nq×|||ˆfS )z+Generate a new set of DSA domain parametersé    éà   é   )é   é   é   NzInvalid modulus length (%d)é   r2   é   é@   Tc                    s*   g | ]}t  ˆtˆ | ƒ ¡  ¡ ¡ ‘qS r/   )r   Únewr   rw   Údigest)r6   Új)ÚoffsetÚseedr/   r0   r9   „  s    "ÿz$_generate_domain.<locals>.<listcomp>c                 S   s   g | ]}t  |¡‘qS r/   ©r   Ú
from_bytes)r6   rP   r/   r/   r0   r9   †  r:   c                    s    g | ]}ˆ | d |ˆ >  ‘qS )r2   r/   )r6   Úi)ÚVÚoutlenr/   r0   r9   ‡  rƒ   é   s   ggen)Úgetr&   r   Údigest_sizer   r   r   rÈ   rÂ   rÃ   rh   r
   ÚsumÚ	itertoolsÚcountr   rw   rA   )ÚLr‡   ÚNÚnÚb_r   Ú	upper_bitÚUÚWÚXÚcr   ÚerÑ   r   r/   )rÊ   rÅ   rË   rÆ   r0   Ú_generate_domaink  sT   
ý
ÿÿñÿrÜ   c                 C   sH  |du rt j}|rDtt|ƒ\}}}t|ƒtk}|t|ƒtkO }||d | dkO }||dkp1||kO }|t|||ƒdkO }|rCtdƒ‚n	t| |ƒ\}}}}| 	¡ }| 	¡ }	|| kratd|| f ƒ‚||	fdvrotd||	f ƒ‚d|  k r||k s�tdƒ‚ tdƒ‚tj
|	d	 |d
�}
|
|d  d }t|||ƒ}|||||dœ}t|ƒS )aÚ  Generate a new DSA key pair.

    The algorithm follows Appendix A.1/A.2 and B.1 of `FIPS 186-4`_,
    respectively for domain generation and key pair generation.

    Args:
      bits (integer):
        Key length, or size (in bits) of the DSA modulus *p*.
        It must be 1024, 2048 or 3072.

      randfunc (callable):
        Random number generation function; it accepts a single integer N
        and return a string of random data N bytes long.
        If not specified, :func:`Cryptodome.Random.get_random_bytes` is used.

      domain (tuple):
        The DSA domain parameters *p*, *q* and *g* as a list of 3
        integers. Size of *p* and *q* must comply to `FIPS 186-4`_.
        If not specified, the parameters are created anew.

    Returns:
      :class:`DsaKey` : a new DSA key object

    Raises:
      ValueError : when **bits** is too little, too big, or not a multiple of 64.

    .. _FIPS 186-4: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
    Nr2   r   zInvalid DSA domain parametersz?Mismatch between size of modulus (%d) and 'bits' parameter (%d)))r¼   r¹   )r½   rº   )r½   r»   )r¾   r»   z;Lengths of p and q (%d, %d) are not compatibleto FIPS 186-3zIncorrent DSA generatorrÁ   )Ú
exact_bitsr‡   r   )r   r‹   rB   r   r   r   rA   r&   rÜ   rh   Úrandomr   )rp   r‡   re   r   r   r   Ú	fmt_errorÚ_rÒ   rÓ   rÚ   r    r   r+   r/   r/   r0   r      s@   ÿÿÿÿr   Tc                 C   sú   t tdtt| ƒƒƒ}t|ƒ}d}|rut|jƒtk}|t|jƒtkO }||jd |j dkO }||j	dkp9|j	|jkO }|t
|j	|j|jƒdkO }||jdkpS|j|jkO }t|dƒru||jdkpe|j|jkO }|t
|j	|j|jƒ|jkO }|r{tdƒ‚|S )a²  Construct a DSA key from a tuple of valid DSA components.

    Args:
      tup (tuple):
        A tuple of long integers, with 4 or 5 items
        in the following order:

            1. Public key (*y*).
            2. Sub-group generator (*g*).
            3. Modulus, finite field order (*p*).
            4. Sub-group order (*q*).
            5. Private key (*x*). Optional.

      consistency_check (boolean):
        If ``True``, the library will verify that the provided components
        fulfil the main DSA properties.

    Raises:
      ValueError: when the key being imported fails the most basic DSA validity checks.

    Returns:
      :class:`DsaKey` : a DSA key object
    r   Fr2   r   r    zInvalid DSA key components)r(   ÚziprB   r   r   r   r   r   r   r   rA   r   rj   r    r&   )ÚtupÚconsistency_checkr+   Úkeyrß   r/   r/   r0   r   é  s    
r   c                    sL   |rt dƒ‚tƒ j| ddd�‰ ˆ d dkrt dƒ‚‡ fdd„d	D ƒ}t|ƒS )
Nz-DSA private key already comes with parametersé   T)Únr_elementsÚonly_ints_expectedr   zNo version foundc                    s   g | ]}ˆ | ‘qS r/   r/   r5   ©Úderr/   r0   r9   '  r{   z+_import_openssl_private.<locals>.<listcomp>)rÀ   é   r2   rÌ   é   )r&   r   Údecoder   )Úencodedr“   r™   râ   r/   rè   r0   Ú_import_openssl_private!  s   rî   c                 C   sj   t | ƒ\}}}|tkrtdƒ‚|r|rtdƒ‚tƒ  |¡j}ttƒ  |p%|¡ƒ\}}}	||	||f}
t|
ƒS )NzNo DSA subjectPublicKeyInfozToo many DSA parameters)	r   r�   r&   r   rì   ÚvalueÚlistr   r   )rí   r“   r™   ÚalgoidÚencoded_keyÚ
emb_paramsr   r   r   r   râ   r/   r/   r0   Ú_import_subjectPublicKeyInfo+  s   rô   c                 C   s   t | ƒ}t|d |ƒS rV   )r   rô   )rí   r“   r™   Úsp_infor/   r/   r0   Ú_import_x509_cert9  s   rö   c           	      C   sv   |rt dƒ‚t | |¡}|d tkrt dƒ‚tƒ  |d ¡j}ttƒ  |d ¡ƒ\}}}t	|||ƒ||||f}t
|ƒS )Nz"PKCS#8 already includes parametersr   zNo PKCS#8 encoded DSA keyr2   rÌ   )r&   r   Úunwrapr�   r   rì   rï   rð   r   rA   r   )	rí   r“   r™   rE   r    r   r   r   râ   r/   r/   r0   Ú_import_pkcs8?  s   rø   c              	   C   sB   t tttf}|D ]}z	|| ||ƒW   S  ty   Y qw tdƒ‚)z?Import a DSA key (public or private half), encoded in DER form.úDSA key format is not supported)rî   rô   rö   rø   r&   )Úkey_datar“   r™   Ú	decodingsÚdecodingr/   r/   r0   Ú_import_key_derK  s   ýÿrý   c                    s  t | ƒ} |durt |ƒ}|  d¡r&t t| ƒ|¡\}}}|r d}t||dƒS |  d¡rut |  d¡d ¡}g ‰ t	|ƒdkrbt
 d|dd… ¡d }ˆ  |dd| … ¡ |d| d… }t	|ƒdks=ˆ d d	kru‡ fd
d„dD ƒ}t|ƒS t	| ƒdkr‰t| d ƒdkr‰t| |dƒS tdƒ‚)að  Import a DSA key.

    Args:
      extern_key (string or byte string):
        The DSA key to import.

        The following formats are supported for a DSA **public** key:

        - X.509 certificate (binary DER or PEM)
        - X.509 ``subjectPublicKeyInfo`` (binary DER or PEM)
        - OpenSSH (ASCII one-liner, see `RFC4253`_)

        The following formats are supported for a DSA **private** key:

        - `PKCS#8`_ ``PrivateKeyInfo`` or ``EncryptedPrivateKeyInfo``
          DER SEQUENCE (binary or PEM)
        - OpenSSL/OpenSSH custom format (binary or PEM)

        For details about the PEM encoding, see `RFC1421`_/`RFC1423`_.

      passphrase (string):
        In case of an encrypted private key, this is the pass phrase
        from which the decryption key is derived.

        Encryption may be applied either at the `PKCS#8`_ or at the PEM level.

    Returns:
      :class:`DsaKey` : a DSA key object

    Raises:
      ValueError : when the given key cannot be parsed (possibly because
        the pass phrase is wrong).

    .. _RFC1421: http://www.ietf.org/rfc/rfc1421.txt
    .. _RFC1423: http://www.ietf.org/rfc/rfc1423.txt
    .. _RFC4253: http://www.ietf.org/rfc/rfc4253.txt
    .. _PKCS#8: http://www.ietf.org/rfc/rfc5208.txt
    Ns   -----r„   ó    r2   rÀ   r~   r   r|   c                    s   g | ]	}t  ˆ | ¡‘qS r/   rÇ   rx   ©r—   r/   r0   r9   ˜  rd   zimport_key.<locals>.<listcomp>)rÀ   rê   r2   rÌ   é0   rù   )r   Ú
startswithr   rì   r	   rý   rŒ   Ú
a2b_base64Úsplitr�   r   Úunpackri   r   r   r&   )Ú
extern_keyr“   ré   ÚmarkerÚenc_flagr˜   Úlengthrâ   r/   rÿ   r0   r   \  s,   (

ýr   z1.2.840.10040.4.1)NN)TrV   ).Ú__all__rŒ   r   rÐ   ÚCryptodome.Util.py3compatr   r   r   r	   r
   Ú
Cryptodomer   ÚCryptodome.IOr   r   ÚCryptodome.Hashr   ÚCryptodome.Util.asn1r   r   r   r   r   ÚCryptodome.Math.Numbersr   ÚCryptodome.Math.Primalityr   r   r   ÚCryptodome.PublicKeyr   r   r   Úobjectr   rÜ   r   r   rî   rô   rö   rø   rý   r   Ú	importKeyr�   r/   r/   r/   r0   Ú<module>   s4      
5
I8

G