ó ¶õ„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?nJe:d]kstC‚ddClDmEZFddDlmGZGdE„Z=dF„Z>dBZ?e:e?krpdZZ ngerdGnde rŽdHnddIe?gD]ZHeHrœeH^qœZIdGeIkrÉdJZJndHeIkrÞdKZJndZJdS(^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}|sct‚||kr®t|d|ƒ}|j dkr |sœt‚|S|||<|St |ƒ}|dkrw|rÙt d|ƒSt j|ƒ‚qwn‰t|t ƒr|St|ƒrb|}t|ƒjƒ}|d}t |ƒ}|dkrJqw||krYqwt}nt j|ddƒ‚t ||ƒ}|||<|rèxO|D]D}|r|j|ƒd|gksÔtd|ƒ‚|||helper to detect if hash is supported by hashlib.pbkdf2_hmac()RjRkiN(t_stdlib_pbkdf2_hmacRJR#RQRERU(Rd((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pytsupported_by_hashlib_pbkdf2¶s N((RFRGRHRJR#R:R_RBR`RaRgRhRiRRmRo(((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((RpRq((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pys Ìsc  st|ƒ}|\}}}|dks3tdƒ‚t|tƒsWt|ddƒ}nt|ƒ}||krŠ||ƒ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. isblock size too smalltparamtkeytc 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 (Ru(Ry(t _inner_copyRw(Rxs9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pythmacs c s<ˆƒ}|j|ƒˆƒ}|j|jƒƒ|jƒS(sgenerated by compile_hmac()(RuRM(R@RxRv(RzRw(s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pyR{s    ( RRRR)tbytesR RbRMt translatet _TRANS_36tcopyt _TRANS_5Ct digest_info( RMRst multipartRRBR`RatklenR{((RzRws9/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. Rrtsecrettsalttinttroundsisrounds must be at least 1s int or Nonetkeyleniskeylen must be at least 0s'keylength too large for digest: %r > %rN( RR R)R RRVRERJR RM( RMR„R…R‡RˆRBR`RatblockR(((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. RrR„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(Rpti(t calc_blockt keyed_hmacR‡R…(s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pys ¾sN(R RR`R)R RRVRERJt MAX_UINT32t OverflowErrorRmRlR#RoRnRt_get_pbkdf2_looperRR (RMR„R…R‡RˆRR`t block_count((RŒRR‡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`RRMR‡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((RpR‹((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pys &st digest_varscs s|]}d|VqdS(sdig_%dN((RpR‹((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^tcompiletevalt __source__( R`tcounttfmtRŸttdicttsourceR‹tcodetgdicttldictR ((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pyRçsB           "     thexlify(R°(t int_to_bytescC stS(N(R•(R`((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pyRXscC snt}t||ƒdƒ}x=t|dƒD]+}||ƒ}|t||ƒdƒN}q,Wt|t|ƒƒS(Nii(t_hexlifyR†R R±Rb(RRMR‡R°R™R(((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pyR•[s  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(sanyshexlify(KRHt __future__RRtloggingt getLoggerRFR3RRnRGtdebugRJt ImportErrorR+tosRŸRtwarningsRR³RltpasslibRt passlib.utilsRRRR R tpasslib.utils.compatR R R Rtpasslib.utils.decorRt__all__RŽt MAX_UINT64R"RNR<RKRURtcleart clear_cacheRRR€R~RRtpackRŠtenvironRWt_force_backendt functoolsR”RR•t_builtin_backendR›R¢R¡RRtbinasciiR°R²R±tbtPBKDF2_BACKENDStPBKDF2_SPEED_FACTOR(((s9/usr/lib/python2.7/site-packages/passlib/crypto/digest.pyts¬          ("    @ / i  #o P ? h     f