o
    _6d                  	   @   s  d Z ddlmZmZ ddlZeeZddlZddl	Z	ddl
mZ dZdaddlmZ ddlmZ ddlmZmZmZ ddlmZmZ dd	lmZmZmZmZmZ ddlm   m!Z" d
gZ#edZ$edZ%edZ&e&e$e%fZ'e(e'Z)dZ*zddl+ZW n e,y   dZY nw e-edsdZ*dZn	e-edsdZ*dZe-edre. Z/ej0j1Z2nG dd dZ3e3 Z/dZ2G dd de"j4e"j5e"j6e"j7e"j8e"j9Z:G dd de:Z;G dd de:Z<G dd de:Z=G dd
 d
e;e:Z+dS )a  passlib.handlers.argon2 -- argon2 password hash wrapper

References
==========
* argon2
    - home: https://github.com/P-H-C/phc-winner-argon2
    - whitepaper: https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf
* argon2 cffi wrapper
    - pypi: https://pypi.python.org/pypi/argon2_cffi
    - home: https://github.com/hynek/argon2_cffi
* argon2 pure python
    - pypi: https://pypi.python.org/pypi/argon2pure
    - home: https://github.com/bwesterb/argon2pure
    )with_statementabsolute_importN)warn)exc)
MAX_UINT32)classpropertyto_bytesrender_bytes)b64s_encodeb64s_decode)uunicodebascii_to_struascii_to_strPY2argon2ididTypezb'argon2' module points to unsupported 'argon2' pypi package; please install 'argon2-cffi' instead.	low_levelz@'argon2-cffi' is too old, please update to argon2_cffi >= 18.2.0PasswordHasherc                   @   s$   e Zd ZdZdZdZdZdZdZdS )_DummyCffiHashera  
        dummy object to use as source of defaults when argon2_cffi isn't present.
        this tries to mimic the attributes of ``argon2.PasswordHasher()`` which the rest of
        this module reads.

        .. note:: values last synced w/ argon2 19.2 as of 2019-11-09
           i      N)	__name__
__module____qualname____doc__	time_costmemory_costparallelismsalt_lenhash_len r$   r$   nC:\Users\jesus\OneDrive\Desktop\erpjis_fastapi\backend\jisbackend\Lib\site-packages\passlib/handlers/argon2.pyr   ]   s    r      c                       sj  e Zd ZdZdZdZejZe	j
jd Ze	j
jd ZejZdZeZejZdZeZdZd	ZeZd
ZdZdZdZi Zedd Z e!Z"ej#Z#eZ$ej%Z%e&dd Z'd
Z(e)	
	
d. fdd	Z*e)dd Z+e,-dZ.e)dd Z/e,-de,j0Z1e)dd Z2dd Z3d/ fdd	Z4e)dd  Z5e)d!d" Z6e)d0d#d$Z7e)d%d& Z8 fd'd(Z9d)Z:e)d*d+ Z;e)d1d,d-Z<  Z=S )2_Argon2Commona&  
    Base class which implements brunt of Argon2 code.
    This is then subclassed by the various backends,
    to override w/ backend-specific methods.

    When a backend is loaded, the bases of the 'argon2' class proper
    are modified to prepend the correct backend-specific subclass.
    r   )
salt	salt_sizer"   roundsr   r    r!   digest_sizer#   type)r,   )r"   r   r#   r+         Zlineari NFc                 C   s   |    t| jS )zj
        return tuple of types supported by this backend
        
        .. versionadded:: 1.7.2
        )get_backendtuple_backend_type_map)clsr$   r$   r%   type_values   s   
z_Argon2Common.type_valuesc                 C   s
   | j tkS )zn
        flag indicating a Type D hash

        .. deprecated:: 1.7.2; will be removed in passlib 2.0
        )r,   TYPE_Dselfr$   r$   r%   type_d   s   
z_Argon2Common.type_dc	                    s`  |d urd|	v rt d||	d< |d ur d|	v rt d||	d< |d ur.|d ur,t d|}|d ur<|d ur:t d|}tt| jdi |	}
|d urQ|
||
_|	d}|d urpt|tj	rdt
|}tj|
|dtd	|d
|
_|d urt|tj	r~t
|}|
j||d|
_|
|
j|
j |d urt|tj	rt
|}|dk r|dkrtd|f ||
_|
S )Nr*   z/'time_cost' and 'rounds' are mutually exclusiver)   z1'salt_len' and 'salt_size' are mutually exclusivez3'hash_len' and 'digest_size' are mutually exclusivez8'checksum_size' and 'digest_size' are mutually exclusiverelaxedr   r+   )minmaxparamr9   )r9   r.   r/   z7max_threads (%d) must be -1 (unlimited), or at least 1.r$   )	TypeErrorsuperr'   using
_norm_typer,   get
isinstanceuhZnative_string_typesintnorm_integerr   checksum_size_norm_memory_costr    _validate_constraintsr!   
ValueErrormax_threads)r3   r,   r    r"   r   r+   rF   r#   rJ   kwdssubclsr9   	__class__r$   r%   r?     sP   
z_Argon2Common.usingc                 C   s*   d| }||k rt d| j|||f d S )Nr-   zO%s: memory_cost (%d) is too low, must be at least 8 * parallelism (8 * %d = %d))rI   name)r3   r    r!   min_memory_costr$   r$   r%   rH   B  s   z#_Argon2Common._validate_constraintsz^\$argon2[a-z]+\$c                 C   s   t |}| j|d uS N)rC   Zto_unicode_for_identify_ident_regexmatch)r3   hashr$   r$   r%   identifyT  s   
z_Argon2Common.identifys  
        ^
        \$argon2(?P<type>[a-z]+)\$
        (?:
            v=(?P<version>\d+)
            \$
        )?
        m=(?P<memory_cost>\d+)
        ,
        t=(?P<time_cost>\d+)
        ,
        p=(?P<parallelism>\d+)
        (?:
            ,keyid=(?P<keyid>[^,$]+)
        )?
        (?:
            ,data=(?P<data>[^,$]+)
        )?
        (?:
            \$
            (?P<salt>[^$]+)
            (?:
                \$
                (?P<digest>.+)
            )?
        )?
        $
    c                 C   s   t |tr
|d}t |tst|d| j|}|s"t| |	ddddddd	d
d	\	}}}}}}}	}
}|r>t
d| |d|rIt|ndt|t|t||
rYt|
nd |	r`t|	nd |rit|dS d dS )Nutf-8rT   r,   versionr    r   r!   keyiddatar(   digestz&argon2 'keyid' parameter not supportedasciir   )r,   rW   r    r*   r!   r(   rY   checksum)rB   r   encodebytesr   ZExpectedStringError_hash_regexrS   MalformedHashErrorgroupNotImplementedErrordecoderD   r   )r3   rT   mr,   rW   r    r   r!   rX   rY   r(   rZ   r$   r$   r%   from_string  s2   




z_Argon2Common.from_stringc                 C   sv   | j }|dkr
d}nd| }| j}|rdtt| j }nd}dt| j|| j| j| j|tt| j	tt| j
f S )Nr    zv=%d$z,data=z"$argon2%s$%sm=%d,t=%d,p=%d%s$%s$%s)rW   rY   r   r
   r   r,   r    r*   r!   r(   r\   )r7   rW   ZvstrrY   Zkdstrr$   r$   r%   	to_string  s$   z_Argon2Common.to_stringc                    s  |rt d |d u sJ t}|d}|d urt|| _tt| jd	i | |d u r9tj	| | j
| jdds8J n| || _
|d u rQtj	| | j| jddsPJ n| || _|d u ritj	| | j| jddshJ n| || _|d u r|| jd u szJ d S t|tstj|dd|| _d S )
Nzoargon2 `type_d=True` keyword is deprecated, and will be removed in passlib 2.0; please use ``type="d"`` insteadr\   r,   )r<   rW   r    r^   rY   r$   )r   r5   rA   lenrF   r>   r'   __init__rC   Zvalidate_default_valuer,   r@   rW   _norm_versionr    rG   rY   rB   r^   r   ExpectedTypeError)r7   r,   r8   rW   r    rY   rK   r\   rM   r$   r%   ri     s4   



z_Argon2Common.__init__c                 C   sb   t |tstrt |tr|d}ntj|dd|tv r |S |	 }|tv r*|S t
d|f )Nr[   strr,   zunknown argon2 hash type: %r)rB   r   r   r^   rc   rC   r   rk   ALL_TYPES_SETlowerrI   )r3   valuetempr$   r$   r%   r@     s   
z_Argon2Common._norm_typec                 C   sh   t |tjstj|dd|dk r|dkrtd|f |  }|| jkr2td| j||| jf |S )NintegerrW   r&   r   zinvalid argon2 hash version: %dzk%s: hash version 0x%X not supported by %r backend (max version is 0x%X); try updating or switching backends)	rB   rC   	int_typesr   rk   rI   r0   max_versionrO   )r3   rW   backendr$   r$   r%   rj   	  s   
z_Argon2Common._norm_versionc                 C   s   t j| || jd|dS )Nr    )r:   r<   r9   )rC   rE   rP   )r3   r    r9   r$   r$   r%   rG     s   z_Argon2Common._norm_memory_costc                 C   s8   z| j | W S  ty   Y nw d||  f }t|)z>
        helper to resolve backend constant from type
        z=unsupported argon2 hash (type %r not supported by %s backend))r2   KeyErrorr0   rI   )r3   ro   msgr$   r$   r%   _get_backend_type%  s   
z_Argon2Common._get_backend_typec                    sz   t | }| j |j krdS |j}|d u s||jkr|j}| j|k r"dS | j|jkr*dS | j|jkr2dS tt| jdi |S )NTr$   )	r,   min_desired_versionrs   rW   r    rF   r>   r'   _calc_needs_update)r7   rK   r3   ZminverrM   r$   r%   ry   7  s   
z _Argon2Common._calc_needs_updatez> -- recommend you install one (e.g. 'pip install argon2_cffi')c                 C   sr   | j }t|tr|dksJ |dk rtd| tjj tD ]}|| jv r*|| _	 dS qtd| tjj
 t| _	dS )z
        helper called by from backend mixin classes' _load_backend_mixin() --
        invoked after backend imports have been loaded, and performs
        feature detection & testing common to all backends.
        r   r&   z6%r doesn't support argon2 v1.3, and should be upgradedz)%r lacks support for all known hash typesT)rs   rB   rD   r   rC   r   PasslibSecurityWarning	ALL_TYPESr2   r,   ZPasslibRuntimeWarningTYPE_ID)	mixin_clsrO   dryrunrs   r,   r$   r$   r%   _finalize_backend_mixinM  s   
z%_Argon2Common._finalize_backend_mixinc                 C   s   |   }|du r|dur| |}|dur*||j|j |dkr*|jdur*tdt|}|dvr:d|||f }nt|}t	j
| |d)z}
        internal helper invoked when backend has hash/verification error;
        used to adapt to passlib message.
        Nargon2_cffiz8argon2_cffi backend doesn't support the 'data' parameter)zDecoding failedz%s reported: %s: hash=%r)reason)r0   re   rH   r    r!   rY   rb   rl   reprr   r`   )r3   errrT   r7   rt   textr   r$   r$   r%   _adapt_backend_errorg  s   
z"_Argon2Common._adapt_backend_error)NNNNNNNN)NFNNN)F)NN)>r   r   r   r   rO   Zsetting_kwds_default_settingsr#   rF   rC   GenericHandlerZ_always_parse_settingsZ_unparsed_settingsr"   Zdefault_salt_sizeZmin_salt_sizer   Zmax_salt_sizer   default_roundsZ
min_rounds
max_roundsZrounds_costZmax_parallelism_default_versionrs   rx   rP   rJ   pure_use_threadsr2   r   r4   r|   r,   r!   rW   r    propertyr8   rY   classmethodr?   rH   recompilerR   rU   Xr_   re   rg   ri   r@   rj   rG   rw   ry   Z_no_backend_suggestionr   r   __classcell__r$   r$   rM   r%   r'   s   s    

	;



2




r'   c                       sR   e Zd ZdZedd Zedd Zejddded	d
 Z	 fddZ
  ZS )
_NoBackendz
    mixin used before any backend has been loaded.
    contains stubs that force loading of one of the available backends.
    c                 C   s   |    | |S rQ   )_stub_requires_backendrT   )r3   secretr$   r$   r%   rT     s   
z_NoBackend.hashc                 C      |    | ||S rQ   )r   verify)r3   r   rT   r$   r$   r%   r     s   z_NoBackend.verifyz1.7z2.0)
deprecatedremovedc                 C   r   rQ   )r   genhash)r3   r   configr$   r$   r%   r     s   z_NoBackend.genhashc                    s   |    tt| |S rQ   )r   r>   r   _calc_checksumr7   r   rM   r$   r%   r     s   z_NoBackend._calc_checksum)r   r   r   r   r   rT   r   rC   Zdeprecated_methodr   r   r   r$   r$   rM   r%   r     s    

r   c                   @   sZ   e Zd ZdZedd Zedd Zedd eD Z	edd	 Z
ed
d Zdd ZdS )_CffiBackendz
    argon2_cffi backend
    c              	   C   s   | t u sJ td u rtrttdS tjj}tdtj	| tj
}i }tD ]"}zt|| ||< W q& tyH   |ttfvsFJ d| Y q&w || _| | _| _| ||S )NFzOdetected 'argon2_cffi' backend, version %r, with support for 0x%x argon2 hashesunexpected missing type: %r)r   _argon2_cffi_argon2_cffi_errorr   ZPasslibSecurityErrorr   ARGON2_VERSIONlogdebug__version__r   r{   getattrupperAttributeErrorTYPE_Ir5   r2   rW   rs   r   )r}   rO   r~   rs   ZTypeEnumtype_mapr,   r$   r$   r%   _load_backend_mixin  s(   
z _CffiBackend._load_backend_mixinc              
   C   st   t | t|d}zttjj| | j| j	| j
| jt|  | j|dW S  tjjy9 } z| |d }~ww )NrV   )r,   r    r   r!   r(   r#   r   )rC   validate_secretr   r   r   r   hash_secretrw   r,   r    r   r!   Z_generate_saltrF   
exceptionsHashingErrorr   )r3   r   r   r$   r$   r%   rT     s    




	
z_CffiBackend.hashc                 c   s$    | ]}t d |d|fV  qdS )s
   $argon2%s$r[   N)r	   r]   ).0r,   r$   r$   r%   	<genexpr>  s    z_CffiBackend.<genexpr>c              
   C   s   t | t|d}t|d}| j|d d|dd  t}| |}ztj	
|||}|du s4J W dS  tjjyB   Y dS  tjjyV } z| j||dd }~ww )NrV   r[   r.      $TFrT   )rC   r   r   _byte_ident_maprA   findr   rw   r   r   Zverify_secretr   ZVerifyMismatchErrorZVerificationErrorr   )r3   r   rT   r,   	type_coderesultr   r$   r$   r%   r     s   


"
z_CffiBackend.verifyc                 C   s   t | t|d}| |}zttjj| |j	|j
|j|jt|j|j||jd}W n tjjyB } z| j||dd }~ww |jdkrN|dd}|S )NrV   )r,   r    r   r!   r(   r#   r   rW   r   r   z$v=16$$)rC   r   r   re   r   r   r   r   rw   r,   r    r*   r!   r(   rF   rW   r   r   r   replace)r3   r   r   r7   r   r   r$   r$   r%   r     s*   





z_CffiBackend.genhashc                 C   s   t d)Nz-shouldn't be called under argon2_cffi backend)AssertionErrorr   r$   r$   r%   r   *  s   z_CffiBackend._calc_checksumN)r   r   r   r   r   r   rT   dictr{   r   r   r   r   r$   r$   r$   r%   r     s    



r   c                   @   s$   e Zd ZdZedd Zdd ZdS )_PureBackendz
    argon2pure backend
    c              	   C   s   | t u sJ zdd laW n
 ty   Y dS w zddlm} W n ty.   td Y dS w td| |s=tdt	j
 i }tD ]$}zttd|  ||< W qA tye   |ttfvscJ d| Y qAw || _| | _| _| ||S )	Nr   F)ARGON2_DEFAULT_VERSIONz\detected 'argon2pure' backend, but package is too old (passlib requires argon2pure >= 1.2.3)zBdetected 'argon2pure' backend, with support for 0x%x argon2 hasheszUsing argon2pure backend, which is 100x+ slower than is required for adequate security. Installing argon2_cffi (via 'pip install argon2_cffi') is strongly recommendedZARGON2r   )r   
argon2pure_argon2pureImportErrorr   r   warningr   r   r   rz   r{   r   r   r   r   r5   r2   rW   rs   r   )r}   rO   r~   rs   r   r,   r$   r$   r%   r   <  s:   
z _PureBackend._load_backend_mixinc              
   C   s   t | t|d}t|| j| j| j| j| j| 	| j
| jd}| jdkr*| j|d< | jr1d|d< | jr9| j|d< z	tjd	i |W S  tjyV } z| j|| dd }~ww )
NrV   )passwordr(   r   r    r!   Z
tag_lengthr   rW   r   threadsTZuse_threadsZassociated_datar6   r$   )rC   r   r   r   r(   r*   r    r!   rF   rw   r,   rW   rJ   r   rY   r   r   ZArgon2Errorr   )r7   r   rK   r   r$   r$   r%   r   n  s0   






z_PureBackend._calc_checksumN)r   r   r   r   r   r   r   r$   r$   r$   r%   r   4  s
    
1r   c                   @   s$   e Zd ZdZdZdZeeedZ	dS )r   a	  
    This class implements the Argon2 password hash [#argon2-home]_, and follows the :ref:`password-hash-api`.

    Argon2 supports a variable-length salt, and variable time & memory cost,
    and a number of other configurable parameters.

    The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords:

    :type type: str
    :param type:
        Specify the type of argon2 hash to generate.
        Can be one of "ID", "I", "D".

        This defaults to "ID" if supported by the backend, otherwise "I".

    :type salt: str
    :param salt:
        Optional salt string.
        If specified, the length must be between 0-1024 bytes.
        If not specified, one will be auto-generated (this is recommended).

    :type salt_size: int
    :param salt_size:
        Optional number of bytes to use when autogenerating new salts.

    :type rounds: int
    :param rounds:
        Optional number of rounds to use.
        This corresponds linearly to the amount of time hashing will take.

    :type time_cost: int
    :param time_cost:
        An alias for **rounds**, for compatibility with underlying argon2 library.

    :param int memory_cost:
        Defines the memory usage in kibibytes.
        This corresponds linearly to the amount of memory hashing will take.

    :param int parallelism:
        Defines the parallelization factor.
        *NOTE: this will affect the resulting hash value.*

    :param int digest_size:
        Length of the digest in bytes.

    :param int max_threads:
        Maximum number of threads that will be used.
        -1 means unlimited; otherwise hashing will use ``min(parallelism, max_threads)`` threads.

        .. note::

            This option is currently only honored by the argon2pure backend.

    :type relaxed: bool
    :param relaxed:
        By default, providing an invalid value for one of the other
        keywords will result in a :exc:`ValueError`. If ``relaxed=True``,
        and the error can be corrected, a :exc:`~passlib.exc.PasslibHashWarning`
        will be issued instead. Correctable errors include ``rounds``
        that are too small or too large, and ``salt`` strings that are too long.

    .. versionchanged:: 1.7.2

        Added the "type" keyword, and support for type "D" and "ID" hashes.
        (Prior versions could verify type "D" hashes, but not generate them).

    .. todo::

        * Support configurable threading limits.
    )r   r   T)Nr   r   N)
r   r   r   r   backendsZ_backend_mixin_targetr   r   r   Z_backend_mixin_mapr$   r$   r$   r%   r     s    P
)>r   
__future__r   r   logging	getLoggerr   r   r   typeswarningsr   r   r   Zpasslibr   Zpasslib.crypto.digestr   Zpasslib.utilsr   r   r	   Zpasslib.utils.binaryr
   r   Zpasslib.utils.compatr   r   r   r   r   Zpasslib.utils.handlersutilshandlersrC   __all__r   r5   r|   r{   setrm   r   r   r   hasattrr   r   r   r   r   r   ZSubclassBackendMixinZParallelismMixinZ	HasRoundsZ
HasRawSaltZHasRawChecksumr   r'   r   r   r   r$   r$   r$   r%   <module>   sj    

	



    *|Z