+
    ¢THiN  ã                   óÒ   € R t ^ RIHu Ht ^ RIHtHt ^ RIH	t	H
t
HtHt ^ RIHtHt ^ RIHt R.t ! R R]P&                  ]P(                  ]P*                  ]P,                  4      tR# )z!hash for SCRAM credential storageN)Únorm_hash_nameÚpbkdf2_hmac)ÚconsteqÚsaslprepÚ
splitcommaÚto_native_str)Úab64_decodeÚab64_encode)Úbascii_to_strÚscramc                   ó  a a€ ] tR t^t oRtR tRtRt^tRt	Rt
^tRtRt. ROt. ROtRt]R 4       t]RR l4       t]R	 4       t]R
 4       tR t]RV 3R ll4       tRV 3R lltRR lt]R 4       tV 3R ltRR lt]RR l4       tRtVtV ;t # )r   a¶  This class provides a format for storing SCRAM passwords, and follows
the :ref:`password-hash-api`.

It supports a variable-length salt, and a variable number of rounds.

The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords:

:type salt: bytes
:param salt:
    Optional salt bytes.
    If specified, the length must be between 0-1024 bytes.
    If not specified, a 12 byte salt will be autogenerated
    (this is recommended).

:type salt_size: int
:param salt_size:
    Optional number of bytes to use when autogenerating new salts.
    Defaults to 12 bytes, but can be any value between 0 and 1024.

:type rounds: int
:param rounds:
    Optional number of rounds to use.
    Defaults to 100000, but must be within ``range(1,1<<32)``.

:type algs: list of strings
:param algs:
    Specify list of digest algorithms to use.

    By default each scram hash will contain digests for SHA-1,
    SHA-256, and SHA-512. This can be overridden by specify either be a
    list such as ``["sha-1", "sha-256"]``, or a comma-separated string
    such as ``"sha-1, sha-256"``. Names are case insensitive, and may
    use :mod:`!hashlib` or `IANA <http://www.iana.org/assignments/hash-function-text-names>`_
    hash names.

: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.

    .. versionadded:: 1.6

In addition to the standard :ref:`password-hash-api` methods,
this class also provides the following methods for manipulating Passlib
scram hashes in ways useful for pluging into a SCRAM protocol stack:

.. automethod:: extract_digest_info
.. automethod:: extract_digest_algs
.. automethod:: derive_digest
ú$scram$i   i † ÚlinearNc                ó¸   € \        VR4      pV P                  V4      pVP                  pV'       g   \        R4      hVP                  VP
                  WB,          3# )aH  return (salt, rounds, digest) for specific hash algorithm.

:type hash: str
:arg hash:
    :class:`!scram` hash stored for desired user

:type alg: str
:arg alg:
    Name of digest algorithm (e.g. ``"sha-1"``) requested by client.

    This value is run through :func:`~passlib.crypto.digest.norm_hash_name`,
    so it is case-insensitive, and can be the raw SCRAM
    mechanism name (e.g. ``"SCRAM-SHA-1"``), the IANA name,
    or the hashlib name.

:raises KeyError:
    If the hash does not contain an entry for the requested digest
    algorithm.

:returns:
    A tuple containing ``(salt, rounds, digest)``,
    where *digest* matches the raw bytes returned by
    SCRAM's :func:`Hi` function for the stored password,
    the provided *salt*, and the iteration count (*rounds*).
    *salt* and *digest* are both raw (unencoded) bytes.
Úianazscram hash contains no digests)r   Úfrom_stringÚchecksumÚ
ValueErrorÚsaltÚrounds)ÚclsÚhashÚalgÚselfÚchkmaps   &&&  Ú8/usr/lib/python3/dist-packages/passlib/handlers/scram.pyÚextract_digest_infoÚscram.extract_digest_infoj   sM   € ô> ˜S &Ó)ˆØ�‰˜tÓ$ˆØ—‘ˆßÜÐ=Ó>Ð>Ø�y‰y˜$Ÿ+™+ v¥{Ð2Ð2ó    c                óŠ   € V P                  V4      P                  pVR8X  d   V# V Uu. uF  p\        WB4      NK  	  up# u upi )a’  Return names of all algorithms stored in a given hash.

:type hash: str
:arg hash:
    The :class:`!scram` hash to parse

:type format: str
:param format:
    This changes the naming convention used by the
    returned algorithm names. By default the names
    are IANA-compatible; possible values are ``"iana"`` or ``"hashlib"``.

:returns:
    Returns a list of digest algorithms; e.g. ``["sha-1"]``
r   )r   Úalgsr   )r   r   Úformatr    r   s   &&&  r   Úextract_digest_algsÚscram.extract_digest_algs�   sB   € ð( �‰˜tÓ$×)Ñ)ˆØ�VÔØˆKÙ7;Ó<±t°”˜sÖ+±tÑ<Ð<ùÒ<s   ©A c                ó|   € \        V\        4      '       d   VP                  R4      p\        V\	        V4      W#4      # )aÏ  helper to create SaltedPassword digest for SCRAM.

This performs the step in the SCRAM protocol described as::

    SaltedPassword  := Hi(Normalize(password), salt, i)

:type password: str or utf-8 bytes
:arg password: password to run through digest

:type salt: bytes
:arg salt: raw salt data

:type rounds: int
:arg rounds: number of iterations.

:type alg: str
:arg alg: name of digest to use (e.g. ``"sha-1"``).

:returns:
    raw bytes of ``SaltedPassword``
zutf-8)Ú
isinstanceÚbytesÚdecoder   r   )r   Úpasswordr   r   r   s   &&&&&r   Úderive_digestÚscram.derive_digest©   s5   € ô. �h¤×&Ò&Ø—‘ wÓ/ˆHô ˜3¤¨Ó 2°DÓAÐAr   c                ó˜  € \        VR R4      pVP                  R4      '       g    \        P                  P	                  V 4      hVR,          P                  R4      p\        V4      ^8w  d    \        P                  P                  V 4      hVw  r4p\        V4      pV\        V4      8w  d    \        P                  P                  V 4      h \        VP                  R 4      4      pT'       g    \        P                  P                  T 4      hRT9   dN   Rp/ p	TP                  R4       F3  p
T
P                  R4      w  r¼ \        TP                  R 4      4      Y›&   K5  	  MTpRp	T ! TTT	TR7      #   \         d!    \        P                  P                  T 4      hi ; i  \         d!    \        P                  P                  T 4      hi ; i)	Úasciir   r   :é   NNÚ$Ú=NÚ,)r   r   r   r    )r   Ú
startswithÚuhÚexcÚInvalidHashErrorÚsplitÚlenÚMalformedHashErrorÚintÚstrr   ÚencodeÚ	TypeError)r   r   ÚpartsÚ
rounds_strÚsalt_strÚchk_strr   r   r    r   Úpairr   Údigests   &&           r   r   Úscram.from_stringÆ   s�  € ä˜T 7¨FÓ3ˆØ�‰˜y×)Ò)Ü—&‘&×)Ñ)¨#Ó.Ð.Ø�R•—‘˜sÓ#ˆÜˆu‹:˜Œ?Ü—&‘&×+Ñ+¨CÓ0Ð0Ø(-Ñ%ˆ
˜gô �Z“ˆØœ˜V›Ô$Ü—&‘&×+Ñ+¨CÓ0Ð0ð	1Ü˜xŸ™¨wÓ7Ó8ˆD÷
 ä—&‘&×+Ñ+¨CÓ0Ð0Ø�'Œ>àˆDØˆFØŸ™ cÖ*�Ø"Ÿj™j¨›o‘�ð9Ü"-¨f¯m©m¸GÓ.DÓ"E�F“Kò +ð ˆDØˆFñ ØØØØô	
ð 	
øô/ ô 	1Ü—&‘&×+Ñ+¨CÓ0Ð0ð	1ûô !ô 9ÜŸ&™&×3Ñ3°CÓ8Ð8ð9ús   ÃE0 Ä?FÅ0+FÆ+G	c                óÌ   a€ \        \        V P                  4      4      pV P                  oR P	                  V3R lV P
                   4       4      pRV P                  W3,          # )r0   c           	   3   ób   <"  € T F$  q R \        \        SV,          4      4       2x € K&  	  R# 5i)r/   N)r
   r	   )Ú.0r   r   s   & €r   Ú	<genexpr>Ú"scram.to_string.<locals>.<genexpr>ù   s,   øé € ð 
ÙJSÀ3ˆe�1”]¤;¨v°c­{Ó#;Ó<Ð=Õ>Ë)ùs   ƒ,/z$scram$%d$%s$%s)r
   r	   r   r   Újoinr    r   )r   r   r?   r   s   &  @r   Ú	to_stringÚscram.to_stringö   sT   ø€ Üœ[¨¯©Ó3Ó4ˆØ—‘ˆØ—(‘(ô 
ØJNÏ)Ê)ó
ó 
ˆð ! D§K¡K°Ð#?Õ?Ð?r   c                ót   <€ Ve	   Ve   Q hTp\         SV `  ! R/ VB pVe   V P                  V4      Vn        V# )N© )ÚsuperÚusingÚ
_norm_algsÚdefault_algs)r   rP   r    ÚkwdsÚsubclsÚ	__class__s   &&&, €r   rN   Úscram.usingþ   sM   ø€ ð ÒØÒ'Ð'Ð'ØˆLô ‘’Ñ& Ñ&ˆð Ò#Ø"%§.¡.°Ó">ˆFÔØˆr   c                ó†  <€ \         SV `  ! R/ VB  V P                  pVe"   Ve   \        R4      hV P	                  V4      pMxVe!   V P	                  VP                  4       4      pMTV P                  '       d8   \        V P                  4      pV P	                  V4      V8X  g   Q RV: 24       hM\        R4      hWn
        R # )Nz+checksum & algs kwds are mutually exclusivezinvalid default algs: zno algs list specifiedrL   )rM   Ú__init__r   ÚRuntimeErrorrO   ÚkeysÚuse_defaultsÚlistrP   r;   r    )r   r    rQ   Ú
digest_maprS   s   &&, €r   rV   Úscram.__init__  s°   ø€ Ü‰ÒÑ ˜4Ò ð —]‘]ˆ
ØÒØÒ%Ü"Ð#PÓQÐQØ—?‘? 4Ó(‰DØÒ#à—?‘? :§?¡?Ó#4Ó5‰DØ××ÐÜ˜×)Ñ)Ó*ˆDØ—?‘? 4Ó(¨DÔ0ÐSÐ4JÈ4É(Ð2SÓSÑ0äÐ4Ó5Ð5ØŽ	r   c                ó¶  € \        V\        4      '       g"   \        P                  P	                  VR R4      hVP                  4        F{  w  r4V\        VR4      8w  d   \        RV: 24      h\        V4      ^	8”  d   \        RV: 24      h\        V\        4      '       d   K\  \        P                  P	                  VRR4      h	  RV9  d   \        R4      hV# )	Údictr   r   z(malformed algorithm name in scram hash: z.SCRAM limits algorithm names to 9 characters: z	raw bytesÚdigestsúsha-1ú-sha-1 must be in algorithm list of scram hash)
r%   r^   r2   r3   ÚExpectedTypeErrorÚitemsr   r   r6   r&   )r   r   Úrelaxedr   rA   s   &&&  r   Ú_norm_checksumÚscram._norm_checksum   sÂ   € Ü˜(¤D×)Ò)Ü—&‘&×*Ñ*¨8°V¸ZÓHÐHØ#Ÿ>™>Ö+‰KˆCØ”n S¨&Ó1Ô1Ü Ð#KÈCÉ7Ð!SÓTÐTÜ�3‹x˜!Œ|Ü ØDÀSÁGÐLóð ô ˜f¤e×,Ô,Ü—f‘f×.Ñ.¨v°{ÀIÓNÐNñ ,ð ˜(Ô"äÐLÓMÐMØˆr   c                ó  € \        V\        4      '       d   \        V4      p\        R V 4       4      p\        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       d   \        R4      hRV9  d   \        R4      hV# )znormalize algs parameterc              3   ó:   "  € T F  p\        VR 4      x € K  	  R# 5i)r   N)r   ©rE   r   s   & r   rF   Ú#scram._norm_algs.<locals>.<genexpr>7  s   é € ÐB¹T°c”n S¨&×1Ð1»Tùs   ‚c              3   ó>   "  € T F  p\        V4      ^	8„  x € K  	  R# 5i)é	   N)r6   ri   s   & r   rF   rj   8  s   é € Ð,¡t Œs�3‹x˜!Ž|£tùs   ‚TFz-SCRAM limits alg names to max of 9 charactersr`   ra   )r%   r9   r   ÚsortedÚanyr   )r   r    s   &&r   rO   Úscram._norm_algs2  sq   € ô �dœC× Ò Ü˜dÓ#ˆDÜÑB¹TÓBÓBˆß‹3Ñ,¡tÓ,�3�3Š3Ñ,¡tÓ,×,Ò,ÜÐLÓMÐMØ˜$ÔäÐLÓMÐMØˆr   c                ó�   <€ \        V P                  4      P                  V P                  4      '       g   R # \        SV `  ! R/ VB # )TrL   )Úsetr    Ú
issupersetrP   rM   Ú_calc_needs_update)r   rQ   rS   s   &,€r   rs   Úscram._calc_needs_update?  s<   ø€ ô �4—9‘9‹~×(Ñ(¨×):Ñ):×;Ò;Ùô ‰wÒ)Ñ1¨DÑ1Ð1r   c                ó¼   aaaa€ V P                   oV P                  oV P                  oV'       d   S! SSSV4      # \        VVVV3R  lV P                   4       4      # )c              3   ó<   <"  € T F  qS! SSSV4      3x € K  	  R # 5i©NrL   )rE   r   r   r   r   Úsecrets   & €€€€r   rF   Ú'scram._calc_checksum.<locals>.<genexpr>Q  s   øé € ÐPÁi¸s™$˜v t¨V°SÓ9Õ:Ãiùs   ƒ)r   r   r)   r^   r    )r   rx   r   r   r   r   s   &f&@@@r   Ú_calc_checksumÚscram._calc_checksumI  sI   û€ Ø—‘ˆØ�y‰yˆØ×!Ñ!ˆßá˜  f¨cÓ2Ð2ä×PÀdÇiÂiÓPÓPÐPr   c                óª  € \         P                  ! V4       V P                  V4      pVP                  pV'       g'   \	        R V P
                   RV P
                   R24      hV'       d£   R;rgVP                  4        Fn  w  r‰VP                  W4      p
\        V	4      \        V
4      8w  d)   \	        RV R\        V	4      : R\        V
4      : 24      h\        W©4      '       d   RpKl  RpKp  	  V'       d   V'       d   \	        R4      hV# VP                   F.  pW…9   g   K  VP                  W4      p
\        W¥V,          4      u # 	  \        R	4      h)
z	expected z hash, got z config string insteadFz
mis-sized z digest in scram hash: z != Tz4scram hash verified inconsistently, may be corruptedzsha-1 digest not found!)r2   Úvalidate_secretr   r   r   Únamerc   rz   r6   r   Ú_verify_algsÚAssertionError)r   rx   r   Úfullr   r   ÚcorrectÚfailedr   rA   Úothers   &&&&       r   ÚverifyÚscram.verifyS  s6  € ä
×Ò˜6Ô"Ø�‰˜tÓ$ˆØ—‘ˆßÜØ˜CŸH™H˜: [°·±°
Ð:PÐQóð ÷ Ø$Ð$ˆGØ%Ÿ|™|ž~‘�Ø×+Ñ+¨FÓ8�ô
 �v“;¤# e£*Ô,Ü$Ø$ S EÐ)@ÄÀVÃÁÈtÔTWÐX]ÓT^ÑSaÐbóð ô ˜5×)Ò)Ø"’Gà!’Fñ  .÷ Ÿ6Ü Ð!WÓXÐXØˆNð ×$Ô$ˆCØŽ}Ø×+Ñ+¨FÓ8�Ü˜u¨S¥kÓ2Ò2ñ %ô Ð6Ó7Ð7r   )r    )r   Ú	salt_sizer   r    l   ÿÿ )r`   úsha-256úsha-512)rˆ   r‰   zsha-224zsha-384r`   )r   )NNrw   )F)!Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r~   Úsetting_kwdsÚidentÚdefault_salt_sizeÚmax_salt_sizeÚdefault_roundsÚ
min_roundsÚ
max_roundsÚrounds_costrP   r   r    Úclassmethodr   r"   r)   r   rI   rN   rV   re   rO   rs   rz   r…   Ú__static_attributes__Ú__classdictcell__Ú__classcell__)rS   Ú__classdict__s   @@r   r   r      s  ù‡ € ñ4ð| €DØ:€LØ€Eð ÐØ€Mð €NØ€JØ€JØ€Kò
 3€Lò I€Lð €Dàñ#3ó ð#3ðJ ó=ó ð=ð0 ñBó ðBð8 ñ-
ó ð-
ò^@ð öó ð÷ô&ð$ ñ
ó ð
õ2ôQð ó'8ó ÷'8ð '8r   )rŽ   Úpasslib.utils.handlersÚutilsÚhandlersr2   Úpasslib.crypto.digestr   r   Úpasslib.utilsr   r   r   r   Úpasslib.utils.binaryr   r	   Úpasslib.utils.compatr
   Ú__all__Ú	HasRoundsÚ
HasRawSaltÚHasRawChecksumÚGenericHandlerr   rL   r   r   Ú<module>r¨      sQ   ðÙ 'ç #Ð #ß =ß FÓ Fß 9Ý .ð ð€ô
m8ˆB�L‰L˜"Ÿ-™-¨×):Ñ):¸B×<MÑ<Mö m8r   