ó ¶õ„Xc @ sÖdZddlmZddlZddlZejeƒZy9ddlmZ e j dkruej dƒdZ nWne k rdZ nXddlZddlZddlmZddlmZyddlmZWne k rõdZnXdd lmZdd lmZmZmZmZmZdd lmZm Z m!Z!m"Z"dd l#m$Z$d dddddgZ%dMZ&dOZ'dPdQdRdSdTdUdVdWdXdYdZg Z(iZ)d-„Z*d.„Z+e,d/„Z-e)j.e-_/dd0„Z0defd1„ƒYZ1ed2„ed3ƒDƒƒZ2ed4„ed3ƒDƒƒZ3e,d5„Z4dd6„Z5ed7ƒj6Z7dd8„Zej8j9d9ƒp}d:Z:e"r½e:d[kr½dd<l;m<Z<d=„Z=d>„Z>d;Z?nˆe:d\kr ddlmZdd@lm@Z@e@dkZAiZBdA„Z=d?Z?n8ddBlCmDZEddClmFZFdD„Z=dE„Z>dFZ?e:e?kr^dZZ ngermdGnde r|dHnddIe?gD]ZGeGrŠeG^qŠZHdGeHkr·dJZIndHeHkrÌdKZIndZIdS(]slpasslib.crypto.digest -- crytographic helpers used by the password hashes in passlib .. versionadded:: 1.7 iÿÿÿÿ(tdivisionN(t pbkdf2_hmacthashlibs*ignoring pure-python hashlib.pbkdf2_hmac()(tStruct(twarn(texc(t join_bytest to_native_strtjoin_byte_valuestto_bytest SequenceMixin(tiranget int_typestunicode_or_bytes_typestPY3(tmemoized_propertyt lookup_hashtHashInfotnorm_hash_namet compile_hmactpbkdf1Rii i@tmd2tmd5tsha1ssha-1tsha224ssha-224ssha2-224tsha256ssha-256ssha2-256tsha384ssha-384ssha2-384tsha512ssha-512ssha2-512tmd4tshassha-0tsha0tripemdt ripemd160s ripemd-160c C sŒ|}t|tƒs*t|ddƒ}ntjdd|jƒjƒƒ}|jdƒrƒ|d}|jdƒrƒ|d }qƒnd „}||ƒ}|r¢|Stj d |ƒ}|rT|j d d d ƒ\}}}|rë||7}n|}|r%|d|7}|r|d7}n||7}n||ƒ}|r;|St j d|||ƒn.|}|j ddƒ}t jd|||ƒ||fS(sA internal helper used by :func:`lookup_hash` -- normalize arbitrary hash name to hashlib format. if name not recognized, returns dummy record and issues a warning. :arg name: unnormalized name :returns: tuple with 2+ elements: ``(hashlib_name, iana_name|None, ... 0+ aliases)``. sutf-8s hash names[_ /]t-sscram-is-plusiûÿÿÿcS s%xtD]}||kr|SqWdS(N(t_known_hash_names(tnametrow((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pyt check_tablevs  s8(?i)^(?P[a-z]+)-?(?P\d)?-?(?P\d{3,4})?$R#trevtsizet_s0normalizing unrecognized hash name %r => %r / %rs;normalizing unrecognized hash name and format %r => %r / %r(t isinstancetstrRtretsubtstriptlowert startswithtendswithtmatchtgrouptlogtinfotreplacetwarning( R#torigR%tresulttmt iana_nameR&R't hashlib_name((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pyt_get_hash_aliases^sB!          c sΈjdƒ rDˆd krDyttˆƒSWqDtk r@qDXntj‰yˆˆdƒWntk rqn9Xd‡‡fd†}ˆ|_d|_dˆ|_|SˆdkrÊd d l m }|Sd S( s internal helper used by :func:`lookup_hash` -- lookup hash constructor by name :arg name: name (normalized to hashlib format, e.g. ``"sha256"``) :returns: hash constructor, e.g. ``hashlib.sha256()``; or None if hash can't be located. R(tnewt algorithmstc s ˆˆ|ƒS(N((tmsg(R#t new_ssl_hash(s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pytconst»sRsMwrapper for hashlib.new(%r), generated by passlib.crypto.digest.lookup_hash()Riÿÿÿÿ(R(snewR>N( R/tgetattrRtAttributeErrorR=t ValueErrort__name__t __module__t__doc__tpasslib.crypto._md4RtNone(R#RBR((R#RAs9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pyt_get_hash_constžs(        c C s©t}y ||SWnttfk r+nXt}t|tƒrÖt|ƒ}|d}||kr–t|d|ƒ}|jdkrˆ|S|||<|St |ƒ}|dkr_|rÁt d|ƒSt j |ƒ‚q_n‰t|t ƒré|St|ƒrJ|}t|ƒjƒ}|d}t |ƒ}|dkr2q_||krAq_t}nt j|ddƒ‚t ||ƒ}|||<|r¥x$|D]}|r…|||helper to detect if hash is supported by hashlib.pbkdf2_hmac()RhRiiN(t_stdlib_pbkdf2_hmacRJR#RQRERT(Rb((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pytsupported_by_hashlib_pbkdf2¶s N((RFRGRHRJR#R:R]RBR^R_ReRfRgRRkRm(((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pyR\s !   cc s|]}|dAVqdS(i\N((t.0tx((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pys Ësicc s|]}|dAVqdS(i6N((RnRo((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pys Ìsc  sýt|ƒ}|\}}}t|tƒs?t|ddƒ}nt|ƒ}||krr||ƒjƒ}|}n||kr“|d||7}n||jtƒƒj‰||jt ƒƒj‰|rÞ‡‡fd†}n‡‡fd†}||_ |S(s® This function returns an efficient HMAC function, hardcoded with a specific digest & key. It can be used via ``hmac = compile_hmac(digest, key)``. :arg digest: digest name or constructor. :arg key: secret key as :class:`!bytes` or :class:`!unicode` (unicode will be encoded using utf-8). :param multipart: request a multipart constructor instead (see return description). :returns: By default, the returned function has the signature ``hmac(msg) -> digest output``. However, if ``multipart=True``, the returned function has the signature ``hmac() -> update, finalize``, where ``update(msg)`` may be called multiple times, and ``finalize() -> digest_output`` may be repeatedly called at any point to calculate the HMAC digest so far. The returned object will also have a ``digest_info`` attribute, containing a :class:`lookup_hash` instance for the specified digest. This function exists, and has the weird signature it does, in order to squeeze as provide as much efficiency as possible, by omitting much of the setup cost and features of the stdlib :mod:`hmac` module. tparamtkeytc s(ˆƒ‰‡‡fd†}ˆj|fS(s)generated by compile_hmac(multipart=True)c s&ˆƒ}|jˆjƒƒ|jƒS(N(tupdateRM(touter(t _outer_copytinner(s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pytfinalizes (Rs(Rw(t _inner_copyRu(Rvs9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pythmacs c s<ˆƒ}|j|ƒˆƒ}|j|jƒƒ|jƒS(sgenerated by compile_hmac()(RsRM(R@RvRt(RxRu(s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pyRys    ( RR)tbytesR R`RMt translatet _TRANS_36tcopyt _TRANS_5Ct digest_info( RMRqt multipartRRBR^R_tklenRy((RxRus9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pyRÎs"       c C s2t|ƒ\}}}t|ddƒ}t|ddƒ}t|tƒs`tj|ddƒ‚n|dkr{tdƒ‚n|d kr|}ngt|tƒs·tj|dd ƒ‚n@|d krÒtd ƒ‚n%||kr÷td ||fƒ‚n||}x&t|ƒD]} ||ƒj ƒ}qW|| S(s;pkcs#5 password-based key derivation v1.5 :arg digest: digest name or constructor. :arg secret: secret to use when generating the key. may be :class:`!bytes` or :class:`unicode` (encoded using UTF-8). :arg salt: salt string to use when generating key. may be :class:`!bytes` or :class:`unicode` (encoded using UTF-8). :param rounds: number of rounds to use to generate key. :arg keylen: number of bytes to generate (if omitted / ``None``, uses digest's native size) :returns: raw :class:`bytes` of generated key .. note:: This algorithm has been deprecated, new code should use PBKDF2. Among other limitations, ``keylen`` cannot be larger than the digest size of the specified hash. Rptsecrettsalttinttroundsisrounds must be at least 1s int or Nonetkeyleniskeylen must be at least 0s'keylength too large for digest: %r > %rN( RR R)R RRURERJR RM( RMR‚RƒR…R†RBR^R_tblockR(((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pyRs(      s>Lc s’t|ddƒ}tˆddƒ‰t|ƒ}|j}tˆtƒs`tjˆddƒ‚nˆdkr{tdƒ‚n|d kr|}nBt|tƒs·tj|dd ƒ‚n|dkrÒtd ƒ‚n||d|}|t krÿt d ƒ‚n|j r!t |j |ˆˆ|ƒS|jrCt|j |ˆˆ|ƒSt||ƒ‰t|ƒ‰t‡‡‡‡fd †td|dƒDƒƒ| S(spkcs#5 password-based key derivation v2.0 using HMAC + arbitrary digest. :arg digest: digest name or constructor. :arg secret: passphrase to use to generate key. may be :class:`!bytes` or :class:`unicode` (encoded using UTF-8). :arg salt: salt string to use when generating key. may be :class:`!bytes` or :class:`unicode` (encoded using UTF-8). :param rounds: number of rounds to use to generate key. :arg keylen: number of bytes to generate. if omitted / ``None``, will use digest's native output size. :returns: raw bytes of generated key .. versionchanged:: 1.7 This function will use the first available of the following backends: * `fastpbk2 `_ * :func:`hashlib.pbkdf2_hmac` (only available in py2 >= 2.7.8, and py3 >= 3.4) * builtin pure-python backend See :data:`passlib.crypto.digest.PBKDF2_BACKENDS` to determine which backend(s) are in use. RpR‚RƒR„R…isrounds must be at least 1s int or NoneR†skeylen must be at least 1skeylen too long for digestc3 s1|]'}ˆˆˆˆt|ƒƒˆƒVqdS(N(t _pack_uint32(Rnti(t calc_blockt keyed_hmacR…Rƒ(s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pys ¾sN(R RR^R)R RRURERJt MAX_UINT32t OverflowErrorRkRjR#RmRlRt_get_pbkdf2_looperRR (RMR‚RƒR…R†RR^t block_count((RŠR‹R…Rƒs9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pyR_s6$          tPASSLIB_PBKDF2_BACKENDtanys from-bytes(tpartialcC s tt|ƒS(N(R’t_pbkdf2_looper(R^((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pyRŽÌscC shtj}d}|||ƒ}x7t|dƒD]%}||ƒ}||||ƒN}q/W|j||ƒS(sk py3-only implementation of pbkdf2 inner loop; uses 'int.from_bytes' + integer XOR tbigi(R„t from_bytesR R (R^R‹RMR…R•tBIGtaccumR(((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pyR“Ïs  tunpack(tsys_bitsc C sžy t|SWntk rnXtrH|d@ rH|d?}d|}nX|d@stry|d?}d|}|d7}q |d?}d|}ntd|ƒ‚t|ƒ}td |d d jd „t|ƒDƒƒd d jd„t|ƒDƒƒƒ}dj|}x(t|ƒD]}|d||f7}qW|dj|7}t |ddƒ}tdtd|ƒ}tƒ} t ||| ƒ| d} | t|<| S(s) We want a helper function which performs equivalent of the following:: def helper(keyed_hmac, digest, rounds): accum = digest for _ in irange(rounds - 1): digest = keyed_hmac(digest) accum ^= digest return accum However, no efficient way to implement "bytes ^ bytes" in python. Instead, using approach where we dynamically compile a helper function based on digest size. Instead of a single `accum` var, this helper breaks the digest into a series of integers. It stores these in a series of`accum_` vars, and performs `accum ^= digest` by unpacking digest and perform xor for each "accum_ ^= digest_". this keeps everything in locals, avoiding excessive list creation, encoding or decoding, etc. :param digest_size: digest size to compile for, in bytes. (must be multiple of 4). :return: helper function with call signature outlined above. iis=%dQs=%dQIiis=%dIsunsupported digest size: %dR^t accum_varss, cs s|]}d|VqdS(sacc_%dN((RnR‰((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pys &st digest_varscs s|]}d|VqdS(sdig_%dN((RnR‰((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pys 'ss def helper(keyed_hmac, digest, rounds): '''pbkdf2 loop helper for digest_size={digest_size}''' unpack_digest = struct.unpack {accum_vars} = unpack_digest(digest) for _ in irange(1, rounds): digest = keyed_hmac(digest) {digest_vars} = unpack_digest(digest) s acc_%d ^= dig_%d s% return struct.pack({accum_vars}) s9texecR tstructthelper( t _looper_cacheROt _have_64_bittNotImplementedErrorRtdicttjoinR R\tcompileteval( R^tcounttfmtRttdicttsourceR‰tcodetgdicttldictRž((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pyRŽçs@           "    (thexlify(t int_to_bytescC stS(N(R“(R^((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pyRŽXscC snt}t||ƒdƒ}x=t|dƒD]+}||ƒ}|t||ƒdƒN}q,Wt|t|ƒƒS(Nii(t_hexlifyR„R R®R`(R‹RMR…R­R—R(((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pyR“[s  R­t fastpbkdf2s hashlib-sslsbuiltin-igffffffö?IIÿÿÿÿllÿÿÿÿ(RR(RR(Rssha-1(Rssha-224ssha2-224(Rssha-256ssha2-256(Rssha-384ssha2-384(Rssha-512ssha2-512(smd4smd4(Rssha-0R(RR(R s ripemd-160(sanys from-bytes(sanysunpacks from-bytes(JRHt __future__RRtloggingt getLoggerRFR3RRlRGtdebugRJt ImportErrorR+tosRRtwarningsRR°RjtpasslibRt passlib.utilsRRRR R tpasslib.utils.compatR R R Rtpasslib.utils.decorRt__all__RŒt MAX_UINT64R"RNR<RKRTRtcleart clear_cacheRRR~R|RRtpackRˆtenvirontgett_force_backendt functoolsR’RŽR“t_builtin_backendR™R RŸtbinasciiR­R¯R®tbtPBKDF2_BACKENDStPBKDF2_SPEED_FACTOR(((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pytsª          ("    @ / i  #o P ? h     f