o
    sh                     @  s   d dl mZ ddlm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 d d
lmZmZmZmZmZ d dlZd dlZd dlZdd Zdd Zdd Zdd Zdd ZG dd dZdS )    )annotations   )cbor)sha256   )Ctap2Info)PinProtocol_PinUv)AESGCM)
InvalidTag)OptionalAnySequenceMappingcastNc                 C  "   t jt j d}|| |  S N)wbits)zlibcompressobj	MAX_WBITScompressflushdatao r   K/var/www/html/env_mimamsha/lib/python3.10/site-packages/fido2/ctap2/blob.py	_compress,      r   c                 C  r   r   )r   decompressobjr   
decompressr   r   r   r   r   _decompress1   r    r#   c                 C  s   dt d|  S )Ns   blobz<Q)structpack)	orig_sizer   r   r   _lb_ad6   s   r'   c                 C  s<   t |}td}t| }||t|t|}|||dS )N   )r   r      )lenosurandomr   encryptr   r'   )keyr   r&   nonceaesgcm
ciphertextr   r   r   _lb_pack:   s   
r2   c              
   C  sn   z|d }|d }|d }t | }|||t|}||fW S  tttfy,   td ty6   tdw )Nr   r   r)   zInvalid entryz	Wrong key)r   decryptr'   	TypeError
IndexErrorKeyError
ValueErrorr   )r.   entryr1   r/   r&   r0   
compressedr   r   r   
_lb_unpackH   s   
r:   c                   @  s`   e Zd ZdZed!ddZ		d"d#ddZd$ddZd%ddZd&ddZ	d'ddZ
d(dd ZdS ))
LargeBlobsaJ  Implementation of the CTAP2.1 Large Blobs API.

    Getting a largeBlobKey for a credential is done via the LargeBlobKey extension.

    :param ctap: An instance of a CTAP2 object.
    :param pin_uv_protocol: An instance of a PinUvAuthProtocol.
    :param pin_uv_token: A valid PIN/UV Auth Token for the current CTAP session.
    infor   returnboolc                 C  s   | j ddu S )N
largeBlobsT)optionsget)r<   r   r   r   is_supported`   s   zLargeBlobs.is_supportedNctapr   pin_uv_protocolOptional[PinProtocol]pin_uv_tokenOptional[bytes]c                 C  sL   |  |js
td|| _| jjjd | _|r!|r!t||| _d S d | _d S )Nz)Authenticator does not support LargeBlobs@   )rB   r<   r7   rC   max_msg_sizemax_fragment_lengthr
   pin_uv)selfrC   rD   rF   r   r   r   __init__d   s   
zLargeBlobs.__init__Sequence[Mapping[int, Any]]c                 C  s   d}d}	 | j j|| jdd }||7 }t|| jk rn|| j7 }q|dd |dd }}|t|dd kr;g S ttttt	f  t
|S )zsGets the entire contents of the Large Blobs array.

        :return: The CBOR decoded list of Large Blobs.
        r       T)rA   r   Ni)rC   large_blobsrJ   r*   r   r   r   r   intr   r   decode)rL   offsetbuffragmentr   checkr   r   r   read_blob_arrayu   s   
zLargeBlobs.read_blob_array
blob_arrayNonec           
      C  s   t |ts	tdt|}|t|dd 7 }d}t|}||k rpt|| | j}||||  }| j	rQdt
d| t| }| j	jj}| j	j| j	j|}	nd}	d}| jj|||dkr`|nd||	d ||7 }||k s"dS dS )zoWrites the entire Large Blobs array.

        :param blob_array: A list to write to the Authenticator.
        zlarge-blob array must be a listN   r   s"    z<I)setlengthrD   pin_uv_param)
isinstancelistr4   r   encoder   r*   minrJ   rK   r$   r%   protocolVERSIONauthenticatetokenrC   rP   )
rL   rX   r   rS   sizeln_setmsgrD   r]   r   r   r   write_blob_array   s:   



zLargeBlobs.write_blob_arraylarge_blob_keybytesc              
   C  sZ   |   D ]&}zt||\}}t|}t||kr|W   S W q ttjfy*   Y qw dS )zGets the Large Blob stored for a single credential.

        :param large_blob_key: The largeBlobKey for the credential, or None.
        :returns: The decrypted and deflated value stored for the credential.
        N)rW   r:   r#   r*   r7   r   error)rL   rk   r8   r9   r&   decompressedr   r   r   get_blob   s   
zLargeBlobs.get_blobr   c              	   C  sv   |du}g }|   D ]}z	t|| d}W q
 ty#   || Y q
w |dur0|t|| |r9| | dS dS )a   Stores a Large Blob for a single credential.

        Any existing entries for the same credential will be replaced.

        :param large_blob_key: The largeBlobKey for the credential.
        :param data: The data to compress, encrypt and store.
        NT)rW   r:   r7   appendr2   rj   )rL   rk   r   modifiedentriesr8   r   r   r   put_blob   s   
zLargeBlobs.put_blobc                 C  s   |  |d dS )zDeletes any Large Blob(s) stored for a single credential.

        :param large_blob_key: The largeBlobKey for the credential.
        N)rs   )rL   rk   r   r   r   delete_blob   s   zLargeBlobs.delete_blob)r<   r   r=   r>   )NN)rC   r   rD   rE   rF   rG   )r=   rN   )rX   rN   r=   rY   )rk   rl   r=   rG   )rk   rl   r   rG   r=   rY   )rk   rl   r=   rY   )__name__
__module____qualname____doc__staticmethodrB   rM   rW   rj   ro   rs   rt   r   r   r   r   r;   V   s    	


(
r;   )
__future__r    r   utilsr   baser   r   pinr	   r
   +cryptography.hazmat.primitives.ciphers.aeadr   cryptography.exceptionsr   typingr   r   r   r   r   r$   r   r+   r   r#   r'   r2   r:   r;   r   r   r   r   <module>   s"   