Xc@sdZddlmZmZddlZejeZddlZddl Z ddl m Z e Z e addlmZddlmZddlmZddlmZmZdd lmZmZmZddljjZd gZ yddl!Z Wne"k re Z nXe#e d e Z$e$rBe$Z%e j&j'Z(nd fd YZ%dZ(dej)ej*ej+ej,ej-ej.fdYZ/de/fdYZ0de/fdYZ1de/fdYZ2d e0e/fdYZ!dS(spasslib.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 i(twith_statementtabsolute_importN(twarn(texc(t MAX_UINT32(tto_bytes(t b64s_encodet b64s_decode(tutunicodet bascii_to_strtargon2tPasswordHashert_default_settingscBs,eZdZdZdZdZdZdZRS(s dummy object to use as source of defaults when argon2 mod not present. synced w/ argon2 16.1 as of 2016-6-16 iii(t__name__t __module__t__doc__t time_costt memory_costt parallelismtsalt_lenthash_len(((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyR :s it _Argon2Commonc BseZdZdZd Zed ZejZ ed ed fZ ej Z dZ eZejZdZeZdZd"ZeZd#ZdZdZeZejZeZej Z eZ!d#Z"e#d#d#d#d#d#d#d#dZ$e#dZ%e#dZ&e'j(de'j)Z*e#dZ+dZ,ed#d#d#dZ-e#dZ.e#edZ/dZ0dZ1e#dZ2e#d#d#dZ3RS($s& 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 tsaltt salt_sizeRtroundsRRRt digest_sizeRs$argon2is $argon2i$s $argon2d$iitlineariic Ks|dk r4d|kr'tdn||d[id])\$ (?: v=(?P\d+) \$ )? m=(?P\d+) , t=(?P\d+) , p=(?P\d+) (?: ,keyid=(?P[^,$]+) )? (?: ,data=(?P[^,$]+) )? (?: \$ (?P[^$]+) (?: \$ (?P.+) )? )? $ c Cs|t|tr!|jd}nt|tsEtj|dn|jj|}|sotj|n|j ddddddd d d \ }}}}}}} } } |dkst d|f|rt dn|d|d kd|r t |nddt |dt |dt |d | rEt | ndd | r]t | ndd| rut | ndS(Nsutf-8R7ttypetversionRRRtkeyidtdataRtdigesttitdsunexpected type code: %rs&argon2 'keyid' parameter not supportedttype_diRtchecksum(R>R?(R%R tencodetbytesRtExpectedStringErrort _hash_regextmatchtMalformedHashErrortgrouptAssertionErrortNotImplementedErrorR(RR ( R/R7tmR9R:RRRR;R<RR=((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyt from_string8s*-    c Cst|j|j}|j}|dkr4d}n d|}|j}|ridtt|j}nd}d|||j|j|j |tt|j tt|j fS(Nitsv=%d$s,data=s%s%sm=%d,t=%d,p=%d%s$%s$%s( tstrR6R@R:R<R RRRRRRA(tselftidentR:tvstrR<tkdstr((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyt to_stringSs      cKs7|jd}|dk r-t||_ntt|j|||_|dkrtj ||j |j ddst n|j ||_ |dkrtj ||j |jddst n|j||_ |dkr|jdks3t n3t|ts*tjj|ddn||_dS(NRARR:RRCR<(R$R tlenR*R"Rt__init__R@R&tvalidate_default_valueR:t _norm_versionRIRR+R<R%RCRtExpectedTypeError(ROR@R:RR<R0RA((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyRUis$     cCst|tjs-tjj|ddn|dkr[|dkr[td|fn|j}||jkrtd|j|||jfn|S(NtintegerR:iisinvalid argon2 hash version: %dsk%s: hash version 0x%X not supported by %r backend (max version is 0x%X); try updating or switching backends( R%R&t int_typesRRXR-t get_backendt max_versionR2(R/R:tbackend((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyRWs c Cs%tj||d|jddd|S(NRRRR(R&R)R3(R/RR((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyR+scKst|}|jrtS|j}|dks=||jkrI|j}n|j|kr\tS|j|jkrrtS|j|jkrtSt t |j |S(N( R9R@tTruetmin_desired_versionR R\R:RR*R"Rt_calc_needs_update(ROR0R/tminver((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyR`s    s> -- recommend you install one (e.g. 'pip install argon2_cffi')cCsT|j}t|tr$|dks*t|dkrPtd|tjjntS(s 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. iis6%r doesn't support argon2 v1.3, and should be upgraded( R\R%R(RIRR&RtPasslibSecurityWarningR^(t mixin_clsR2tdryrunR\((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyt_finalize_backend_mixins  !  cCs|j}|dkr6|dk r6|j|}n|dk r|j|j|j|dkr|jdk rtdqnt|}|dkrd|||f}n t |}t j |d|dS(s} internal helper invoked when backend has hash/verification error; used to adapt to passlib message. t argon2_cffis8argon2_cffi backend doesn't support the 'data' parametersDecoding faileds%s reported: %s: hash=%rtreasonN(sDecoding failed( R[R RLR,RRR<RJRNtreprRRG(R/terrR7ROR]ttextRg((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyt_adapt_backend_errors     ( ssalts salt_sizessalt_lensroundss time_costs memory_costs parallelisms digest_sizeshash_leniiN(4RRRR2t setting_kwdsRRPR RR*R6Rtdefault_salt_sizet min_salt_sizeRt max_salt_sizeRtdefault_roundst min_roundst max_roundst rounds_costtmax_parallelismt_default_versionR\R R_R3R.tFalsetpure_use_threadsRR:RR@R<t classmethodR#R,R8tretcompiletXRERLRSRURWR+R`t_no_backend_suggestionReRk(((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyRIsd         6 ) t _NoBackendcBs\eZdZedZedZejddddedZdZ RS( s mixin used before any backend has been loaded. contains stubs that force loading of one of the available backends. cCs|j|j|S(N(t_stub_requires_backendR7(R/tsecret((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyR7s cCs|j|j||S(N(R~tverify(R/RR7((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyR s t deprecateds1.7tremoveds2.0cCs|j|j||S(N(R~tgenhash(R/Rtconfig((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyRs cCs |jtt|j|S(N(R~R"R t_calc_checksum(ROR((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyRs ( RRRRxR7RR&tdeprecated_methodRR(((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyR}s t _CffiBackendcBsSeZdZedZedZedZedZdZRS(s argon2_cffi backend cCsRtdkrtStjj}tjdtj|||_|_ |j ||S(NsOdetected 'argon2_cffi' backend, version %r, with support for 0x%x argon2 hashes( t _argon2_cffiR Rvt low_leveltARGON2_VERSIONtlogtdebugt __version__R:R\Re(RcR2RdR\((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyt_load_backend_mixin0s    cCstj|t|d}ybttjjdtjjjd|j d|j d|j dt|j d|j d|SWn(tjjk r}|j|nXdS( Nsutf-8R9RRRRRR(R&tvalidate_secretRR RRt hash_secrettTypetIRRpRt_generate_saltR*t exceptionst HashingErrorRk(R/RRi((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyR7>s     cCstj|t|d}t|d}|jdrLtjjj}ntjjj}y2tjj |||}|t kst t SWnEtj j k rtStj jk r}|j|d|nXdS(Nsutf-8tasciis $argon2d$R7(R&RRR5RRRtDRt verify_secretR^RIRtVerifyMismatchErrorRvtVerificationErrorRk(R/RR7R9tresultRi((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyRQs cCstj|t|d}|j|}|jrFtjjj}ntjjj }yat tjj d|d|j d|j d|jdt|jd|jd|d |j}Wn.tjjk r}|j|d |nX|jd kr |jd d }n|S(Nsutf-8R9RRRRRRR:R7is$v=16$t$(R&RRRLR@RRRRRR RRRRRR*R:RRRktreplace(R/RRROR9RRi((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyRfs*      cCstddS(Ns-shouldn't be called under argon2_cffi backend(RI(ROR((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyRs( RRRRxRR7RRR(((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyR(s  t _PureBackendcBs&eZdZedZdZRS(s argon2pure backend cCsyddlaWntk r$tSXyddlm}Wntk rZtjdtSXtjd||stdt j n||_ |_ |j ||S(Ni(tARGON2_DEFAULT_VERSIONs\detected 'argon2pure' backend, but package is too old (passlib requires argon2pure >= 1.2.3)sBdetected 'argon2pure' backend, with support for 0x%x argon2 hashessUsing argon2pure backend, which is 100x+ slower than is required for adequate security. Installing argon2_cffi (via 'pip install argon2_cffi') is strongly recommended(t argon2puret _argon2puret ImportErrorRvRRtwarningRRRRbR:R\Re(RcR2RdR\((s;/usr/lib/python2.7/site-packages/passlib/handlers/argon2.pyRs      cCstj|t|d}|jr1tj}n tj}td|d|jd|j d|j d|j d|j d|d |j }|jd kr|j|d sB        *hQ