a fWc @sdZddlmZmZddlZeeZddlZddl Z ddl m Z dZ da ddlmZddlmZddlmZmZmZddlmZmZdd lmZmZmZmZmZddlm m!Z"d gZ#ed Z$ed Z%ed Z&e&e$e%fZ'e(e'Z)dZ*z ddl+Z Wne,y dZ Yn,0e-e ds$dZ*dZ ne-e ds8dZ*dZ e-e drVe .Z/e j0j1Z2nGdddZ3e3Z/dZ2Gddde"j4e"j5e"j6e"j7e"j8e"j9Z:Gddde:Z;Gddde:Z= 18.2.0PasswordHasherc@s$eZdZdZdZdZdZdZdZdS)_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 iN) __name__ __module__ __qualname____doc__ time_cost memory_cost parallelismsalt_lenhash_lenr$r$;/usr/lib/python3.9/site-packages/passlib/handlers/argon2.pyr]s rc sfeZdZdZdZdZejZe j j dZ e j j dZ ej ZdZeZejZdZeZdZd ZeZd ZdZd Zd ZiZed dZ e!Z"ej#Z#eZ$ej%Z%e&ddZ'd Z(e)d.fdd Z*e)ddZ+e,-dZ.e)ddZ/e,-de,j0Z1e)ddZ2ddZ3d/fdd Z4e)dd Z5e)d!d"Z6e)d0d#d$Z7e)d%d&Z8fd'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"roundsrr r! digest_sizer#type)r,)r"rr#r+ZlineariNFcCs|t|jS)zj return tuple of types supported by this backend .. versionadded:: 1.7.2 ) get_backendtuple_backend_type_map)clsr$r$r% type_valuessz_Argon2Common.type_valuescCs |jtkS)zn flag indicating a Type D hash .. deprecated:: 1.7.2; will be removed in passlib 2.0 )r,TYPE_Dselfr$r$r%type_dsz_Argon2Common.type_dc  sj|dur d| vrtd|| d<|dur@d| vr8td|| d<|dur\|durXtd|}|durx|durttd|}tt|jfi| } |dur| || _| d} |durt|tj rt |}tj | |dt d | d | _ |durt|tj rt |}| j|| d | _| | j| j|durft|tj r>t |}|d kr`|d kr`td|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 exclusiverelaxedrr+)minmaxparamr9)r9r.r/z7max_threads (%d) must be -1 (unlimited), or at least 1.) TypeErrorsuperr'using _norm_typer,get isinstanceuhZnative_string_typesint norm_integerr checksum_size_norm_memory_costr _validate_constraintsr! ValueError max_threads) r3r,r r"rr+rFr#rJkwdssubclsr9 __class__r$r%r?sP       z_Argon2Common.usingcCs*d|}||kr&td|j|||fdS)Nr-zO%s: memory_cost (%d) is too low, must be at least 8 * parallelism (8 * %d = %d))rIname)r3r r!min_memory_costr$r$r%rHBsz#_Argon2Common._validate_constraintsz^\$argon2[a-z]+\$cCst|}|j|duSN)rCZto_unicode_for_identify _ident_regexmatch)r3hashr$r$r%identifyTs z_Argon2Common.identifys ^ \$argon2(?P[a-z]+)\$ (?: v=(?P\d+) \$ )? m=(?P\d+) , t=(?P\d+) , p=(?P\d+) (?: ,keyid=(?P[^,$]+) )? (?: ,data=(?P[^,$]+) )? (?: \$ (?P[^$]+) (?: \$ (?P.+) )? )? $ c Cst|tr|d}t|ts*t|d|j|}|sDt|| ddddddd d d \ }}}}}}} } } |r|t d || d |rt |ndt |t |t || rt | nd| rt | nd| rt | nddS)Nutf-8rTr,versionr rr!keyiddatar(digestz&argon2 'keyid' parameter not supportedasciir)r,rWr r*r!r(rYchecksum)rBr encodebytesrZExpectedStringError _hash_regexrSMalformedHashErrorgroupNotImplementedErrordecoderDr ) r3rTmr,rWr rr!rXrYr(rZr$r$r% from_strings.      z_Argon2Common.from_stringc Csv|j}|dkrd}nd|}|j}|r:dtt|j}nd}dt|j||j|j|j|tt|j tt|j fS)Nrzv=%d$z,data=z"$argon2%s$%sm=%d,t=%d,p=%d%s$%s$%s) rWrYrr rr,r r*r!r(r\)r7rWZvstrrYZkdstrr$r$r% to_strings$  z_Argon2Common.to_stringc s|rtd|dusJt}|d}|dur8t||_tt|jfi||durrtj ||j |j dds~Jn | ||_ |durtj ||j |j ddsJn | ||_ |durtj ||j|jddsJn |||_|dur|jdusJn"t|tstj|dd||_dS) Nzoargon2 `type_d=True` keyword is deprecated, and will be removed in passlib 2.0; please use ``type="d"`` insteadr\r,)r<rWr r^rY)rr5rAlenrFr>r'__init__rCZvalidate_default_valuer,r@rW _norm_versionr rGrYrBr^rExpectedTypeError)r7r,r8rWr rYrKr\rMr$r%ris4         z_Argon2Common.__init__cCsft|ts4tr$t|tr$|d}ntj|dd|tvr@|S| }|tvrT|St d|fdS)Nr[strr,zunknown argon2 hash type: %r) rBr rr^rcrCrrk ALL_TYPES_SETlowerrI)r3valueZtempr$r$r%r@s  z_Argon2Common._norm_typecCsht|tjstj|dd|dkr:|dkr:td|f|}||jkrdtd|j|||jf|S)NZintegerrWr&rzinvalid argon2 hash version: %dzk%s: hash version 0x%X not supported by %r backend (max version is 0x%X); try updating or switching backends) rBrCZ int_typesrrkrIr0 max_versionrO)r3rWbackendr$r$r%rj s  z_Argon2Common._norm_versioncCstj|||jd|dS)Nr )r:r<r9)rCrErP)r3r r9r$r$r%rGs z_Argon2Common._norm_memory_costcCs<z |j|WStyYn0d||f}t|dS)z> helper to resolve backend constant from type z=unsupported argon2 hash (type %r not supported by %s backend)N)r2KeyErrorr0rI)r3romsgr$r$r%_get_backend_type%s   z_Argon2Common._get_backend_typec szt|}|j|jkrdS|j}|dus0||jkr6|j}|j|krDdS|j|jkrTdS|j|jkrddStt|jfi|S)NT) r,min_desired_versionrprWr rFr>r'_calc_needs_update)r7rKr3ZminverrMr$r%rv7s    z _Argon2Common._calc_needs_updatez> -- recommend you install one (e.g. 'pip install argon2_cffi')cCsp|j}t|tr|dksJ|dkr6td|tjjtD]}||jvr:||_ qlq:td|tjj t |_ dS)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. rr&z6%r doesn't support argon2 v1.3, and should be upgradedz)%r lacks support for all known hash typesT) rprBrDrrCrPasslibSecurityWarning ALL_TYPESr2r,ZPasslibRuntimeWarningTYPE_ID) mixin_clsrOdryrunrpr,r$r$r%_finalize_backend_mixinMs z%_Argon2Common._finalize_backend_mixincCs|}|dur"|dur"||}|durT||j|j|dkrT|jdurTtdt|}|dvrtd|||f}nt|}t j ||ddS)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)zDecoding failedz%s reported: %s: hash=%r)reason) r0rerHr r!rYrbrlreprrr`)r3errrTr7rqtextr~r$r$r%_adapt_backend_errorgs z"_Argon2Common._adapt_backend_error)NNNNNNNN)NFNNN)F)NN)>rrrrrOZ setting_kwds_default_settingsr#rFrCGenericHandlerZ_always_parse_settingsZ_unparsed_settingsr"Zdefault_salt_sizeZ min_salt_sizerZ max_salt_sizerdefault_roundsZ min_roundsZ max_roundsZ rounds_costZmax_parallelism_default_versionrprurPrJpure_use_threadsr2rr4ryr,r!rWr propertyr8rY classmethodr?rHrecompilerRrUXr_rergrir@rjrGrtrvZ_no_backend_suggestionr|r __classcell__r$r$rMr%r'ss~  ;    2      r'csReZdZdZeddZeddZejddded d Z fd d Z Z S) _NoBackendz mixin used before any backend has been loaded. contains stubs that force loading of one of the available backends. cCs|||SrQ)_stub_requires_backendrT)r3secretr$r$r%rTsz_NoBackend.hashcCs||||SrQ)rverify)r3rrTr$r$r%rsz_NoBackend.verifyz1.7z2.0)Z deprecatedZremovedcCs||||SrQ)rgenhash)r3rconfigr$r$r%rsz_NoBackend.genhashcs|tt||SrQ)rr>r_calc_checksumr7rrMr$r%rsz_NoBackend._calc_checksum) rrrrrrTrrCZdeprecated_methodrrrr$r$rMr%rs    rc@sZeZdZdZeddZeddZeddeDZ edd Z ed d Z d d Z dS) _CffiBackendz argon2_cffi backend c Cs|tus Jtdur&tr"ttdStjj}tdtj |tj }i}t D]F}zt || ||<WqLty|ttfvsJd|YqL0qL||_||_|_|||S)NFzOdetected 'argon2_cffi' backend, version %r, with support for 0x%x argon2 hashesunexpected missing type: %r)r _argon2_cffi_argon2_cffi_errorrZPasslibSecurityErrorrARGON2_VERSIONlogdebug __version__rrxgetattrupperAttributeErrorTYPE_Ir5r2rWrpr|)rzrOr{rpZTypeEnumtype_mapr,r$r$r%_load_backend_mixins&     z _CffiBackend._load_backend_mixinc Cst|t|d}z8ttjj||j|j |j |j t| |j |dWStjjy~}z||WYd}~n d}~00dS)NrV)r,r rr!r(r#r)rCvalidate_secretrrrr hash_secretrtr,r rr!Z_generate_saltrF exceptions HashingErrorr)r3rrr$r$r%rTs     z_CffiBackend.hashccs"|]}td|d|fVqdS)s $argon2%s$r[N)r r]).0r,r$r$r% sz_CffiBackend.c Cst|t|d}t|d}|j|dd|ddt}||}z"tj |||}|dushJWdStj j yYdStj j y}z|j||dWYd}~n d}~00dS)NrVr[r.$TFrT)rCrr_byte_ident_maprAfindrrtrrZ verify_secretrZVerifyMismatchErrorZVerificationErrorr)r3rrTr, type_coderesultrr$r$r%rs   "  z_CffiBackend.verifyc Cst|t|d}||}z= 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 recommendedZARGON2r)r argon2pure _argon2pure ImportErrorrrZwarningrrrrwrxrrrrr5r2rWrpr|)rzrOr{rprr,r$r$r%r<s4        z _PureBackend._load_backend_mixinc Cst|t|d}t||j|j|j|j|j| |j |j d}|j dkrT|j |d<|j rbd|d<|jrr|j|d<ztjfi|WStjy}z|j||dWYd}~n d}~00dS) NrV)passwordr(rr r!Z tag_lengthrrWrthreadsTZ use_threadsZassociated_datar6)rCrrrr(r*r r!rFrtr,rWrJrrYrrZ Argon2Errorr)r7rrKrr$r$r%rns,      z_PureBackend._calc_checksumN)rrrrrrrr$r$r$r%r4s 1rc@s$eZdZdZdZdZeeedZ dS)ra 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}rT)Nr}rN) rrrrZbackendsZ_backend_mixin_targetrrrZ_backend_mixin_mapr$r$r$r%rsP)>rZ __future__rrZloggingZ getLoggerrrrtypeswarningsrrrZpasslibrZpasslib.crypto.digestrZ passlib.utilsrrr Zpasslib.utils.binaryr r Zpasslib.utils.compatr r rrrZpasslib.utils.handlersZutilshandlersrC__all__rr5ryrxsetrmrrrhasattrrrrrrrZSubclassBackendMixinZParallelismMixinZ HasRoundsZ HasRawSaltZHasRawChecksumrr'rrrr$r$r$r%sf             *|Z