o
    l>j(                     @  s^  d Z ddlmZ ddlZddlmZ ddlmZmZ ddl	m
Z
mZ ddlmZ ddlmZmZmZmZmZmZmZmZmZ erVddlZejd	krPdd
lmZ nedddZddlmZ ddlmZmZ g dZ dZ!d.ddZ"d/ddZ#d0ddZ$d1d2d d!Z%d3d#d$Z&d4d&d'Z'G d(d) d)eZ(ed*edZ)G d+d dee)ef Z*G d,d- d-e*e+ Z,dS )5zlVarious utility functions.

This module contains various functions used throughout the rest of the project.
    )annotationsN)abstractmethod)urlsafe_b64decodeurlsafe_b64encode)Fieldfields)BytesIO)	TYPE_CHECKINGAnyClassVarHashableMappingSequenceTypeVarget_type_hintsoverload)      )Selfr   _DataClassMapping)bound)default_backend)hasheshmac)websafe_encodewebsafe_decodesha256hmac_sha256	bytes2int	int2bytes   databytesreturnc                 C  s$   t t  t }||  | S )ztProduces a SHA256 hash of the input.

    :param data: The input data to hash.
    :return: The resulting hash.
    )r   HashSHA256r   updatefinalize)r!   h r)   @/home/thesage/.local/lib/python3.10/site-packages/fido2/utils.pyr   M   s   
r   keyc                 C  s&   t | t t }|| | S )zPerforms an HMAC-SHA256 operation on the given data, using the given key.

    :param key: The key to use.
    :param data: The input data to hash.
    :return: The resulting hash.
    )r   HMACr   r%   r   r&   r'   )r+   r!   r(   r)   r)   r*   r   X   s   
r   valueintc                 C  s   t | dS )zParses an arbitrarily sized integer from a byte string.

    :param value: A byte string encoding a big endian unsigned integer.
    :return: The parsed int.
    big)r.   
from_bytes)r-   r)   r)   r*   r   d   s   r   minlenc                 C  sX   g }| dkr| d| @  | dL } | dks| |  |dg|t|   tt|S )zEncodes an int as a byte string.

    :param value: The integer value to encode.
    :param minlen: An optional minimum length for the resulting byte string.
    :return: The value encoded as a big endian byte string.
          r   )appendextendlenr"   reversed)r-   r2   bar)   r)   r*   r   m   s   
r   str | bytesc                 C  s<   t | tr| d}nt| }|dt| d  7 }t|S )zDecodes a websafe-base64 encoded string.
    See: "Base 64 Encoding with URL and Filename Safe Alphabet" from Section 5
    in RFC4648 without padding.

    :param data: The input to decode.
    :return: The decoded bytes.
    ascii   =   )
isinstancestrencoder"   r7   r   )r!   data_br)   r)   r*   r   }   s
   
r   r?   c                 C  s   t | dddS )zEncodes a byte string into websafe-base64 encoding.

    :param data: The input to encode.
    :return: The encoded string.
    r<       r;   )r   replacedecode)r!   r)   r)   r*   r      s   r   c                      s.   e Zd ZdZdddZdd fddZ  ZS )
ByteBufferz6BytesIO-like object with the ability to unpack values.fmtr?   c                 C  s    t |}|| |jd S )zReads and unpacks a value from the buffer.

        :param fmt: A struct format string yielding a single value.
        :return: The unpacked value.
        r   )structStructunpackreadsize)selfrF   sr)   r)   r*   rI      s   
zByteBuffer.unpackr1   rK   
int | Noner#   r"   c                   s@   t  |}|dur|dkrt||krtd|t|f |S )zLike BytesIO.read(), but checks the number of bytes read and raises an error
        if fewer bytes were read than expected.
        Nr   z,Not enough data to read (need: %d, had: %d).)superrJ   r7   
ValueError)rL   rK   r!   	__class__r)   r*   rJ      s   zByteBuffer.read)rF   r?   r1   )rK   rN   r#   r"   )__name__
__module____qualname____doc__rI   rJ   __classcell__r)   r)   rQ   r*   rE      s    
	rE   _Tc                   @  s   e Zd ZU dZded< dd Zeed"d
dZdd Z	dd Z
dd Zedd Zeed#ddZeed$ddZeed%ddZedd Zed%dd Zd!S )&r   z7A data class with members also accessible as a Mapping.zClassVar[dict[str, Field[Any]]]__dataclass_fields__c                 C  s   t t| }|  t| di  t| D ]?}|| j| |< t| |j}|d urRz| 	||j |}t| |j| W q t
ttfyQ   td|j d| jj w qd S )N_field_keyszError parsing field  for )r   typeobject__setattr__r   r[   _get_field_keygetattrname_parse_value	TypeErrorKeyErrorrP   rR   rT   )rL   hintsfr-   r)   r)   r*   __post_init__   s"   z_DataClassMapping.__post_init__fieldr   r#   rY   c                 C  s   t  N)NotImplementedError)clsri   r)   r)   r*   r`      s   z _DataClassMapping._get_field_keyc                   s    fdd j  D S )Nc                 3  s(    | ]\}}t  |jd ur|V  qd S rj   )ra   rb   ).0krg   rL   r)   r*   	<genexpr>   s    z-_DataClassMapping.__iter__.<locals>.<genexpr>)r[   itemsro   r)   ro   r*   __iter__   s   
z_DataClassMapping.__iter__c                 C  s   t tt| S rj   )r7   listiterro   r)   r)   r*   __len__   s   z_DataClassMapping.__len__c                 C  s   | j | }t| |j}|d u rt||jd}|r||S t|tr-t|ts-t|S t|t	rBt
dd |D rBdd |D S |S )N	serializec                 s  s    | ]}t |tV  qd S rj   )r>   r   rm   vr)   r)   r*   rp      s    z0_DataClassMapping.__getitem__.<locals>.<genexpr>c                 S  s"   g | ]}t |tr|nt|qS r)   )r>   dictrw   r)   r)   r*   
<listcomp>   s   " z1_DataClassMapping.__getitem__.<locals>.<listcomp>)r[   ra   rb   re   metadatagetr>   r   ry   r   all)rL   r+   rg   r-   rv   r)   r)   r*   __getitem__   s   
z_DataClassMapping.__getitem__c                   s  d B krj d ztu st|r|W S W n	 ty"   Y nw ttdttr=tdd  fdd|D S ttdttr_t|tr_td\ fdd|	 D S tdd }|rk||S td	d }|rw||S t
d
t| d )Nr   
__origin____args__c                   s   g | ]}  |qS r)   rc   rw   )rl   tr)   r*   rz      s    z2_DataClassMapping._parse_value.<locals>.<listcomp>c                   s&   i | ]\}}  |  |qS r)   r   )rm   rn   rx   )rl   t_kt_vr)   r*   
<dictcomp>   s    z2_DataClassMapping._parse_value.<locals>.<dictcomp>	from_dict__call__zUnparseable value of type r\   )r   r
   r>   rd   
issubclassra   r^   r   r   rq   rP   r]   )rl   r   r-   r   wrapr)   )rl   r   r   r   r*   rc      s4   
z_DataClassMapping._parse_valuerl   
type[Self]r!   Nonec                 C     d S rj   r)   rl   r!   r)   r)   r*   r   
     z_DataClassMapping.from_dictr   c                 C  r   rj   r)   r   r)   r)   r*   r     r   Mapping[_T, Any]c                 C  r   rj   r)   r   r)   r)   r*   r     r   c                 C  sF   |d u rd S t || r|S t |tst| j dt| | |S )Nz/.from_dict called with non-Mapping data of type)r>   r   rd   rT   r]   _parse_from_dictr   r)   r)   r*   r     s   


c           	      C  s   i }t | }t| D ].}| |}||}|d u rq
|jd}|r(||}n||j }| ||}|||j< q
| di |S )Ndeserializer)   )r   r   r`   r|   r{   rb   rc   )	rl   r!   kwargsrf   rg   r+   r-   r   r   r)   r)   r*   r   #  s   



z"_DataClassMapping._parse_from_dictN)ri   r   r#   rY   )rl   r   r!   r   r#   r   )rl   r   r!   r   r#   r   )rl   r   r!   r   r#   r   )rT   rU   rV   rW   __annotations__rh   classmethodr   r`   rr   ru   r~   rc   r   r   r   r)   r)   r)   r*   r      s2   
 
&
c                      s>   e Zd ZdZedddZ fdd	Ze fd
dZ  ZS )_JsonDataObjectzIA data class with members also accessible as a JSON-serializable Mapping.ri   r   r#   r?   c                 C  sD   |j d}|r
|S |jd}|d ddd |dd  D  S )Nrb   _r    c                 s  s    | ]}|  V  qd S rj   )title)rm   pr)   r)   r*   rp   @  s    z1_JsonDataObject._get_field_key.<locals>.<genexpr>   )r{   r|   rb   splitjoin)rl   ri   rb   partsr)   r)   r*   r`   :  s
   $z_JsonDataObject._get_field_keyc                   s"   t  |}t|trt|S |S rj   )rO   r~   r>   r"   r   )rL   r+   r-   rQ   r)   r*   r~   B  s   
z_JsonDataObject.__getitem__c                   sP   |d B |kr|j d }n|}t|tr!t|tr!t|tr!t|S t ||S )Nr   )	r   r>   r]   r   r"   r?   r   rO   rc   )rl   r   r-   t2rQ   r)   r*   rc   H  s   z_JsonDataObject._parse_value)ri   r   r#   r?   )	rT   rU   rV   rW   r   r`   r~   rc   rX   r)   r)   rQ   r*   r   7  s    r   )r!   r"   r#   r"   )r+   r"   r!   r"   r#   r"   )r-   r"   r#   r.   rS   )r-   r.   r2   r.   r#   r"   )r!   r:   r#   r"   )r!   r"   r#   r?   )-rW   
__future__r   rG   abcr   base64r   r   dataclassesr   r   ior   typingr	   r
   r   r   r   r   r   r   r   sysversion_infor   cryptography.hazmat.backendsr   cryptography.hazmat.primitivesr   r   __all__LOG_LEVEL_TRAFFICr   r   r   r   r   r   rE   rY   r   r?   r   r)   r)   r)   r*   <module>   s8   ,




	

	 