
    +a                     n    d dl Z ddlmZmZmZ ddlmZ ddlmZm	Z	m
Z
 dZdZdZdZd	Zd
 Z G d d      Zy)    N   )
Parameters_check_typesextract_parameters)InvalidHash)Typehash_secretverify_secret      i     c                 H    t        | t              r| S | j                  |      S )zM
    Ensure *s* is a bytes string.  Encode using *encoding* if it isn't.
    )
isinstancebytesencode)sencodings     9/usr/lib/python3/dist-packages/argon2/_password_hasher.py_ensure_bytesr      s"     !U88H    c                       e Zd ZdZddgZeeeee	de
j                  fdZed        Zed        Zed        Zed	        Zed
        Zed        Zd Ze
j*                  e
j,                  e
j                  dZd Zd Zy)PasswordHashera  
    High level class to hash passwords with sensible defaults.

    Uses Argon2\ **id** by default and always uses a random salt_ for hashing.
    But it can verify any type of Argon2 as long as the hash is correctly
    encoded.

    The reason for this being a class is both for convenience to carry
    parameters and to verify the parameters only *once*.  Any unnecessary
    slowdown when hashing is a tangible advantage for a brute force attacker.

    :param int time_cost: Defines the amount of computation realized and
        therefore the execution time, given in number of iterations.
    :param int memory_cost: Defines the memory usage, given in kibibytes_.
    :param int parallelism: Defines the number of parallel threads (*changes*
        the resulting hash value).
    :param int hash_len: Length of the hash in bytes.
    :param int salt_len: Length of random salt to be generated for each
        password.
    :param str encoding: The Argon2 C library expects bytes.  So if
        :meth:`hash` or :meth:`verify` are passed an unicode string, it will be
        encoded using this encoding.
    :param Type type: Argon2 type to use.  Only change for interoperability
        with legacy systems.

    .. versionadded:: 16.0.0
    .. versionchanged:: 18.2.0
       Switch from Argon2i to Argon2id based on the recommendation by the
       current RFC draft. See also :doc:`parameters`.
    .. versionchanged:: 18.2.0
       Changed default *memory_cost* to 100 MiB and default *parallelism* to 8.
    .. versionchanged:: 18.2.0 ``verify`` now will determine the type of hash.
    .. versionchanged:: 18.3.0 The Argon2 type is configurable now.

    .. _salt: https://en.wikipedia.org/wiki/Salt_(cryptography)
    .. _kibibytes: https://en.wikipedia.org/wiki/Binary_prefix#kibi
    _parametersr   zutf-8c           
          t        |t        f|t        f|t        f|t        f|t        f|t        f|t        f      }|rt	        |      t        |d|||||      | _        || _        y )N)	time_costmemory_costparallelismhash_lensalt_lenr   type   )r    versionr   r   r   r   r   )r   intstrr   	TypeErrorr   r   r   )	selfr   r   r   r   r   r   r    es	            r   __init__zPasswordHasher.__init__@   s~      #&$c*$c*___
 A, &##
 !r   c                 .    | j                   j                  S N)r   r   r&   s    r   r   zPasswordHasher.time_costb   s    )))r   c                 .    | j                   j                  S r*   )r   r   r+   s    r   r   zPasswordHasher.memory_costf       +++r   c                 .    | j                   j                  S r*   )r   r   r+   s    r   r   zPasswordHasher.parallelismj   r-   r   c                 .    | j                   j                  S r*   )r   r   r+   s    r   r   zPasswordHasher.hash_lenn       (((r   c                 .    | j                   j                  S r*   )r   r   r+   s    r   r   zPasswordHasher.salt_lenr   r0   r   c                 .    | j                   j                  S r*   )r   r    r+   s    r   r    zPasswordHasher.typev   s    $$$r   c           	      
   t        t        || j                        t        j                  | j
                        | j                  | j                  | j                  | j                  | j                        j                  d      S )z
        Hash *password* and return an encoded hash.

        :param password: Password to hash.
        :type password: ``bytes`` or ``unicode``

        :raises argon2.exceptions.HashingError: If hashing fails.

        :rtype: unicode
        )secretsaltr   r   r   r   r    ascii)r	   r   r   osurandomr   r   r   r   r   r    decode)r&   passwords     r   hashzPasswordHasher.hashz   sa      4==9DMM*nn((((]]
 &/	r   )s	   $argon2i$s	   $argon2d$s	   $argon2idc                     t        |d      }	 | j                  |dd    }t        |t        || j                        |      S # t        t        t        f$ r t               w xY w)a  
        Verify that *password* matches *hash*.

        .. warning::

            It is assumed that the caller is in full control of the hash.  No
            other parsing than the determination of the hash type is done by
            ``argon2-cffi``.

        :param hash: An encoded hash as returned from
            :meth:`PasswordHasher.hash`.
        :type hash: ``bytes`` or ``unicode``

        :param password: The password to verify.
        :type password: ``bytes`` or ``unicode``

        :raises argon2.exceptions.VerifyMismatchError: If verification fails
            because *hash* is not valid for *password*.
        :raises argon2.exceptions.VerificationError: If verification fails for
            other reasons.
        :raises argon2.exceptions.InvalidHash: If *hash* is so clearly
            invalid, that it couldn't be passed to Argon2.

        :return: ``True`` on success, raise
            :exc:`~argon2.exceptions.VerificationError` otherwise.
        :rtype: bool

        .. versionchanged:: 16.1.0
            Raise :exc:`~argon2.exceptions.VerifyMismatchError` on mismatches
            instead of its more generic superclass.
        .. versionadded:: 18.2.0 Hash type agility.
        r6   N	   )r   _header_to_type
IndexErrorKeyErrorLookupErrorr   r
   r   )r&   r;   r:   	hash_types       r   verifyzPasswordHasher.verify   sm    B T7+	 ,,T"1X6I -$--8)
 	
 Hk2 	 -	 s   A A c                 2    | j                   t        |      k7  S )aO  
        Check whether *hash* was created using the instance's parameters.

        Whenever your Argon2 parameters -- or ``argon2-cffi``'s defaults! --
        change, you should rehash your passwords at the next opportunity.  The
        common approach is to do that whenever a user logs in, since that
        should be the only time when you have access to the cleartext
        password.

        Therefore it's best practice to check -- and if necessary rehash --
        passwords after each successful authentication.

        :rtype: bool

        .. versionadded:: 18.2.0
        )r   r   )r&   r;   s     r   check_needs_rehashz!PasswordHasher.check_needs_rehash   s    " #5d#;;;r   N)__name__
__module____qualname____doc__	__slots__DEFAULT_TIME_COSTDEFAULT_MEMORY_COSTDEFAULT_PARALLELISMDEFAULT_HASH_LENGTHDEFAULT_RANDOM_SALT_LENGTHr   IDr(   propertyr   r   r   r   r   r    r;   IDr>   rC   rE    r   r   r   r      s    $J 
+I $''$+WW !D * * , , , , ) ) ) ) % %, ffffggO)
V<r   r   )r7   _utilsr   r   r   
exceptionsr   	low_levelr   r	   r
   rO   rN   rK   rL   rM   r   r   rT   r   r   <module>rX      sH    	 @ @ # 7 7       y< y<r   