σ φ 5Xc@ΐsdZddlmZmZddlZejeƒZddlm Z ddl m Z m Z ddlm Z mZmZddlmZmZmZddlmZddljjZd gZed ƒZed ƒZed ƒZd ejej ej!ej"ej#ej$fd „ƒYZ dS(s/passlib.handlers.scrypt -- scrypt password hashi(twith_statementtabsolute_importN(tscrypt(th64tto_bytes(Rt b64s_decodet b64s_encode(tut bascii_to_strtsuppress_cause(t classpropertyRs$scrypt$s$7$t$cBΐs7eZdZdZdZdZeZeefZ d Z d Z d Z d Z d Zd Zd ZdZed d„ƒZed„ƒZed„ƒZed„ƒZed„ƒZd„Zd d„Zeed„ƒZd„Zed„ƒZed„ƒZ edd„ƒZ!eded„ƒZ"d„Z#d„Z$RS(!s“ This class implements an SCrypt-based password [#scrypt-home]_ hash, and follows the :ref:`password-hash-api`. It supports a variable-length salt, a variable number of rounds, as well as some custom tuning parameters unique to scrypt (see below). The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :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. Defaults to 16 bytes, but can be any value between 0 and 1024. :type rounds: int :param rounds: Optional number of rounds to use. Defaults to 16, but must be within ``range(1,32)``. .. warning:: Unlike many hash algorithms, increasing the rounds value will increase both the time *and memory* required to hash a password. :type block_size: int :param block_size: Optional block size to pass to scrypt hash function (the ``r`` parameter). Useful for tuning scrypt to optimal performance for your CPU architecture. Defaults to 8. :type parallelism: int :param parallelism: Optional parallelism to pass to scrypt hash function (the ``p`` parameter). Defaults to 1. :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. .. note:: The underlying scrypt hash function has a number of limitations on it's parameter values, which forbids certain combinations of settings. The requirements are: * ``linear_rounds = 2**`` * ``linear_rounds < 2**(16 * block_size)`` * ``block_size * parallelism <= 2**30-1`` .. todo:: This class currently does not support configuring default values for ``block_size`` or ``parallelism`` via a :class:`~passlib.context.CryptContext` configuration. Rtidenttsaltt salt_sizetroundst block_sizet parallelismi iiiitlog2icKΐsΓtt|ƒj|}|dk rit|tjƒrEt|ƒ}n|j|d|j dƒƒ|_ ny$t j d|j >|j |jƒWn/tk rΎ}ttdt|ƒƒƒ‚nX|S(Ntrelaxedis&scrypt: invalid settings combination: (tsuperRtusingtNonet isinstancetuhtnative_string_typestintt_norm_block_sizetgetRt_scrypttvalidatetdefault_roundsRt ValueErrorR tstr(tclsRtkwdstsubclsterr((s;/usr/lib/python2.7/site-packages/passlib/handlers/scrypt.pyR›s $$ cCΐs||j|ƒS(N(tparse(R"thash((s;/usr/lib/python2.7/site-packages/passlib/handlers/scrypt.pyt from_string―scCΐsZ|j|ƒ\}}t|d|jtƒdƒ}|rD||ƒStjj|ƒ‚dS(Ns_parse_%s_string(t _parse_identtgetattrtstript_UDOLLARRRtexctInvalidHashError(R"R'R tsuffixtfunc((s;/usr/lib/python2.7/site-packages/passlib/handlers/scrypt.pyR&³s  c Cΐs*|jdƒ}t|ƒdkr3|\}}}n<t|ƒdkrZ|\}}d}ntjj|dƒ‚|jdƒ}t|ƒdkr’|\}}}ntjj|dƒ‚tdtdt|dƒd t|dƒd t|dƒd t |j d ƒƒd |r#t |j d ƒƒndƒS(NR iismalformed hasht,smalformed settings fieldR RRRR tasciitchecksum( tsplittlenRRR-tMalformedHashErrortdictt IDENT_SCRYPTRRtencode( R"R/tpartstparamsR tdigesttnstrtbstrtpstr((s;/usr/lib/python2.7/site-packages/passlib/handlers/scrypt.pyt_parse_scrypt_stringΗs&  cCΐs|jdƒjdƒ}t|ƒdkr9|\}}n3t|ƒdkr]|\}d}ntjjƒ‚t|ƒdkr–tjj|dƒ‚ntdtdt j |d ƒd t j |dd !ƒd t j |d d!ƒd |dd |rt j |ƒndƒS(NR2R iii sparams field too shortR RRiRR R3( R9R4R5RRR-R6R7tIDENT_7Rt decode_int6t decode_int30t decode_bytes(R"R/R:R;R<((s;/usr/lib/python2.7/site-packages/passlib/handlers/scrypt.pyt_parse_7_stringυs    c Cΐsς|j}|tkrSd|j|j|jtt|jƒƒtt|jƒƒfS|j}y|j dƒWn#t k r’t t dƒƒ‚nXtdj dtj|jƒtj|jƒtj|jƒ|jdtj|jƒgƒƒSdS(Ns$scrypt$ln=%d,r=%d,p=%d$%s$%sR2s.scrypt $7$ hashes dont support non-ascii saltsts$7$R (R R8RRRRRR R3tdecodetUnicodeDecodeErrorR tNotImplementedErrortjoinRt encode_int6t encode_int30t encode_bytes(tselfR R ((s;/usr/lib/python2.7/site-packages/passlib/handlers/scrypt.pyt to_strings*     cKΐs;tt|ƒj||dkr%n|j|ƒ|_dS(N(RRt__init__RRR(RNRR#((s;/usr/lib/python2.7/site-packages/passlib/handlers/scrypt.pyRP1s c Cΐs"tj||ddddd|ƒS(NtminitparamRR(Rt norm_integer(R"RR((s;/usr/lib/python2.7/site-packages/passlib/handlers/scrypt.pyR>scCΐs7tt|ƒjƒ}|jtkr3t|ƒ}n|S(N(RRt_generate_saltR RAR(RNR ((s;/usr/lib/python2.7/site-packages/passlib/handlers/scrypt.pyRTBscCΐstjS(N(Rtbackend_values(R"((s;/usr/lib/python2.7/site-packages/passlib/handlers/scrypt.pytbackendsPscCΐstjS(N(Rtbackend(R"((s;/usr/lib/python2.7/site-packages/passlib/handlers/scrypt.pyt get_backendTstanycCΐs:y|j|dtƒtSWntjjk r5tSXdS(Ntdryrun(t set_backendtTrueRR-tMissingBackendErrortFalse(R"tname((s;/usr/lib/python2.7/site-packages/passlib/handlers/scrypt.pyt has_backendXs cCΐstj|d|ƒdS(NRZ(Rt _set_backend(R"R_RZ((s;/usr/lib/python2.7/site-packages/passlib/handlers/scrypt.pyR[`sc CΐsMt|ddƒ}tj||jdd|j>d|jd|jd|jƒS(NRRtsecrettnitrtptkeylen(RRRR RRRt checksum_size(RNRb((s;/usr/lib/python2.7/site-packages/passlib/handlers/scrypt.pyt_calc_checksumgs(cKΐs2|jt|ƒjkrtStt|ƒj|S(sR mark hash as needing update if rounds is outside desired bounds. (RttypeR\RRt_calc_needs_update(RNR#((s;/usr/lib/python2.7/site-packages/passlib/handlers/scrypt.pyRjps(sidentssaltRsroundss block_sizes parallelismN(%t__name__t __module__t__doc__R_t setting_kwdsRgR8t default_identRAt ident_valuestdefault_salt_sizet max_salt_sizeRt min_roundst max_roundst rounds_costRRt classmethodRRR(R&R@RERORPR^RRTR RVRXR`R[RhRj(((s;/usr/lib/python2.7/site-packages/passlib/handlers/scrypt.pyR!sB@    .    (%Rmt __future__RRtloggingt getLoggerRktlogtpasslib.cryptoRRt passlib.utilsRRtpasslib.utils.binaryRRtpasslib.utils.compatRRR tpasslib.utils.decorR tpasslib.utils.handlerstutilsthandlersRt__all__R8RAR,tParallelismMixint HasRoundst HasRawSalttHasRawChecksumt HasManyIdentstGenericHandler(((s;/usr/lib/python2.7/site-packages/passlib/handlers/scrypt.pyts     !