a
    |fM                     @   s  d dl Z d dlmZm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 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 d dlmZmZ G dd dZg Zzd dlmZmZ ed W n ey   eZeZY n0 zd dl m!Z!m"Z" ed W n ey.   eZ!eZ"Y n0 z8d dl#m$Z$m%Z% e&e%ddZ'e'du r\eed W n ey   eZ$eZ%Y n0 zd dl(m)Z)m*Z* ed W n ey   eZ)eZ*Y n0 eddZ+eddZ,eddZ-eddZ.e+eee,e!e"e-e$e%e.e)e*dZ/dddddZ0G d d! d!eZ1ed"d#Z2e2d$d%d%e1j3e2d&d%d%e1j4e2d'd%d%e1j4e2d(d)d)e1j4d*e2d+d%d%e1j4e2d,d%d%e1j5e2d-d)d)e1j5e2d.d)d)e1j5e2d/d)d)e1j5e2d0d)d)e1j5e2d1d)d)e1j5e2d2d)d)e1j5e2d3d)d)e1j6d4	d5e2d6d)d%e1j4ie2d$d%d%e1j3e2d7d%d%e1j4e2d8d)d)e1j4d9dZ7e2d:d%dde2d;d%dde2d<d%dde2d=d%dde2d>d%dde2d?d%dde2d@d%dde2dAd%dde2dBd%dddC	Z8dDdEdFdGdHdIdJdKdLdMdNdOZ9dPdQdRZ:dSdTdUdVdWdXdYdZd[Z;d\d]d^d_d`dadbdcZ<e= ddddde> e? e@ eA eB eC eDdddeEdedfZFG dgdh dheZGG didj djeZHG dkdl dleZIG dmdn dneZJG dodp dpeKZLG dqdr dreMZNG dsdt dteKZOdS )u    N)hexlify	unhexlify)
namedtuple)Enum)x509)default_backend)hashesserialization)ec)rsa)
deprecated)JWException)base64url_decodebase64url_encode)json_decodejson_encodec                   @   s0   e Zd Zedd Zedd Zedd ZdS )UnimplementedOKPCurveKeyc                 C   s   t d S NNotImplementedError)cls r   FD:\Projects\storyit_web\backend\venv\Lib\site-packages\jwcrypto/jwk.pygenerate   s    z!UnimplementedOKPCurveKey.generatec                 G   s   t d S r   r   r   argsr   r   r   from_public_bytes   s    z*UnimplementedOKPCurveKey.from_public_bytesc                 G   s   t d S r   r   r   r   r   r   from_private_bytes   s    z+UnimplementedOKPCurveKey.from_private_bytesN)__name__
__module____qualname__classmethodr   r   r   r   r   r   r   r      s   

r   )Ed25519PublicKeyEd25519PrivateKeyEd25519)Ed448PublicKeyEd448PrivateKeyEd448)X25519PublicKeyX25519PrivateKeyr   X25519)X448PublicKeyX448PrivateKeyX448zpubkey privkey)r$   r'   r*   r-   zElliptic CurveRSAzOctet sequencezOctet Key Pair)ECr.   octOKPc                   @   s   e Zd ZdZdZdZdZdS )ParmTypezA string with a namezBase64url EncodedzBase64urlUint EncodedzUnsupported ParameterN)r   r   r    nameb64b64uunsupportedr   r   r   r   r2   d   s   r2   	Parameterz description public required typeZCurveTzX CoordinatezY CoordinatezECC Private KeyF)crvxydZModulusExponentzPrivate ExponentzFirst Prime FactorzSecond Prime FactorzFirst Factor CRT ExponentzSecond Factor CRT ExponentzFirst CRT CoefficientzOther Primes Info)	ner;   pqdpdqqiZothkz	Key Valuez
Public KeyzPrivate Key)r8   r9   r;   zKey TypezPublic Key UsezKey OperationsZ	AlgorithmzKey IDz	X.509 URLzX.509 Certificate Chainz"X.509 Certificate SHA-1 Thumbprintz$X.509 Certificate SHA-256 Thumbprint)	ktyusekey_opsalgkidZx5uZx5cZx5tzx5t#S256zP-256 curvezP-384 curvezP-521 curvezSECG secp256k1 curvez%Ed25519 signature algorithm key pairsz#Ed448 signature algorithm key pairszX25519 function key pairszX448 function key pairsz\BrainpoolP256R1 curve (unregistered, custom-defined in breach of IETF rules by gematik GmbH)z\BrainpoolP384R1 curve (unregistered, custom-defined in breach of IETF rules by gematik GmbH)z\BrainpoolP512R1 curve (unregistered, custom-defined in breach of IETF rules by gematik GmbH))P-256P-384P-521	secp256k1r$   r'   r*   r-   BP-256BP-384BP-512zDigital Signature or MACZ
Encryption)sigencz Compute digital Signature or MACzVerify digital signature or MACzEncrypt contentz6Decrypt content and validate decryption, if applicablezEncrypt keyz2Decrypt key and validate decryption, if applicablez
Derive keyz#Derive bits not to be used as a key)signverifyencryptdecryptwrapKey	unwrapKey	deriveKey
deriveBitsrJ   rK   rL   rM   rN   rO   rP   )Z	secp256r1Z	secp384r1Z	secp521r1rM   ZbrainpoolP256r1ZbrainpoolP384r1ZbrainpoolP512r1    @   )sha-256zsha-256-128zsha-256-120z
sha-256-96z
sha-256-64z
sha-256-32zsha-384zsha-512zsha3-224zsha3-256zsha3-384zsha3-512zblake2s-256zblake2b-256zblake2b-512c                       s*   e Zd ZdZd fdd	Zdd Z  ZS )InvalidJWKTypezfInvalid JWK Type Exception.

    This exception is raised when an invalid parameter type is used.
    Nc                    s   t t|   || _d S r   )superr^   __init__value)selfra   	__class__r   r   r`      s    zInvalidJWKType.__init__c                 C   s   d| j tt f S )Nz&Unknown type "%s", valid types are: %s)ra   listJWKTypesRegistrykeysrb   r   r   r   __str__   s    zInvalidJWKType.__str__)Nr   r   r    __doc__r`   ri   __classcell__r   r   rc   r   r^      s   r^   c                       s(   e Zd ZdZ fddZdd Z  ZS )InvalidJWKUsagezInvalid JWK usage Exception.

    This exception is raised when an invalid key usage is requested,
    based on the key type and declared usage constraints.
    c                    s   t t|   || _|| _d S r   )r_   rm   r`   ra   rF   )rb   rF   ra   rc   r   r   r`      s    zInvalidJWKUsage.__init__c                 C   s\   | j tt v rt| j  }n
d| j  }| jtt v rFt| j }n
d| j }d||f S )NUnknown(%s)z.Invalid usage requested: "%s". Valid for: "%s")rF   re   JWKUseRegistryrg   ra   )rb   usagevalidr   r   r   ri      s    

zInvalidJWKUsage.__str__rj   r   r   rc   r   rm      s   rm   c                       s(   e Zd ZdZ fddZdd Z  ZS )InvalidJWKOperationzInvalid JWK Operation Exception.

    This exception is raised when an invalid key operation is requested,
    based on the key type and declared usage constraints.
    c                    s   t t|   || _|| _d S r   )r_   rr   r`   opvalues)rb   	operationrt   rc   r   r   r`     s    zInvalidJWKOperation.__init__c                 C   sr   | j tt v rt| j  }n
d| j  }g }| jD ]2}|tt v rV|t|  q2|d|  q2d||f S )Nrn   z2Invalid operation requested: "%s". Valid for: "%s")rs   re   JWKOperationsRegistryrg   rt   append)rb   rs   rq   vr   r   r   ri     s    

zInvalidJWKOperation.__str__rj   r   r   rc   r   rr     s   rr   c                   @   s   e Zd ZdZdS )InvalidJWKValuezInvalid JWK Value Exception.

    This exception is raised when an invalid/unknown value is used in the
    context of an operation that requires specific values to be used based
    on the key type or other constraints.
    N)r   r   r    rk   r   r   r   r   ry   "  s   ry   c                       s  e Zd ZdZ fddZedd Zdd Zdd	d
Zdd Z	dddZ
dd Zdd Zdd Zdd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ed'd( Zdd+d,Zdd-d.Zd/d0 Zdd1d2Zdd3d4Zdd5d6Zd7d8 Zed9d: Z ed;d< Z!ed=d> Z"ee#d?d@ Z$ee#dAdB Z%ee#dCdD Z&e#dEdF Z'dGdH Z(dIdJ Z)dKdL Z*dMdN Z+dOdP Z,dQdR Z-dSdT Z.dUdV Z/dWdX Z0dYdZ Z1d[d\ Z2d]d^ Z3dd_d`Z4ddadbZ5ddcddZ6dedf Z7ddgdhZ8ddidjZ9edkdl Z:eddmdnZ;e<= fdodpZ>ddrdsZ? fdtduZ@dvdw ZAddxdyZB fdzd{ZCd|d} ZDd~d ZEdd ZF fddZGedd ZHdd ZI  ZJS )JWKzJSON Web Key object

    This object represents a Key.
    It must be instantiated by using the standard defined key/value pairs
    as arguments of the initialization function.
    c                    sL   t t|   d| _d| _d|v r4| jf i | n|rH| jf i | dS )a  Creates a new JWK object.

        The function arguments must be valid parameters as defined in the
        'IANA JSON Web Key Set Parameters registry' and specified in
        the :data:`JWKParamsRegistry` variable. The 'kty' parameter must
        always be provided and its value must be a valid one as defined
        by the 'IANA JSON Web Key Types registry' and specified in the
        :data:`JWKTypesRegistry` variable. The valid key parameters per
        key type are defined in the :data:`JWKValuesRegistry` variable.

        To generate a new random key call the class method generate() with
        the appropriate 'kty' parameter, and other parameters as needed (key
        size, public exponents, curve types, etc..)

        Valid options per type, when generating new keys:
         * oct: size(int)
         * RSA: public_exponent(int), size(int)
         * EC: crv(str) (one of P-256, P-384, P-521, secp256k1)
         * OKP: crv(str) (one of Ed25519, Ed448, X25519, X448)

        Deprecated:
        Alternatively if the 'generate' parameter is provided with a
        valid key type as value then a new key will be generated according
        to the defaults or provided key strength options (type specific).

        :param \**kwargs: parameters (optional).

        :raises InvalidJWKType: if the key type is invalid
        :raises InvalidJWKValue: if incorrect or inconsistent parameters
            are provided.
        Nr   )r_   rz   r`   _cache_pub_k_cache_pri_kgenerate_key
import_key)rb   kwargsrc   r   r   r`   3  s     zJWK.__init__c              
   K   sd   |  }d }z|d }t |d| }W n2 ttfyV } zt||W Y d }~n
d }~0 0 || |S )NrE   _generate_%s)getattrKeyErrorAttributeErrorr^   )r   r   objrE   genr>   r   r   r   r   \  s     zJWK.generatec              
   K   s`   d }z| d}t| d| }W n2 ttfyR } zt||W Y d }~n
d }~0 0 || d S )Nr   r   )popr   r   r   r^   )rb   paramsrE   r   r>   r   r   r   r}   h  s    
 zJWK.generate_keyNc              
   C   sx   |}d|v r| d}n\d|v rtzddlm} ||d }W n. tyl } ztd|W Y d }~n
d }~0 0 |j}|S )NsizerH   r   )JWAzInvalid 'alg' parameter)r   Zjwcrypto.jwar   Zinstantiate_algr   
ValueErrorZinput_keysize)rb   r   Zdefault_sizer   r   rH   r>   r   r   r   _get_gen_sizer  s     zJWK._get_gen_sizec                 C   sB   |  |d}t|d }d|d< t||d< | jf i | d S )N      r0   rE   rD   )r   osurandomr   r~   )rb   r   r   keyr   r   r   _generate_oct  s
    zJWK._generate_octc                 C   sf   d}|d ur|d d d }t |dd}t|}||krJ||8 }n|d }tt|d | S )Nr      r      L0x0)hexrstriplstriplenr   r   )rb   iZbit_sizeextendZhexiZhexlr   r   r   _encode_int  s    
zJWK._encode_intc                 C   sH   d}|  |d}d|v r"|d}t||t }| j|fi | d S )Ni  i   Zpublic_exponent)r   r   r   generate_private_keyr   _import_pyca_pri_rsa)rb   r   Zpubexpr   r   r   r   r   _generate_RSA  s    
zJWK._generate_RSAc                 K   s|   |  }|jd| |jj| |jj| |j| |j| |j| |j	| |j
| |jd	 | jf i | d S )Nr.   )	rE   r=   r>   r;   r?   r@   rA   rB   rC   )private_numbersupdater   public_numbersr=   r>   r;   r?   r@   Zdmp1Zdmq1Ziqmpr~   rb   r   r   pnr   r   r   r     s    





zJWK._import_pyca_pri_rsac                 K   s<   |  }|jd| |j| |jd | jf i | d S )Nr.   )rE   r=   r>   )r   r   r   r=   r>   r~   r   r   r   r   _import_pyca_pub_rsa  s    

zJWK._import_pyca_pub_rsac                 C   s  |  d}|d u r|}n|dkr&d}n|}|rV|}|dkr>d}||krVtd||f |  d}|d ur|d ur||krtd||f |dkrt S |dkrt S |d	krt S |dkrt S |d
krt S |dkrt	 S |dk rt
 S |tv rt| S td| d S )Nr8   zP-256KrM   z.Curve requested is "%s", but key curve is "%s"rE   z>Curve Requested is of type "%s", but key curve is of type "%s"rJ   rK   rL   rN   rO   rP   zUnknown Curve Name [%s])getry   r^   r
   Z	SECP256R1Z	SECP384R1Z	SECP521R1Z	SECP256K1ZBrainpoolP256R1ZBrainpoolP384R1ZBrainpoolP512R1_OKP_CURVES_TABLE)rb   r3   ctyper8   cnameZccrvrE   r   r   r   _get_curve_by_name  sH    



zJWK._get_curve_by_namec                 C   sX   d}d|v r| d}d|v r(| d}| |d}t|t }| j|fi | d S )NrJ   curver8   r/   )r   r   r
   r   r   _import_pyca_pri_ec)rb   r   r   curve_fnr   r   r   r   _generate_EC  s    

zJWK._generate_ECc              	   K   sd   |  }|jjj}|jdt|jj | |jj|| |jj	|| |j
|d | jf i | d S )Nr/   )rE   r8   r9   r:   r;   )r   r   r   key_sizer   JWKpycaCurveMapr3   r   r9   r:   Zprivate_valuer~   rb   r   r   r   r   r   r   r   r     s    

zJWK._import_pyca_pri_ecc                 K   sR   |  }|jj}|jdt|jj | |j|| |j|d | j	f i | d S )Nr/   )rE   r8   r9   r:   )
r   r   r   r   r   r3   r   r9   r:   r~   r   r   r   r   _import_pyca_pub_ec  s    
zJWK._import_pyca_pub_ecc                 C   s@   d|vrt d| |d d}|j }| j|fi | d S )Nr8   z)Must specify "crv" for OKP key generationr1   )ry   r   privkeyr   _import_pyca_pri_okp)rb   r   r   r   r   r   r   _generate_OKP  s
    
zJWK._generate_OKPc                 C   s<   t  D ]"\}}t||j|jfr|  S qtd| d S )NzInvalid OKP Key object %r)r   items
isinstancepubkeyr   ry   )rb   r   r3   valr   r   r   _okp_curve_from_pyca_key
  s    
zJWK._okp_curve_from_pyca_keyc              
   K   s^   |j d| |t|tjjtjjt t|	 
tjjtjjd | jf i | d S )Nr1   )rE   r8   r;   r9   )r   r   r   private_bytesr	   EncodingRawPrivateFormatNoEncryption
public_keypublic_bytesPublicFormatr~   rb   r   r   r   r   r   r     s    
zJWK._import_pyca_pri_okpc                 K   s>   |j d| |t|tjjtjjd | jf i | d S )Nr1   )rE   r8   r9   )	r   r   r   r   r	   r   r   r   r~   r   r   r   r   _import_pyca_pub_okp  s    zJWK._import_pyca_pub_okpc                 K   s  i }d}d | _ d | _t| }tt D ],}||v r,|| ||< ||v r,|| qDq,|d}|tvrtt|tt	|  D ]4}||v r|| ||< |d7 }||v r|| qqt	| 
 D ] \}}|jr||vrtd| |jtjkr||v rtd| |jtjkrl||v rlzt||  W n4 tyj } ztd| |W Y d }~n
d }~0 0 |jtjkr||v rz| ||  W q ty } ztd| |W Y d }~qd }~0 0 q|D ]}|| ||< q|dkrtdd	|v rF|d	 D ]>}	d}
|d	 D ]}|	|kr|
d7 }
q|
dkrtd
qd|v rd	|v rddg}g d}|d dkr|D ]}||d	 v r|tdq|n0|d dkr|D ]}||d	 v rtdq|   | d|d  | | d S )Nr   rE      zMissing required value %szUnsupported parameter %s"%s" is not base64url encoded!"%s" is not Base64urlUInt encodedzNo Key Values foundrG   zDuplicate values in "key_ops"rF   rS   rT   )rU   rV   rW   rX   rY   rZ   rQ   zBIncompatible "use" and "key_ops" values specified at the same timerR   )r{   r|   re   rg   JWKParamsRegistryremover   rf   r^   JWKValuesRegistryr   requiredry   typer2   r6   r4   r   	Exceptionr5   _decode_intclear__setitem__r   )rb   r   ZnewkeyZkey_valsnamesr3   rE   r   r>   koZcntZckoZsiglZenclrs   r   r   r   r~   (  s    




zJWK.import_keyc              
   C   sR   |  }zt |}W n* ty< } zt|W Y d}~n
d}~0 0 |jf i | |S )zCreates a RFC 7517 JWK from the standard JSON format.

        :param key: The RFC 7517 representation of a JWK.

        :return: A JWK object that holds the json key.
        :rtype: JWK
        N)r   r   ry   r~   )r   r   r   Zjkeyr>   r   r   r   	from_json  s    	zJWK.from_jsonTFc                 C   s   |du r|  |S | |S )a  Exports the key in the standard JSON format.
        Exports the key regardless of type, if private_key is False
        and the key is_symmetric an exception is raised.

        :param private_key(bool): Whether to export the private key.
                                  Defaults to True.

        :return: A portable representation of the key.
            If as_dict is True then a dictionary is returned.
            By default a json string
        :rtype: `str` or `dict`
        T)_export_allexport_public)rb   private_keyas_dictr   r   r   export  s    
z
JWK.exportc                 C   s   |   }|du r|S t|S )a  Exports the public key in the standard JSON format.
        It fails if one is not available like when this function
        is called on a symmetric key.

        :param as_dict(bool): If set to True export as python dict not JSON

        :return: A portable representation of the public key only.
            If as_dict is True then a dictionary is returned.
            By default a json string
        :rtype: `str` or `dict`
        T)_public_paramsr   )rb   r   pubr   r   r   r     s    zJWK.export_publicc                 C   sx   | j stdi }t}|D ](}|| jr||  v r| |||< qt| d }|D ]}|| jrV| |||< qV|S )NNo public key availablerE   )
has_publicr^   r   publicrg   r   r   )rb   r   regr3   r   r   r   r     s    

zJWK._public_paramsc                 C   s"   i }| |  |du r|S t|S )NT)r   r   )rb   r   r;   r   r   r   r     s
    
zJWK._export_allc                 C   s   | j r| |S tddS )a  Export the private key in the standard JSON format.
        It fails for a JWK that has only a public key or is symmetric.

        :param as_dict(bool): If set to True export as python dict not JSON

        :return: A portable representation of a private key.
            If as_dict is True then a dictionary is returned.
            By default a json string
        :rtype: `str` or `dict`
        No private key availableN)has_privater   r^   rb   r   r   r   r   export_private  s    
zJWK.export_privatec                 C   s   | j r| |S tdd S )NzNot a symmetric key)is_symmetricr   r^   r   r   r   r   export_symmetric  s    
zJWK.export_symmetricc                 C   s   |   }tf i |S r   )r   rz   )rb   r   r   r   r   r     s    z
JWK.publicc                 C   sB   | j r
dS t| d }|D ] }|| jr||  v r dS qdS )z4Whether this JWK has an asymmetric Public key value.FrE   Tr   r   r   r   rg   rb   r   r3   r   r   r   r     s    zJWK.has_publicc                 C   sB   | j r
dS t| d }|D ] }|| js||  v r dS qdS )z5Whether this JWK has an asymmetric Private key value.FrE   Tr   r   r   r   r   r     s    zJWK.has_privatec                 C   s   |  ddkS )z$Whether this JWK is a symmetric key.rE   r0   r   rh   r   r   r   r     s    zJWK.is_symmetricc                 C   s
   |  dS )zThe Key typerE   r   rh   r   r   r   key_type  s    zJWK.key_typec                 C   s
   |  dS )z^The Key ID.
        Provided by the kid parameter if present, otherwise returns None.
        rI   r   rh   r   r   r   key_id  s    z
JWK.key_idc                 C   s    |  ddvrtd|  dS )zThe Curve Name.rE   )r/   r1   zNot an EC or OKP keyr8   )r   r^   rh   r   r   r   	key_curve  s    zJWK.key_curvec                 C   s
   |  |S )a0  Gets the Elliptic Curve associated with the key.

        :param arg: an optional curve name

        :raises InvalidJWKType: the key is not an EC or OKP key.
        :raises InvalidJWKValue: if the curve name is invalid.

        :return: An EllipticCurve object
        :rtype: `EllipticCurve`
        )r   )rb   argr   r   r   	get_curve  s    zJWK.get_curvec                 C   sT   |  d}|r ||kr t|||  d}|rPt|ts>|g}||vrPt||d S )NrF   rG   )r   rm   r   re   rr   )rb   rp   ru   rF   opsr   r   r   _check_constraints"  s    



zJWK._check_constraintsc                 C   s   t tt|dS )N   )intr   r   )rb   r=   r   r   r   r   .  s    zJWK._decode_intc                 C   s,   |  | d}|  | d}t||S )Nr>   r=   )r   r   r   ZRSAPublicNumbers)rb   r>   r=   r   r   r   
_rsa_pub_n1  s    zJWK._rsa_pub_nc              
   C   sz   |  | d}|  | d}|  | d}|  | d}|  | d}|  | d}t|||||||  S )Nr?   r@   r;   rA   rB   rC   )r   r   r   ZRSAPrivateNumbersr   )rb   r?   r@   r;   rA   rB   rC   r   r   r   
_rsa_pri_n6  s    zJWK._rsa_pri_nc                 C   s(   | j }|d u r$|  t }|| _ |S r   )r{   r   r   r   rb   rD   r   r   r   _rsa_pub?  s
    zJWK._rsa_pubc                 C   s(   | j }|d u r$|  t }|| _ |S r   )r|   r   r   r   r   r   r   r   _rsa_priF  s
    zJWK._rsa_pric                 C   s<   |  | d}|  | d}| j|dd}t|||S )Nr9   r:   r/   )r   )r   r   r   r
   ZEllipticCurvePublicNumbers)rb   r   r9   r:   r   r   r   r   	_ec_pub_nM  s    zJWK._ec_pub_nc                 C   s"   |  | d}t|| |S )Nr;   )r   r   r
   ZEllipticCurvePrivateNumbersr   )rb   r   r;   r   r   r   	_ec_pri_nS  s    zJWK._ec_pri_nc                 C   s*   | j }|d u r&| |t }|| _ |S r   )r{   r   r   r   rb   r   rD   r   r   r   _ec_pubW  s
    zJWK._ec_pubc                 C   s*   | j }|d u r&| |t }|| _ |S r   )r|   r   r   r   r   r   r   r   _ec_pri^  s
    zJWK._ec_pric              
   C   s|   | j }|d u rx| d}zt| j}W n2 tyX } ztd| |W Y d }~n
d }~0 0 t| d}||}|| _ |S )Nr8   Unknown curve "%s"r9   )r{   r   r   r   r   ry   r   r   )rb   rD   r8   r   r>   r9   r   r   r   _okp_pube  s    
$
zJWK._okp_pubc              
   C   s|   | j }|d u rx| d}zt| j}W n2 tyX } ztd| |W Y d }~n
d }~0 0 t| d}||}|| _ |S )Nr8   r   r;   )r|   r   r   r   r   ry   r   r   )rb   rD   r8   r   r>   r;   r   r   r   _okp_pris  s    
$
zJWK._okp_pric                 C   sV   |  d}|dkr|  dS |dkr,|  S |dkr>| |S |dkrN|  S td S NrE   r0   rD   r.   r/   r1   )r   r   r   r   r   rb   r   Zktyper   r   r   _get_public_key  s    


zJWK._get_public_keyc                 C   sV   |  d}|dkr|  dS |dkr,|  S |dkr>| |S |dkrN|  S td S r   )r   r   r   r   r   r   r   r   r   _get_private_key  s    


zJWK._get_private_keyc                 C   s   |  dtt }|tur"|g}|du rN|  ddkrB|  dS t||n|dkrl| d| | |S |dkr| d| | |S |d	ks|d
kr| d| | |S |dks|dkr| d| | |S tdS )a  Get the key object associated to the requested operation.
        For example the public RSA key for the 'verify' operation or
        the private EC key for the 'decrypt' operation.

        :param operation: The requested operation.
         The valid set of operations is available in the
         :data:`JWKOperationsRegistry` registry.
        :param arg: An optional, context specific, argument.
         For example a curve name.

        :raises InvalidJWKOperation: if the operation is unknown or
         not permitted with this key.
        :raises InvalidJWKUsage: if the use constraints do not permit
         the operation.

        :return: A Python Cryptography key object for asymmetric keys
            or a baseurl64_encoded octet string for symmetric keys
        rG   NrE   r0   rD   rS   rQ   rT   rU   rW   rR   rV   rX   )	r   re   rv   rg   rr   r   r  r  r   )rb   ru   r   Zvalidopsr   r   r   
get_op_key  s,    





zJWK.get_op_keyc                 C   s   t |tjr| | nt |tjr0| | ntt |tjrH| | n\t |tj	r`| 
| nDt |tttfr|| | n(t |tttfr| | ntd| d S )NzUnknown key object %r)r   r   ZRSAPrivateKeyr   ZRSAPublicKeyr   r
   ZEllipticCurvePrivateKeyr   ZEllipticCurvePublicKeyr   r#   r&   r)   r   r"   r%   r(   r   ry   rb   r   r   r   r   import_from_pyca  s&    zJWK.import_from_pycac                 C   s   zt j||t d}W n ty } zt|dur2|zt j|t d}W nF ty   ztj|t d}| }W n ty   |Y n0 Y n0 W Y d}~n
d}~0 0 | | |du r| 	 }| 
d| dS )at  Imports a key from data loaded from a PEM file.
        The key may be encrypted with a password.
        Private keys (PKCS#8 format), public keys, and X509 certificate's
        public keys can be imported with this interface.

        :param data(bytes): The data contained in a PEM file.
        :param password(bytes): An optional password to unwrap the key.
        )passwordbackendNr  rI   )r	   Zload_pem_private_keyr   r   Zload_pem_public_keyr   Zload_pem_x509_certificater   r  
thumbprintr   )rb   datar  rI   r   r>   certr   r   r   import_from_pem  s.    


&
zJWK.import_from_pemc                 C   s   t jj}|rx| jstdt jj}|du r4t  }n0t|t	rJt 
|}n|du r\tdntd|  j|||dS | jstdt jj}|  j||dS dS )	aq  Exports keys to a data buffer suitable to be stored as a PEM file.
        Either the public or the private key can be exported to a PEM file.
        For private keys the PKCS#8 format is used. If a password is provided
        the best encryption method available as determined by the cryptography
        module is used to wrap the key.

        :param private_key: Whether the private key should be exported.
         Defaults to `False` which means the public key is exported by default.
        :param password(bytes): A password for wrapping the private key.
         Defaults to False which will cause the operation to fail. To avoid
         encryption the user must explicitly pass None, otherwise the user
         needs to provide a password in a bytes buffer.

        :return: A serialized bytes buffer containing a PEM formatted key.
        :rtype: `bytes`
        r   NFz+The password must be None or a bytes stringz!The password string must be bytes)encodingformatZencryption_algorithmr   )r  r  )r	   r   ZPEMr   r^   r   ZPKCS8r   r   bytesZBestAvailableEncryptionr   	TypeErrorr  r   r   r   ZSubjectPublicKeyInfor  r   )rb   r   r  rR   fZenc_algr   r   r   export_to_pem  s&    


zJWK.export_to_pemc                 C   s   |  }| | |S r   )r  )r   r   r   r   r   r   	from_pyca   s    
zJWK.from_pycac                 C   s   |  }| || |S )a?  Creates a key from PKCS#8 formatted data loaded from a PEM file.
           See the function `import_from_pem` for details.

        :param data(bytes): The data contained in a PEM file.
        :param password(bytes): An optional password to unwrap the key.

        :return: A JWK object.
        :rtype: JWK
        )r  )r   r
  r  r   r   r   r   from_pem&  s    zJWK.from_pemc                 C   sp   d|  di}t|d   D ]\}}|jr|  |||< qtj|t d}|tt	|
d t| S )zReturns the key thumbprint as specified by RFC 7638.

        :param hashalg: A hash function (defaults to SHA256)

        :return: A base64url encoded digest of the key
        :rtype: `str`
        rE   r  utf8)r   r   r   r   r   ZHashr   r   r  r   encoder   finalize)rb   Zhashalgtr3   r   digestr   r   r   r	  5  s    	zJWK.thumbprintr]   c              
   C   sn   zt | }W n4 ty@ } ztd||W Y d}~n
d}~0 0 |du rXtd|| |}d||S )ad  Returns the key thumbprint URI as specified by RFC 9278.

        :param hname: A hash function name as specified in IANA's
         Named Information registry:
         https://www.iana.org/assignments/named-information/
         Values from `IANANamedInformationHashAlgorithmRegistry`

        :return: A JWK Thumbprint URI
        :rtype: `str`
        zUnknown hash "{}"NzUnsupported hash "{}"z*urn:ietf:params:oauth:jwk-thumbprint:{}:{}))IANANamedInformationHashAlgorithmRegistryr   ry   r  r	  )rb   hnamehr>   r  r   r   r   thumbprint_uriF  s    &
zJWK.thumbprint_uric              
      s  |  d}|dkrP|d u r@|tvr*t|tt| || d S ||krPtd|tt| 	 v rTd | _
d | _t| | jtjkrz(t|}|dkr|dkr|dkrtW n2 ty } ztd| |W Y d }~n
d }~0 0 nZt| | jtjkr>z| | W n4 ty< } ztd| |W Y d }~n
d }~0 0 tt| || d S |tt	 v r|tt| || d S tt	 D ]:}||krq|tt| 	 v rtd||qtt| || d S )	NrE   zCannot change key type    r0   rD   r   r   z Cannot set '{}' on '{}' key type)r   rf   r^   r_   rz   r   r   re   r   rg   r{   r|   r   r2   r4   r   r   ry   r5   r   r   r   r  )rb   itemra   rE   rx   r>   r3   rc   r   r   r   ]  sZ    


zJWK.__setitem__c                 O   s,   t |i | D ]\}}| || qdS zV
        :param \*args: arguments
        :param \**kwargs: keyword arguments
        Ndictr   r   rb   r   r   rD   rx   r   r   r   r     s    z
JWK.updatec                 C   s"   ||   vr| || | |S r   rg   r   r   rb   r   defaultr   r   r   
setdefault  s    zJWK.setdefaultc                    s   |  |}|d u rt||dkrNtt|  D ]}|  |d ur2tdq2|  d}|d ur|tt|  v rd | _d | _tt| 	| d S )NrE   z#Cannot remove 'kty', values present)
r   r   re   r   rg   r{   r|   r_   rz   __delitem__)rb   r  paramr3   rE   rc   r   r   r(    s    


zJWK.__delitem__c                 C   s2   t |tstS |  | ko0| d|dkS NrI   )r   rz   NotImplementedr	  r   )rb   otherr   r   r   __eq__  s
    
z
JWK.__eq__c                 C   s   t |  | dfS r*  )hashr	  r   rh   r   r   r   __hash__  s    zJWK.__hash__c                 C   s   zj|t  v r&||  v r&| |W S | d}|d urd|tt|  v rd||  v rd| |W S tW n ty   t|d Y n0 d S )NrE   )r   rg   r   re   r   r   r   )rb   r  rE   r   r   r   __getattr__  s    
zJWK.__getattr__c                    s   z`|t  v r| || tt D ]$}|tt|  v r&| || q&tt| || W n t	y|   t
|d Y n0 d S r   )r   rg   r   re   rf   r   r_   rz   __setattr__r   r   )rb   r  ra   r3   rc   r   r   r1    s    zJWK.__setattr__c              
   C   sd   |  }ddi}zt |d|d< W n* tyN } zt|W Y d}~n
d}~0 0 |jf i | |S )zCreates a symmetric JWK key from a user password.

        :param password: A password in utf8 format.

        :return: a JWK object
        :rtype: JWK
        rE   r0   r  rD   N)r   r  r   ry   r~   )r   r  r   r   r>   r   r   r   from_password  s    	zJWK.from_passwordc                 C   s(   i }|  dd|d< |  |d< t|S )NrI   zMissing Key IDr	  )r   r	  r   )rb   	repr_dictr   r   r   __repr__  s    zJWK.__repr__)N)N)N)TF)F)F)F)F)N)N)NN)NN)FF)N)r]   )N)Kr   r   r    rk   r`   r!   r   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r~   r   r   r   r   r   r   r   r   propertyr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r  r  r   SHA256r	  r  r   r   r'  r(  r-  r/  r0  r1  r2  r4  rl   r   r   rc   r   rz   +  s   )



	
.
W











	


*
!
&

9

rz   c                   @   s   e Zd Zdd ZdS )_JWKkeysc                 C   s"   t |tstdt| | dS )zAdds a JWK object to the set

        :param elem: the JWK object to add.

        :raises TypeError: if the object is not a JWK.
        z#Only JWK objects are valid elementsN)r   rz   r  setaddrb   elemr   r   r   r9    s    
z_JWKkeys.addN)r   r   r    r9  r   r   r   r   r7    s   r7  c                       s   e Zd ZdZ fddZdd Zdd Z fdd	Zd
d ZdddZ	dd Z
d ddZdd Zedd Zdd Zdd Zdd Z  ZS )!JWKSetzA set of JWK objects.

    Inherits from the standard 'dict' builtin type.
    Creates a special key 'keys' that is of a type derived from 'set'
    The 'keys' attribute accepts only :class:`jwcrypto.jwk.JWK` elements.
    c                    s6   t t|   t t| dt  | j|i | d S Nrg   )r_   r<  r`   r   r7  r   )rb   r   r   rc   r   r   r`     s    zJWKSet.__init__c                 C   s   | d   S r=  )__iter__rh   r   r   r   r>    s    zJWKSet.__iter__c                 C   s   | d  |S r=  )__contains__r  r   r   r   r?    s    zJWKSet.__contains__c                    s8   |dkr"t |ts"| d | ntt| || d S r=  )r   r7  r9  r_   r<  r   )rb   r   r   rc   r   r   r     s    zJWKSet.__setitem__c                 O   s,   t |i | D ]\}}| || qdS r   r!  r#  r   r   r   r     s    zJWKSet.updateNc                 C   s"   ||   vr| || | |S r   r$  r%  r   r   r   r'  !  s    zJWKSet.setdefaultc                 C   s   | d  | d S r=  )r9  r:  r   r   r   r9  &  s    z
JWKSet.addTFc                 C   s`   i }|   D ]>\}}|dkrBg }|D ]}||j|dd q$|}|||< q|du rX|S t|S )a  Exports a RFC 7517 key set.
           Exports as json by default, or as dict if requested.

        :param private_key(bool): Whether to export private keys.
                                  Defaults to True.
        :param as_dict(bool): Whether to return a dict instead of
                              a JSON object

        :return: A portable representation of the key set.
            If as_dict is True then a dictionary is returned.
            By default a json string
        :rtype: `str` or `dict`
        rg   T)r   )r   rw   r   r   )rb   Zprivate_keysr   Zexp_dictrD   rx   rg   jwkr   r   r   r   )  s    
zJWKSet.exportc              
   C   s   zt |}W n* ty6 } zt|W Y d}~n
d}~0 0 d|vrDt| D ]<\}}|dkr|D ]}| d tf i | q`qL|| |< qLdS )zImports a RFC 7517 key set using the standard JSON format.

        :param keyset: The RFC 7517 representation of a JOSE key set.
        Nrg   )r   r   ry   r   r9  rz   )rb   keysetZjwksetr>   rD   rx   r@  r   r   r   import_keysetC  s    zJWKSet.import_keysetc                 C   s   |  }| | |S )zCreates a RFC 7517 key set from the standard JSON format.

        :param keyset: The RFC 7517 representation of a JOSE key set.

        :return: A JWKSet object.
        :rtype: JWKSet
        )rB  )r   rA  r   r   r   r   r   W  s    	
zJWKSet.from_jsonc                 C   sF   |  |}t|dkrtdzt|d W S  ty@   Y dS 0 dS )zGets a key from the set.
        :param kid: the 'kid' key identifier.

        :return: A JWK from the set
        :rtype: JWK
        r   z3Duplicate keys found with requested kid: 1 expectedr   N)get_keysr   ry   tuple
IndexError)rb   rI   rg   r   r   r   get_keyd  s    
zJWKSet.get_keyc                    s    fdd| d D S )zGets keys from the set with matching kid.
        :param kid: the 'kid' key identifier.

        :return: a List of keys
        :rtype: `list`
        c                    s   h | ]}| d  kr|qS rI   r   ).0r   rG  r   r   	<setcomp>{  r  z"JWKSet.get_keys.<locals>.<setcomp>rg   r   )rb   rI   r   rG  r   rC  t  s    zJWKSet.get_keysc                 C   sN   i }|   D ]8\}}|dkr<g }|D ]}|t| q$|}|||< qt|S r=  )r   rw   reprr   )rb   r3  rD   rx   rg   r@  r   r   r   r4  }  s    
zJWKSet.__repr__)N)TF)r   r   r    rk   r`   r>  r?  r   r   r'  r9  r   rB  r!   r   rF  rC  r4  rl   r   r   rc   r   r<     s   


	r<  )Pr   binasciir   r   collectionsr   enumr   Zcryptographyr   Zcryptography.hazmat.backendsr   Zcryptography.hazmat.primitivesr   r	   Z)cryptography.hazmat.primitives.asymmetricr
   r   r   Zjwcrypto.commonr   r   r   r   r   r   ZImplementedOkpCurvesZ1cryptography.hazmat.primitives.asymmetric.ed25519r"   r#   rw   ImportErrorZ/cryptography.hazmat.primitives.asymmetric.ed448r%   r&   Z0cryptography.hazmat.primitives.asymmetric.x25519r(   r)   r   Z
priv_bytesZ.cryptography.hazmat.primitives.asymmetric.x448r+   r,   Z_Ed25519_CURVEZ_Ed448_CURVEZ_X25519_CURVEZ_X448_CURVEr   rf   r2   ZJWKParameterr3   r4   r5   r6   r   r   ZJWKEllipticCurveRegistryro   rv   r   r6  SHA384SHA512ZSHA3_224ZSHA3_256ZSHA3_384ZSHA3_512ZBLAKE2sZBLAKE2br  r^   rm   rr   ry   r"  rz   r8  r7  r<  r   r   r   r   <module>   sF  








	

"		       N