o
    c6                     @   s  d Z ddlZddlZddlZddlZddlmZmZmZm	Z	m
Z
mZmZmZ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ZddlmZmZmZ eeZ G dd	 d	ej!ej"d
Z#e#j$G dd de#Z%e#j$G dd de#Z&e#j$G dd de#Z'dS )JSON Web Key.    N)	AnyCallableDictMappingOptionalSequenceTupleTypeUnion)default_backend)hashesserialization)ecrsa)errors	json_utilutilc                
   @   s  e Zd ZU dZdZi Zeeed  f e	d< dZ
eee df e	d< 	 eZee e	d< 	 dd	d
dZeeeee ee ef f e	d< ee	d< ejfdeg ejf defddZejdddZe		ddedee dee defddZe		ddedee dee dd fddZ dS )JWKr   ktyTYPES .cryptography_key_typesrequiredN),:T)indent
separators	sort_keys_thumbprint_json_dumps_paramskeyhash_functionreturnc                    sN   t j| t d}|tj fdd   D fi  j	  |
 S )zgCompute JWK Thumbprint.

        https://tools.ietf.org/html/rfc7638

        :returns: bytes

        )backendc                    s    i | ]\}}| j v r||qS r   )r   ).0kvselfr   7/opt/certbot/lib/python3.10/site-packages/josepy/jwk.py
<dictcomp>=   s    z"JWK.thumbprint.<locals>.<dictcomp>)r   Hashr   updatejsondumpsto_jsonitemsr   encodefinalize)r(   r!   digestr   r'   r)   
thumbprint2   s   	zJWK.thumbprintc                 C   s   t  )ziGenerate JWK with public key.

        For symmetric cryptosystems, this would return ``self``.

        )NotImplementedErrorr'   r   r   r)   
public_keyB   s   zJWK.public_keydatapasswordr#   c                 C   s   |d u rt  n|}i }tjtjfD ](}z	||||W   S  tttjjfy9 } z||t	|< W Y d }~qd }~ww tj
tjfD ]&}z|||W   S  ttjjfyf } z||t	|< W Y d }~q@d }~ww td|)NzUnable to deserialize key: {0})r   r   load_pem_private_keyload_der_private_key
ValueError	TypeErrorcryptography
exceptionsUnsupportedAlgorithmstrload_pem_public_keyload_der_public_keyr   Errorformat)clsr7   r8   r#   r>   loader_privateerrorloader_publicr   r   r)   _load_cryptography_keyK   s2   zJWK._load_cryptography_keyc              
   C   s   z	|  |||}W n tjy' } ztd| t|dW  Y d}~S d}~ww | jtur>t|| j	s>td
|j| j| j D ]}t||j	rR||d  S qCtd
|j)a  Load serialized key as JWK.

        :param str data: Public or private key serialized as PEM or DER.
        :param str password: Optional password.
        :param backend: A `.PEMSerializationBackend` and
            `.DERSerializationBackend` provider.

        :raises errors.Error: if unable to deserialize, or unsupported
            JWK algorithm

        :returns: JWK of an appropriate type.
        :rtype: `JWK`

        z,Loading symmetric key, asymmetric failed: %sr    Nz"Unable to deserialize {0} into {1}zUnsupported algorithm: {0})rI   r   rC   loggerdebugJWKOcttypNotImplemented
isinstancer   rD   	__class__r   values)rE   r7   r8   r#   r    rG   jwk_clsr   r   r)   loadh   s    zJWK.load)r"   r   )NN)!__name__
__module____qualname____doc__type_field_namer   r   r@   r
   __annotations__r   r	   r   rO   r   r   r   r   r   intboolr   SHA256r   HashAlgorithmbytesr4   abcabstractmethodr6   classmethodrI   rT   r   r   r   r)   r      sJ   
 (	
r   )	metaclassc                   @   sj   e Zd ZU dZdZdZdejfZe	e
d< deeef fddZed	eeef dd fd
dZdddZdS )rM   zSymmetric JWK.octrJ   r%   r    r"   c                 C   s   dt | jiS )Nr%   )r   encode_b64joser    r'   r   r   r)   fields_to_partial_json   s   zJWKOct.fields_to_partial_jsonjobjc                 C   s   | t |d dS )Nr%   rJ   )r   decode_b64joserE   rg   r   r   r)   fields_from_json   s   zJWKOct.fields_from_jsonc                 C   s   | S Nr   r'   r   r   r)   r6      s   zJWKOct.public_keyN)r"   rM   )rU   rV   rW   rX   rN   	__slots__r   rY   r   r_   rZ   r   r@   rf   rb   r   r   rj   r6   r   r   r   r)   rM      s   
 
rM   c                       s   e Zd ZU dZdZejejfZdZ	de
jdfZejjed< deded	d
f fddZeded	efddZeded	efddZdddZedeeef d	d fddZd	eeef fddZ  ZS )JWKRSAzRSA JWK.

    :ivar key: :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`
        or :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey` wrapped
        in :class:`~josepy.util.ComparableRSAKey`

    RSArJ   enr    argskwargsr"   Nc                    @   d|v rt |d tjst|d |d< t j|i | d S Nr    )rP   r   ComparableRSAKeysuper__init__r(   rq   rr   rQ   r   r)   rw      
   

zJWKRSA.__init__r7   c                 C   s0   t | d}t|d }t|jd|dS )zOEncode Base64urlUInt.
        :type data: long
        :rtype: unicode
           big	byteorderlength)max
bit_lengthmathceilr   re   to_bytesrE   r7   r   r   r   r)   _encode_param   s   zJWKRSA._encode_paramc                 C   s>   zt |}|st tj|ddW S  ty   t w )Decode Base64urlUInt.r|   r~   )r   rh   r   DeserializationErrorr[   
from_bytesr;   )rE   r7   binaryr   r   r)   _decode_param   s   
zJWKRSA._decode_paramc                 C   s   t | | j dS )NrJ   )typer    r6   r'   r   r   r)   r6      s   zJWKRSA.public_keyrg   c              	      sD   fdddD \}}t j||d}dvr  |t dS  d }dv s?dv s?d	v s?d
v s?dv s?dv rstfdddD  \}}}}	}
}tdd |D rbtd|t fdd|D \}}}}	}
nt 	|||\}}t 
||}t ||}	t ||}
t |||||	|
|t } |dS )Nc                 3   s    | ]
}  | V  qd S rk   r   r$   xri   r   r)   	<genexpr>   s    z*JWKRSA.fields_from_json.<locals>.<genexpr>rp   ro   )ro   rp   drJ   pqdpdqqiothc                 3   s    | ]}  |V  qd S rk   )getr   )rg   r   r)   r      s    

)r   r   r   r   r   c                 s   s    | ]	}|d u r|V  qd S rk   r   )r$   paramr   r   r)   r      s    z(Some private parameters are missing: {0}c                 3   s    | ]
}  t|V  qd S rk   )r   r@   r   )rE   r   r)   r      s    
)r   RSAPublicNumbersr6   r   r   tupler   rC   rD   rsa_recover_prime_factorsrsa_crt_dmp1rsa_crt_dmq1rsa_crt_iqmpRSAPrivateNumbersprivate_key)rE   rg   rp   ro   public_numbersr   r   r   r   r   r   
all_paramsr    r   ri   r)   rj      sH   
zJWKRSA.fields_from_jsonc              	      s~   t  jjtjr j }|j|jd}n j } j	  }|j|j|j
|j|j|j|j|jd} fdd| D S )Nr   )rp   ro   r   r   r   r   r   r   c                    s   i | ]
\}}|  |qS r   )r   r$   r    valuer'   r   r)   r*   	  s    z1JWKRSA.fields_to_partial_json.<locals>.<dictcomp>)rP   r    _wrappedr   RSAPublicKeyr   rp   ro   private_numbersr6   r   r   r   dmp1dmq1iqmpr0   )r(   numbersparamsprivatepublicr   r'   r)   rf      s&   



zJWKRSA.fields_to_partial_json)r"   rm   )rU   rV   rW   rX   rN   r   r   RSAPrivateKeyr   rl   r   rY   r   josepyr   ru   rZ   r   rw   rb   r[   r@   r   r   r6   r   rj   r   rf   __classcell__r   r   ry   r)   rm      s    
 	

(rm   c                	       s  e Zd ZU dZdZdZejejfZ	de
jddfZejjed< ded	ed
df fddZededed
efddZedededed
efddZeded
efddZeded
ejfddZedejd
efddZd
eeef fddZed eeef d
d fd!d"Zd%d#d$Z   Z!S )&JWKECzEC JWK.

    :ivar key: :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey`
        or :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey` wrapped
        in :class:`~josepy.util.ComparableECKey`

    ECrJ   crvr   yr    rq   rr   r"   Nc                    rs   rt   )rP   r   ComparableECKeyrv   rw   rx   ry   r   r)   rw     rz   zJWKEC.__init__r7   r   c                 C   s   t |jd|dS )zlEncode Base64urlUInt.
        :type data: long
        :type key_size: long
        :rtype: unicode
        r|   r}   )r   re   r   r   r   r   r)   r   #  s   zJWKEC._encode_paramnamevalid_lengthc              	   C   s`   z$t |}t||krtd| d| dt| dtj|ddW S  ty/   t w )r   zExpected parameter "z" to be z" bytes after base64-decoding; got z bytes insteadr|   r   )r   rh   lenr   r   r[   r   r;   )rE   r7   r   r   r   r   r   r)   r   ,  s   
zJWKEC._decode_param
curve_namec                 C   s,   |dkrdS |dkrdS |dkrdS t  )N	secp256r1P-256	secp384r1P-384	secp521r1P-521)r   SerializationError)rE   r   r   r   r)   _curve_name_to_crv:  s   zJWKEC._curve_name_to_crvc                 C   s8   |dkrt  S |dkrt  S |dkrt  S t )Nr   r   r   )r   	SECP256R1	SECP384R1	SECP521R1r   r   )rE   r   r   r   r)   _crv_to_curveD  s   zJWKEC._crv_to_curvecurvec                 C   s>   t |tjrdS t |tjrdS t |tjrdS td| )N    0   B   zUnexpected curve: )rP   r   r   r   r   r;   )rE   r   r   r   r)   expected_length_for_curveO  s   zJWKEC.expected_length_for_curvec                    s   i }t jjtjrj  nt jjtjr*j }j   |j	|d< nt
d j|d<  j|d<  fdd| D } jj|d< |S )Nr   zRSupplied key is neither of type EllipticCurvePublicKey nor EllipticCurvePrivateKeyr   r   c              	      s&   i | ]\}}| | jqS r   )r   r   r   r   r   r(   r   r)   r*   h  s    z0JWKEC.fields_to_partial_json.<locals>.<dictcomp>r   )rP   r    r   r   EllipticCurvePublicKeyr   EllipticCurvePrivateKeyr   r6   private_valuer   r   r   r   r0   r   r   r   )r(   r   r   r   r   r)   rf   Y  s"   


zJWKEC.fields_to_partial_jsonrg   c                    s     d } | fdddD \}}tj|||d}dvr. |t dS  d d}t||t } |dS )Nr   c                 3   s"    | ]}  | |V  qd S rk   r   )r$   rp   rE   expected_lengthrg   r   r)   r   s  s     z)JWKEC.fields_from_json.<locals>.<genexpr>)r   r   )r   r   r   r   rJ   )	r   r   r   EllipticCurvePublicNumbersr6   r   r   EllipticCurvePrivateNumbersr   )rE   rg   r   r   r   r   r   r    r   r   r)   rj   o  s   

zJWKEC.fields_from_jsonc                 C   s8   t | jdr| j }n	| j t }t| |dS )Nr6   rJ   )hasattrr    r6   r   r   r   )r(   r    r   r   r)   r6     s   zJWKEC.public_key)r"   r   )"rU   rV   rW   rX   rN   rl   r   r   r   r   r   rY   r   r   r   r   rZ   r   rw   rb   r[   r@   r   r   r   EllipticCurver   r   r   rf   r   rj   r6   r   r   r   ry   r)   r     s.   
 	
	r   )(rX   r`   r-   loggingr   typingr   r   r   r   r   r   r	   r
   r   cryptography.exceptionsr=   cryptography.hazmat.backendsr   cryptography.hazmat.primitivesr   r   )cryptography.hazmat.primitives.asymmetricr   r   josepy.utilr   r   r   r   	getLoggerrU   rK   TypedJSONObjectWithFieldsABCMetar   registerrM   rm   r   r   r   r   r)   <module>   s(    ,
km