
Z$                 @   sC  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 j e  Z Gd	 d
   d
 e j  Z e j Gd d   d e   Z e j Gd d   d e   Z e j Gd d   d e   Z d S)zJSON Web Key.    N)default_backend)hashes)serialization)ec)rsa)errors	json_utilutilc               @   s   e  Z d  Z d Z d Z i  Z f  Z e Z d d d d d d	 i Z	 e
 j d
 d  Z e j d d    Z e d d d d   Z e d d d d   Z d S)JWKzJSON Web Key.ZktyindentNZ
separators,:Z	sort_keysTc                so   t  j |   d t   } | j t j t   f d d   t j   j	    D    j
  j    | j   S)zgCompute JWK Thumbprint.

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

        :returns: bytes

        backendc             3   s0   |  ]& \ } } |   j  k r | | f Vq d  S)N)required).0kv)self ,/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)NotImplementedError)r   r   r   r   
public_key8   s    zJWK.public_keyc             C   s  | d  k r t    n | } i  } xo t j t j f D][ } y | | | |  SWq4 t t t j j f k
 r } z | | | <WYd  d  } ~ Xq4 Xq4 Wxi t j	 t j
 f D]U } y | | |  SWq t t j j f k
 r } z | | | <WYd  d  } ~ Xq Xq Wt j d j |    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   y |  j  | | |  } WnE t j k
 r` } z" t j d |  t d |  SWYd d } ~ Xn X|  j t k	 r t | |  j	  r t j d j
 | j |  j    x9 t j |  j  D]% } t | | j	  r | d |  Sq Wt j d j
 | 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})r.   r   r'   loggerdebugJWKOcttypNotImplemented
isinstancecryptography_key_typesr(   	__class__r   Z
itervaluesTYPES)r)   r*   r+   r   r/   r-   Zjwk_clsr   r   r   load[   s     zJWK.load)r   r   )__name__
__module____qualname____doc__type_field_namer8   r6   r4   r   r   r   ZSHA256r    abcabstractmethodr"   classmethodr.   r9   r   r   r   r   r
      s   	r
   c               @   sm   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)N)r!   )r   r   r   r   fields_to_partial_json   s    zJWKES.fields_to_partial_jsonc             C   s   t     d  S)N)r!   )r)   jobjr   r   r   fields_from_json   s    zJWKES.fields_from_jsonc             C   s   t     d  S)N)r!   )r   r   r   r   r"      s    zJWKES.public_keyN)r:   r;   r<   r=   r3   r   ZEllipticCurvePublicKeyZEllipticCurvePrivateKeyr6   r
   r>   r   rE   rA   rG   r"   r   r   r   r   rB   {   s   rB   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)r2   zSymmetric JWK.octr/   r   c             C   s   d t  j |  j  i S)Nr   )r   encode_b64joser/   )r   r   r   r   rE      s    zJWKOct.fields_to_partial_jsonc             C   s   |  d t  j | d   S)Nr/   r   )r   decode_b64jose)r)   rF   r   r   r   rG      s    zJWKOct.fields_from_jsonc             C   s   |  S)Nr   )r   r   r   r   r"      s    zJWKOct.public_keyN)zkey)r:   r;   r<   r=   r3   	__slots__r
   r>   r   rE   rA   rG   r"   r   r   r   r   r2      s   r2   c                   s   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   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RSAr/   enc                sW   d | k r: t  | d t j  r: t j | d  | d <t t |   j | |   d  S)Nr/   )r5   r	   ZComparableRSAKeysuperrL   __init__)r   argskwargs)r7   r   r   rP      s    zJWKRSA.__init__c             C   sA   d d   } t  j t j | t |  d d  j 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_zerosrS   NL)r   rI   binasciiZ	unhexlifyhexrstrip)r)   r*   rW   r   r   r   _encode_param   s    zJWKRSA._encode_paramc             C   sH   y# t  t j t j |   d  SWn t k
 rC t j    Yn Xd S)zDecode Base64urlUInt.   N)intrY   Zhexlifyr   rJ   r#   r   ZDeserializationError)r)   r*   r   r   r   _decode_param   s    #zJWKRSA._decode_paramc             C   s   t  |   d |  j j    S)Nr/   )typer/   r"   )r   r   r   r   r"      s    zJWKRSA.public_keyc                s     f d d   d D \ } } t  j d | d |  } d  k r[ | j t    } nm  j  d  } d  k s d  k s d  k s d	  k s d
  k s d  k rJt  f d d   d D  \ } } }	 }
 } } t d d   | D  rt j d j |    t   f d d   | D  \ } } }	 }
 } nQ t  j	 | | |  \ } } t  j
 | |  }	 t  j | |  }
 t  j | |  } t  j | | | |	 |
 | |  j t    }   d |  S)Nc             3   s"   |  ] }   j   |  Vq d  S)N)r_   )r   rC   )r)   rF   r   r   r      s    z*JWKRSA.fields_from_json.<locals>.<genexpr>rN   rM   dpqdpdqqiZothc             3   s   |  ] }   j  |  Vq d  S)N)get)r   rC   )rF   r   r   r      s    c             s   s!   |  ] } | d  k r | Vq d  S)Nr   )r   Zparamr   r   r   r      s    z(Some private parameters are missing: {0}c             3   s   |  ] }   j  |  Vq d  S)N)r_   )r   rC   )r)   r   r   r      s    r/   )rN   rM   )rb   rc   zdpzdqzqi)r   ZRSAPublicNumbersr"   r   r_   tupler   r'   r(   Zrsa_recover_prime_factorsZrsa_crt_dmp1Zrsa_crt_dmq1Zrsa_crt_iqmpZRSAPrivateNumbersZprivate_key)r)   rF   rN   rM   public_numbersr/   ra   rb   rc   rd   re   rf   Z
all_paramsr   )r)   rF   r   rG      s.    "$$/.zJWKRSA.fields_from_jsonc                s   t    j j t j  rB   j j   } d | j d | j i } nr   j j   }   j j	   j   } d | j d | j d | j
 d | j d | j d | j d | j d | j i } t   f d	 d
   t j |  D  S)NrN   rM   ra   rb   rc   rd   re   rf   c             3   s*   |  ]  \ } } |   j  |  f Vq d  S)N)r\   )r   r/   value)r   r   r   r     s   z0JWKRSA.fields_to_partial_json.<locals>.<genexpr>)r5   r/   Z_wrappedr   RSAPublicKeyri   rN   rM   Zprivate_numbersr"   ra   rb   rc   Zdmp1Zdmq1Ziqmpr   r   r   )r   ZnumbersZparamsZprivateZpublicr   )r   r   rE      s     								zJWKRSA.fields_to_partial_json)zkey)r:   r;   r<   r=   r3   r   rk   ZRSAPrivateKeyr6   rK   r
   r>   r   rP   rA   r\   r_   r"   rG   rE   r   r   )r7   r   rL      s   'rL   )r=   r?   rY   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:   r0   ZTypedJSONObjectWithFieldsr
   registerrB   r2   rL   r   r   r   r   <module>   s(   g