o
    6hX                     @   s,  d dl Z d dlZd dlZd dlmZ d dlmZ ddlmZ ddl	m
Z
 ddlmZmZmZ ddlmZmZ dd	lmZmZmZ ejejdddfd
dZdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Z dd Z!dd Z"d d! Z#d"d# Z$d$d% Z%d&d' Z&d(d) Z'd*d+ Z(d,d- Z)d.d/ Z*dS )0    N)Mappingpack   )jwk)get_random_bytes)
ALGORITHMSJWE_SIZE_LIMITZIPS)JWEErrorJWEParseError)base64url_decodebase64url_encodeensure_binaryc                 C   s   t | } |tjvrtd| |tjvrtd| t||}t|||||}t|| } t||||| |\}}	}
}t	|||	|
|}|S )a  Encrypts plaintext and returns a JWE cmpact serialization string.

    Args:
        plaintext (bytes): A bytes object to encrypt
        key (str or dict): The key(s) to use for encrypting the content. Can be
            individual JWK or JWK set.
        encryption (str, optional): The content encryption algorithm used to
            perform authenticated encryption on the plaintext to produce the
            ciphertext and the Authentication Tag.  Defaults to A256GCM.
        algorithm (str, optional): The cryptographic algorithm used
            to encrypt or determine the value of the CEK.  Defaults to dir.
        zip (str, optional): The compression algorithm) applied to the
            plaintext before encryption. Defaults to None.
        cty (str, optional): The media type for the secured content.
            See http://www.iana.org/assignments/media-types/media-types.xhtml
        kid (str, optional): Key ID for the provided key

    Returns:
        bytes: The string representation of the header, encrypted key,
            initialization vector, ciphertext, and authentication tag.

    Raises:
        JWEError: If there is an error signing the token.

    Examples:
        >>> from jose import jwe
        >>> jwe.encrypt('Hello, World!', 'asecret128bitkey', algorithm='dir', encryption='A128GCM')
        'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4R0NNIn0..McILMB3dYsNJSuhcDzQshA.OfX9H_mcUpHDeRM4IA.CcnTWqaqxNsjT4eCaUABSg'

    Algorithm %s not supported.)
r   r   	SUPPORTEDr   r   	construct_encoded_header	_compress_encrypt_and_auth_jwe_compact_serialize)	plaintextkey
encryption	algorithmzipctykidencoded_headerenc_cekivcipher_textauth_tag
jwe_string r$   \/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/jose/jwe.pyencrypt   s   


r&   c              
   C   s  t | tkrtdt |  dt dt| \}}}}}}z |d }|d }	|tjvr1td| |	tjvr<td|	 W n tyH   tdw t	||}|tj
kr]|dk}
t|}n'z	||}d	}
W n tyu   td
| d ty   d}
t|	}Y nw |}|}zt||	||||}W n ty   td|	 d ty } zt|d}~ww |durt|d|}|
r|S dS )a  Decrypts a JWE compact serialized string and returns the plaintext.

    Args:
        jwe_str (str): A JWE to be decrypt.
        key (str or dict): A key to attempt to decrypt the payload with. Can be
            individual JWK or JWK set.

    Returns:
        bytes: The plaintext bytes, assuming the authentication tag is valid.

    Raises:
        JWEError: If there is an exception verifying the token.

    Examples:
        >>> from jose import jwe
        >>> jwe.decrypt(jwe_string, 'asecret128bitkey')
        'Hello, World!'
    zJWE string z bytes exceeds  bytesalgencr   z!alg and enc headers are required!    Talg  is not implementedFenc Nr   )lenr	   r   _jwe_compact_deserializer   r   KeyErrorr   r   r   DIR_get_key_bytes_from_key
unwrap_keyNotImplementedError	Exception_get_random_cek_bytes_for_enc_decrypt_and_auth_decompressget)jwe_strr   headerr   encrypted_keyr    r!   r"   r(   r)   	cek_valid	cek_bytesprotected_headeraad
plain_texter$   r$   r%   decrypt<   sP   





rC   c                 C   s   t | d }|S )a+  Returns the decoded headers without verification of any kind.

    Args:
        jwe_str (str): A compact serialized JWE to decode the headers from.

    Returns:
        dict: The dict representation of the JWE headers.

    Raises:
        JWEError: If there is an exception decoding the JWE.
    r   )r/   )r:   r;   r$   r$   r%   get_unverified_header   s   rD   c                 C   s|   |t jv rt| |\}}}t|||||}	n|t jv r$t| |}|}	ntd| d|||||}
||	kr<t	d|
S )a  
    Decrypt and verify the data

    Args:
        cek_bytes (bytes): cek to derive encryption and possible auth key to
            verify the auth tag
        cipher_text (bytes): Encrypted data
        iv (bytes): Initialization vector (iv) used to encrypt data
        aad (bytes): Additional Authenticated Data used to verify the data
        auth_tag (bytes): Authentication ntag to verify the data

    Returns:
        (bytes): Decrypted data
    r-    is not implemented!zInvalid JWE Auth Tag)
r   HMAC_AUTH_TAG3_get_encryption_key_mac_key_and_key_length_from_cek	_auth_tagGCMr   r   r4   rC   r   )r>   r)   r!   r    r@   r"   encryption_keymac_keykey_lenauth_tag_checkr   r$   r$   r%   r7      s   

r7   c           	      C   sT   t | d }| d| }t||}| | d  }|d\}}t||}|||fS )N   r   -)r.   _get_hmac_keysplitr   r   )	r>   r)   derived_key_lenmac_key_bytesrK   encryption_key_bytesencryption_alg_rJ   r$   r$   r%   rG      s   

rG   c              
   C   s\  t | } z| dd\}}}}}t|}W n ty    td ttjfy-   tdw zt	|}W n tyH } ztd| d}~ww t
|tsRtdzt|}	W n ttjfyf   tdw zt|}
W n ttjfy{   td	w zt|}W n ttjfy   td
w zt|}W n ttjfy   tdw |||	|
||fS )z
    Deserialize and verify the header and segments are appropriate.

    Args:
        jwe_bytes (bytes): The compact serialized JWE
    Returns:
        (dict, bytes, bytes, bytes, bytes, bytes)
       .   zNot enough segmentszInvalid headerzInvalid header string: Nz,Invalid header string: must be a json objectzInvalid encrypted keyz
Invalid IVzInvalid cyphertextzInvalid auth tag)r   rQ   r   
ValueErrorr   	TypeErrorbinasciiErrorjsonloads
isinstancer   )	jwe_bytesheader_segmentencrypted_key_segment
iv_segmentcipher_text_segmentauth_tag_segmentheader_datar;   rB   r<   r    
ciphertextr"   r$   r$   r%   r/     sP   
r/   c                 C   sL   | |d}|r||d< |r||d< |r||d< t j|dddd}t|S )	a  
    Generate an appropriate JOSE header based on the values provided
    Args:
        alg (str): Key wrap/negotiation algorithm
        enc (str): Encryption algorithm
        zip (str): Compression method
        cty (str): Content type of the encrypted data
        kid (str): ID for the key used for the operation

    Returns:
        bytes: JSON object of header based on input
    )r(   r)   r   r   r   ),:T)
separators	sort_keyszutf-8)r]   dumpsencoder   )r(   r)   r   r   r   r;   json_headerr$   r$   r%   r   Q  s   
r   c                 C   s
   t d| S )Nz!Qr   )int_valr$   r$   r%   _big_endianm  s   
rp   c                 C   s   z
t ||| \}}W n ty   td| dw |tjv r9t||\}}	}
|||\}}}t||||	|
}n|tjv rNt	
||}|||\}}}ntd| d||||fS )a/  
    Generate a content encryption key (cek) and initialization
    vector (iv) based on enc and alg, compress the plaintext based on zip,
    encrypt the compressed plaintext using the cek and iv based on enc

    Args:
        key (Key): The key provided for encryption
        alg (str): The algorithm use for key wrap/negotiation
        enc (str): The encryption algorithm with which to encrypt the plaintext
        zip (str): The compression algorithm with which to compress the plaintext
        plaintext (bytes): The data to encrypt
        aad (str): Additional authentication data utilized for generating an
                    auth tag

    Returns:
          (bytes, bytes, bytes, bytes): A tuple of the following data
                                 (key wrapped cek, iv, cipher text, auth tag)
    r+   r,   r-   rE   )_get_cekr4   r   r   rF   rG   r&   rH   rI   r   r   )r   r(   r)   r   r   r@   r>   kw_cekrJ   rK   rL   r    rg   tagr"   r$   r$   r%   r   q  s   

r   c                 C   s   |  d\}}t||}|S )z
    Get an HMACKey for the provided encryption algorithm and key bytes

    Args:
        enc (str): Encryption algorithm
        mac_key_bytes (bytes): vytes for the HMAC key

    Returns:
         (HMACKey): The key to perform HMAC actions
    rO   )rQ   r   r   )r)   rS   rV   hash_algrK   r$   r$   r%   rP     s   rP   c                 C   sR   | t jvrtd|  d| du r|}|S | t jkr!t|}|S td|  d)z
    Compress the plaintext based on the algorithm supplied

    Args:
        zip (str): Compression Algorithm
        plaintext (bytes): plaintext to compress

    Returns:
        (bytes): Compressed plaintext
    ZIP  is not supported!NrE   )r
   r   r4   DEFzlibcompress)r   r   
compressedr$   r$   r%   r     s   


r   c                 C   st   | t jvrtd|  d| du r|}|S | t jkr2t }|j|td}|jr0t	dt d|S td|  d)z
    Decompress the plaintext based on the algorithm supplied

    Args:
        zip (str): Compression Algorithm
        plaintext (bytes): plaintext to decompress

    Returns:
        (bytes): Compressed plaintext
    ru   rv   N)
max_lengthz Decompressed JWE string exceeds r'   rE   )
r
   r   r4   rw   rx   decompressobj
decompressr	   unconsumed_tailr   )r   rz   decompresseddecompressorr$   r$   r%   r8     s   


r8   c                 C   s4   |t jkrt|\}}||fS t| |\}}||fS )a  
    Get the content encryption key

    Args:
        enc (str): Encryption algorithm
        alg (str): kwy wrap/negotiation algorithm
        key (Key): Key provided to encryption method

    Return:
        (bytes, bytes): Tuple of (cek bytes and wrapped cek)
    )r   r1   _get_direct_key_wrap_cek_get_key_wrap_cek)r)   r(   r   cekwrapped_cekr$   r$   r%   rq     s
   
rq   c                 C   s:   |   }|d dkrt| }d}||fS td|d )z
    Get the cek and wrapped cek from the encryption key direct

    Args:
        key (Key): Key provided to encryption method

    Return:
        (Key, bytes): Tuple of (cek Key object and wrapped cek)
    ktyoctr*   zJWK type {} not supported!)to_dictr2   r4   format)r   jwk_datar>   r   r$   r$   r%   r     s   r   c                 C   s   |   }|d }t|}|S )z
    Get the raw key bytes from a Key object

    Args:
        key (Key): Key from which to extract the raw key bytes
    Returns:
        (bytes) key data
    k)r   r   )r   r   encoded_keyr>   r$   r$   r%   r2      s   	r2   c                 C   s   t | }||}||fS )a  _get_rsa_key_wrap_cek
    Get the content encryption key for RSA key wrap

    Args:
        enc (str): Encryption algorithm
        key (Key): Key provided to encryption method

    Returns:
        (Key, bytes): Tuple of (cek Key object and wrapped cek)
    )r6   wrap_key)r)   r   r>   r   r$   r$   r%   r     s   
r   c                 C   st   | t jkrd}n*| t jkrd}n"| t jt jfv rd}n| t jkr#d}n| t jkr+d}nt|  dt|d }|S )z
    Get the random cek bytes based on the encryptionn algorithm

    Args:
        enc (str): Encryption algorithm

    Returns:
        (bytes) random bytes for cek key
             i  i   z not supported   )	r   A128GCMA192GCMA128CBC_HS256A256GCMA192CBC_HS384A256CBC_HS512r4   r   )r)   num_bitsr>   r$   r$   r%   r6     s   




r6   c           	      C   s:   t t|d }|| |  | }||}|d| }|S )aZ  
    Get ann auth tag from the provided data

    Args:
        ciphertext (bytes): Encrypted value
        iv (bytes): Initialization vector
        aad (bytes): Additional Authenticated Data
        mac_key (bytes): Key to use in generating the MAC
        tag_length (int): How log the tag should be

    Returns:
        (bytes) Auth tag
    r   r   )rp   r.   sign)	rg   r    r@   rK   
tag_lengthalauth_tag_input	signaturer"   r$   r$   r%   rH   9  s
   
rH   c           	      C   sL   t |}t|}t|}t|}t|}| d | d | d | d | S )ay  
    Generate a compact serialized JWE

    Args:
        encoded_header (bytes): Base64 URL Encoded JWE header JSON
        encrypted_cek (bytes): Encrypted content encryption key (cek)
        iv (bytes): Initialization vector (IV)
        cipher_text (bytes): Cipher text
        auth_tag (bytes): JWE Auth Tag

    Returns:
        (str): JWE compact serialized string
    rW   )r   r   )	r   encrypted_cekr    r!   r"   encoded_encrypted_cek
encoded_ivencoded_cipher_textencoded_auth_tagr$   r$   r%   r   N  s.   r   )+r[   r]   rx   collections.abcr   structr    r   backendsr   	constantsr   r	   r
   
exceptionsr   r   utilsr   r   r   r   r1   r&   rC   rD   r7   rG   r/   r   rp   r   rP   r   r8   rq   r   r2   r   r6   rH   r   r$   r$   r$   r%   <module>   s<    . &
J%