U
    ]$                     @   s   d Z ddlZddlZddlZ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 ddlmZmZmZ eeZG d	d
 d
ej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)default_backend)hashes)serialization)ec)rsa)errors	json_utilutilc                   @   sd   e Zd ZdZdZi ZdZeZddddZ	e
jfdd	Zejd
d ZedddZedddZdS )JWKr   Zkty N),:T)indentZ
separatorsZ	sort_keysc              	      sP   t j| t d}|tjt fddt 	 D f j
  | S )zgCompute JWK Thumbprint.

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

        :returns: bytes

        )backendc                 3   s$   | ]\}}| j kr||fV  qd S N)required).0kvselfr   ,/usr/lib/python3/dist-packages/josepy/jwk.py	<genexpr>3   s    
z!JWK.thumbprint.<locals>.<genexpr>)r   ZHashr   updatejsondumpsdictsix	iteritemsZto_json_thumbprint_json_dumps_paramsencodefinalize)r   Zhash_functionZdigestr   r   r   
thumbprint)   s    
zJWK.thumbprintc                 C   s
   t  dS )ziGenerate JWK with public key.

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

        NNotImplementedErrorr   r   r   r   
public_key8   s    zJWK.public_keyc                 C   s   |d krt  n|}i }tjtjfD ]L}z||||W   S  tttjjfk
rl } z|||< W 5 d }~X Y q"X q"tj	tj
fD ]H}z|||W   S  ttjjfk
r } z|||< W 5 d }~X Y q|X q|td|d S )NzUnable to deserialize key: {0})r   r   Zload_pem_private_keyZload_der_private_key
ValueError	TypeErrorcryptography
exceptionsZUnsupportedAlgorithmZload_pem_public_keyZload_der_public_keyr   Errorformat)clsdatapasswordr   r*   loadererrorr   r   r   _load_cryptography_keyA   s*    zJWK._load_cryptography_keyc              
   C   s   z|  |||}W n> tjk
rP } ztd| t|d W Y S d}~X Y nX | jtk	r~t|| j	s~td
|j| jt| jD ]}t||j	r||d  S qtd
|jdS )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keyNz"Unable to deserialize {0} into {1}zUnsupported algorithm: {0})r2   r   r+   loggerdebugJWKOcttypNotImplemented
isinstancecryptography_key_typesr,   	__class__r   Z
itervaluesTYPES)r-   r.   r/   r   r4   r1   Zjwk_clsr   r   r   load[   s"       zJWK.load)NN)NN)__name__
__module____qualname____doc__type_field_namer=   r;   r9   r   r    r   ZSHA256r#   abcabstractmethodr&   classmethodr2   r>   r   r   r   r   r      s    

r   c                   @   sJ   e Zd ZdZdZejejfZde	j
ddfZdd Zedd	 Zd
d ZdS )JWKESz<ES JWK.

    .. warning:: This is not yet implemented!

    ZESZcrvxyc                 C   s
   t  d S r   r$   r   r   r   r   fields_to_partial_json   s    zJWKES.fields_to_partial_jsonc                 C   s
   t  d S r   r$   r-   jobjr   r   r   fields_from_json   s    zJWKES.fields_from_jsonc                 C   s
   t  d S r   r$   r   r   r   r   r&      s    zJWKES.public_keyN)r?   r@   rA   rB   r8   r   ZEllipticCurvePublicKeyZEllipticCurvePrivateKeyr;   r   rC   r   rJ   rF   rM   r&   r   r   r   r   rG   {   s    
rG   c                   @   s>   e Zd ZdZdZdZdejfZdd Z	e
dd Zd	d
 ZdS )r7   zSymmetric JWK.octr3   r   c                 C   s   dt | jiS )Nr   )r	   encode_b64joser4   r   r   r   r   rJ      s    zJWKOct.fields_to_partial_jsonc                 C   s   | t |d dS )Nr   r3   )r	   decode_b64joserK   r   r   r   rM      s    zJWKOct.fields_from_jsonc                 C   s   | S r   r   r   r   r   r   r&      s    zJWKOct.public_keyN)r?   r@   rA   rB   r8   	__slots__r   rC   r   rJ   rF   rM   r&   r   r   r   r   r7      s   

r7   c                       st   e Zd ZdZdZejejfZdZ	de
jdfZ fddZedd	 Zed
d Zdd Zedd Z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`

    ZRSAr3   enc                    s@   d|kr*t |d tjs*t|d |d< tt| j|| d S )Nr4   )r:   r
   ZComparableRSAKeysuperrR   __init__)r   argskwargsr<   r   r   rV      s    
 zJWKRSA.__init__c                 C   s.   dd }t t|t|dd dS )zQEncode Base64urlUInt.

        :type data: long
        :rtype: unicode

        c                 S   s   t | d rd|  S | S )N   0)len)argr   r   r   _leading_zeros   s    z,JWKRSA._encode_param.<locals>._leading_zerosrZ   NL)r	   rO   binasciiZ	unhexlifyhexrstrip)r-   r.   r^   r   r   r   _encode_param   s    zJWKRSA._encode_paramc                 C   s:   zt tt|dW S  tk
r4   t Y nX dS )zDecode Base64urlUInt.   N)intr`   Zhexlifyr	   rP   r'   r   ZDeserializationError)r-   r.   r   r   r   _decode_param   s    zJWKRSA._decode_paramc                 C   s   t | | j dS )Nr3   )typer4   r&   r   r   r   r   r&      s    zJWKRSA.public_keyc              	      s@   fdddD \}}t j||d}dkr<|t }n d }dkszdkszdkszd	kszd
kszdkrtfdddD  \}}}	}
}}tdd |D rtd|t fdd|D \}}}	}
}n6t 	|||\}}t 
||}	t ||}
t ||}t ||||	|
||t } |dS )Nc                 3   s   | ]}  | V  qd S r   rf   r   rH   rK   r   r   r      s     z*JWKRSA.fields_from_json.<locals>.<genexpr>rT   rS   )rS   rT   dpqdpdqqiZothc                 3   s   | ]}  |V  qd S r   )getri   )rL   r   r   r      s    )rl   rm   rn   ro   rp   c                 s   s   | ]}|d kr|V  qd S r   r   )r   Zparamr   r   r   r      s      z(Some private parameters are missing: {0}c                 3   s   | ]}  |V  qd S r   rh   ri   )r-   r   r   r      s    r3   )r   ZRSAPublicNumbersr&   r   rf   tupler   r+   r,   Zrsa_recover_prime_factorsZrsa_crt_dmp1Zrsa_crt_dmq1Zrsa_crt_iqmpZRSAPrivateNumbersZprivate_key)r-   rL   rT   rS   public_numbersr4   rk   rl   rm   rn   ro   rp   Z
all_paramsr   rK   r   rM      sP          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}t fddt|D S )Nrj   )rT   rS   rk   rl   rm   rn   ro   rp   c                 3   s    | ]\}}|  |fV  qd S r   )rc   )r   r4   valuer   r   r   r     s   z0JWKRSA.fields_to_partial_json.<locals>.<genexpr>)r:   r4   Z_wrappedr   RSAPublicKeyrs   rT   rS   Zprivate_numbersr&   rk   rl   rm   Zdmp1Zdmq1Ziqmpr   r   r   )r   ZnumbersZparamsZprivateZpublicr   r   r   rJ      s&    


zJWKRSA.fields_to_partial_json)r?   r@   rA   rB   r8   r   ru   ZRSAPrivateKeyr;   rQ   r   rC   r   rV   rF   rc   rf   r&   rM   rJ   __classcell__r   r   rY   r   rR      s   


&rR   )rB   rD   r`   r   ZloggingZcryptography.exceptionsr)   r   Zcryptography.hazmat.backendsr   Zcryptography.hazmat.primitivesr   r   Z)cryptography.hazmat.primitives.asymmetricr   r   Zjosepyr   r	   r
   Z	getLoggerr?   r5   ZTypedJSONObjectWithFieldsr   registerrG   r7   rR   r   r   r   r   <module>   s(   
g