o
    5hjW                     @   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/   h/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/Crypto/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|rtddjjj	jjg}t| }d}n|rtdtttj|
}d}|dkr|S |dkrt||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:`Crypto.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:`Crypto.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 Crypto.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sJ |	|d  }
|	|
d  }|
 | krt||tkrn|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 st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:`Crypto.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rt| d dkrt| |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   Crypto.Util.py3compatr   r   r   r	   r
   Cryptor   	Crypto.IOr   r   Crypto.Hashr   Crypto.Util.asn1r   r   r   r   r   Crypto.Math.Numbersr   Crypto.Math.Primalityr   r   r   Crypto.PublicKeyr   r   r   objectr   r   r   r   r   r   r   r   r   r   	importKeyr   r/   r/   r/   r0   <module>   s4      
5
I8

G