B
    ?[/                 @   s   d Z dZddgZddlT ejd dkr<ejd dkr<ddlT ddlZdd	lm	Z	m
Z
mZ dd
lmZ G dd dZdd Zdd Zdd ZdddZdS )a  RSA digital signature protocol with appendix according to PKCS#1 PSS.

See RFC3447__ or the `original RSA Labs specification`__.

This scheme is more properly called ``RSASSA-PSS``.

For example, a sender may authenticate a message using SHA-1 and PSS like
this:

    >>> from Crypto.Signature import PKCS1_PSS
    >>> from Crypto.Hash import SHA
    >>> from Crypto.PublicKey import RSA
    >>> from Crypto import Random
    >>>
    >>> message = 'To be signed'
    >>> key = RSA.importKey(open('privkey.der').read())
    >>> h = SHA.new()
    >>> h.update(message)
    >>> signer = PKCS1_PSS.new(key)
    >>> signature = PKCS1_PSS.sign(key)

At the receiver side, verification can be done like using the public part of
the RSA key:

    >>> key = RSA.importKey(open('pubkey.der').read())
    >>> h = SHA.new()
    >>> h.update(message)
    >>> verifier = PKCS1_PSS.new(key)
    >>> if verifier.verify(h, signature):
    >>>     print "The signature is authentic."
    >>> else:
    >>>     print "The signature is not authentic."

:undocumented: __revision__, __package__

.. __: http://www.ietf.org/rfc/rfc3447.txt
.. __: http://www.rsa.com/rsalabs/node.asp?id=2125
z$Id$newPSS_SigScheme    )*      N)
ceil_shiftceil_divlong_to_bytes)strxorc               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )r   zKThis signature scheme can perform PKCS#1 PSS RSA signature or verification.c             C   s   || _ || _|| _dS )a!  Initialize this PKCS#1 PSS signature scheme object.
        
        :Parameters:
         key : an RSA key object
                If a private half is given, both signature and verification are possible.
                If a public half is given, only verification is possible.
         mgfunc : callable
                A mask generation function that accepts two parameters: a string to
                use as seed, and the lenth of the mask to generate, in bytes.
         saltLen : int
                Length of the salt, in bytes.
        N)_key_saltLen_mgfunc)selfkeymgfuncsaltLen r   9lib/python3.7/site-packages/Crypto/Signature/PKCS1_PSS.py__init__O   s    zPSS_SigScheme.__init__c             C   s
   | j  S )zCReturn True if this cipher object can be used for signing messages.)r   Zhas_private)r   r   r   r   can_sign`   s    zPSS_SigScheme.can_signc       
         s   | j j}| jdkr j}n| j}| jr.| j}n fdd}tjj| j j	}t
|d}t |d |||}| j |}td|t|  | }	|	S )aB  Produce the PKCS#1 PSS signature of a message.
    
        This function is named ``RSASSA-PSS-SIGN``, and is specified in
        section 8.1.1 of RFC3447.
    
        :Parameters:
         mhash : hash object
                The hash that was carried out over the message. This is an object
                belonging to the `Crypto.Hash` module.
   
        :Return: The PSS signature encoded as a string.
        :Raise ValueError:
            If the RSA key length is not sufficiently long to deal with the given
            hash algorithm.
        :Raise TypeError:
            If the RSA key has no private half.
    
        :attention: Modify the salt length and the mask generation function only
                    if you know what you are doing.
                    The receiver must use the same parameters too.
        Nc                s   t | | S )N)MGF1)xy)mhashr   r   <lambda>   s    z$PSS_SigScheme.sign.<locals>.<lambda>   r   r   )r   Z	_randfuncr   digest_sizer   CryptoUtilnumbersizenr   EMSA_PSS_ENCODEZdecryptbchrlen)
r   r   ZrandfuncsLenmgfmodBitskemmSr   )r   r   signd   s    

zPSS_SigScheme.signc       
         s   | j dkr j}n| j }| jr&| j}n fdd}tjj| jj}t	|d}t
||kr^dS | j|dd }t	|d d}td|t
|  | }yt ||d ||}	W n tk
r   dS X |	S )a  Verify that a certain PKCS#1 PSS signature is authentic.
    
        This function checks if the party holding the private half of the given
        RSA key has really signed the message.
    
        This function is called ``RSASSA-PSS-VERIFY``, and is specified in section
        8.1.2 of RFC3447.
    
        :Parameters:
         mhash : hash object
                The hash that was carried out over the message. This is an object
                belonging to the `Crypto.Hash` module.
         S : string
                The signature that needs to be validated.
    
        :Return: True if verification is correct. False otherwise.
        Nc                s   t | | S )N)r   )r   r   )r   r   r   r      s    z&PSS_SigScheme.verify.<locals>.<lambda>r   Fr   r   )r   r   r   r   r   r   r    r   r!   r   r$   Zencryptr#   EMSA_PSS_VERIFY
ValueError)
r   r   r+   r%   r&   r'   r(   r)   emLenresultr   )r   r   verify   s$    

zPSS_SigScheme.verifyN)__name__
__module____qualname____doc__r   r   r,   r1   r   r   r   r   r   L   s
   0c             C   s^   t d}x8tt||jD ]$}t|d}||| |   }qW t||ksRt|d| S )z,Mask Generation Function, described in B.2.1    N)	branger   r   r	   r   digestr$   AssertionError)ZmgfSeedZmaskLenhashTZcountercr   r   r   r      s    
r   c             C   s
  t |d}d}x$td| | D ]}|d? dB }q W || j| d k rNtdtd}|rj|dkrj||}| tdd |   | }	td|| | j d  td | }
||	 || j d }t|
|}tt	|d | @ |dd  }||	  td	 }|S )
a%  
    Implement the ``EMSA-PSS-ENCODE`` function, as defined
    in PKCS#1 v2.1 (RFC3447, 9.1.1).

    The original ``EMSA-PSS-ENCODE`` actually accepts the message ``M`` as input,
    and hash it internally. Here, we expect that the message has already
    been hashed instead.

    :Parameters:
     mhash : hash object
            The hash object that holds the digest of the message being signed.
     emBits : int
            Maximum length of the final encoding, in bits.
     randFunc : callable
            An RNG function that accepts as only parameter an int, and returns
            a string of random bytes, to be used as salt.
     mgf : callable
            A mask generation function that accepts two parameters: a string to
            use as seed, and the lenth of the mask to generate, in bytes.
     sLen : int
            Length of the salt, in bytes.

    :Return: An ``emLen`` byte long string that encodes the hash
            (with ``emLen = \ceil(emBits/8)``).

    :Raise ValueError:
        When digest or salt length are too big.
    r   r   r      r   z6Digest or salt length are too long for given key size.r6   N   )
r   r9   r   r.   r8   r   r#   r:   r
   bord)r   emBitsZrandFuncr&   r%   r/   lmaskisalthdbdbMaskmaskedDBr)   r   r   r   r"      s     
&
"r"   c             C   s`  t |d}d}x$td| | D ]}|d? dB }q W || j| d k rJdS t|dd d	krbdS |d|| j d  }||| j d d }	|t|d @ rdS ||	|| j d }
t||
}tt|d | @ |dd  }|td|| j | d  td sdS td
}|r,|| d }| 	tdd | 
  | 
 }|	|kr\dS dS )a  
    Implement the ``EMSA-PSS-VERIFY`` function, as defined
    in PKCS#1 v2.1 (RFC3447, 9.1.2).

    ``EMSA-PSS-VERIFY`` actually accepts the message ``M`` as input,
    and hash it internally. Here, we expect that the message has already
    been hashed instead.

    :Parameters:
     mhash : hash object
            The hash object that holds the digest of the message to be verified.
     em : string
            The signature to verify, therefore proving that the sender really signed
            the message that was received.
     emBits : int
            Length of the final encoding (em), in bits.
     mgf : callable
            A mask generation function that accepts two parameters: a string to
            use as seed, and the lenth of the mask to generate, in bytes.
     sLen : int
            Length of the salt, in bytes.

    :Return: 0 if the encoding is consistent, 1 if it is inconsistent.

    :Raise ValueError:
        When digest or salt length are too big.
    r   r   r   r?   r   FNr@   r6   T)r   r9   r   ordrA   r
   r#   
startswithr8   r   r:   )r   r)   rB   r&   r%   r/   rC   rD   rI   rF   rH   rG   rE   Zhpr   r   r   r-     s0    

"* "
r-   c             C   s   t | ||S )a  Return a signature scheme object `PSS_SigScheme` that
    can be used to perform PKCS#1 PSS signature or verification.

    :Parameters:
     key : RSA key object
        The key to use to sign or verify the message. This is a `Crypto.PublicKey.RSA` object.
        Signing is only possible if *key* is a private RSA key.
     mgfunc : callable
        A mask generation function that accepts two parameters: a string to
        use as seed, and the lenth of the mask to generate, in bytes.
        If not specified, the standard MGF1 is used.
     saltLen : int
        Length of the salt, in bytes. If not specified, it matches the output
        size of the hash function.
 
    )r   )r   r   r   r   r   r   r   Q  s    )NN)r5   Z__revision____all__ZCrypto.Util.py3compatsysversion_infoZCrypto.Util.py21compatZCrypto.Util.numberr   r   r   r	   ZCrypto.Util.strxorr
   r   r   r"   r-   r   r   r   r   r   <module><   s   }	;D