U
    ;gx                     @   sj  d dl mZmZmZm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mZmZmZmZmZmZ ddlmZmZmZ ddlmZmZm Z m!Z!m"Z" ddl#m$Z$ ddl%m&Z& dd	l'm(Z(m)Z)m*Z* G d
d dZ+G dd dZ,G dd dZ-dd Z.dd Z/e e!ee"edZ0dd Z1dd Z2d%ddZ3d&ddZ4dd Z5dd  Z6d!d" Z7d#d$ Z8dS )'    )unicode_literalsdivisionabsolute_importprint_functionN   )CertBagCertificateDSAPrivateKeyECPrivateKeyEncryptedDataEncryptedPrivateKeyInfoIntegerOctetStringPfxPrivateKeyInfoPublicKeyInfoRSAPrivateKeyRSAPublicKeySafeContentsunarmor)pbkdf1pbkdf2
pkcs12_kdf)aes_cbc_pkcs7_decryptdes_cbc_pkcs5_decryptrc2_cbc_pkcs5_decryptrc4_decrypttripledes_cbc_pkcs5_decrypt)constant_compare)pretty_message)byte_clsstr_cls	type_namec                   @   sL   e Zd ZdZdZdd Zedd Zedd Zedd	 Z	ed
d Z
dS )_PrivateKeyBaseNc                 C   s   | j dkr| jd jS | j dkr^| jd d }td|d |d |d	 | j | jd jd
S | j dkr| jd j}| jd d |d< | j |d< |S dS )a.  
        Unwraps the private key into an asn1crypto.keys.RSAPrivateKey,
        asn1crypto.keys.DSAPrivateKey or asn1crypto.keys.ECPrivateKey object

        :return:
            An asn1crypto.keys.RSAPrivateKey, asn1crypto.keys.DSAPrivateKey or
            asn1crypto.keys.ECPrivateKey object
        rsaprivate_keydsaprivate_key_algorithm
parametersr   pqgversionr)   r*   r+   
public_keyr%   ecr.   N)	algorithmasn1parsedr	   r.   unwrap)selfparamsoutput r7   8/tmp/pip-unpacked-wheel-x1gypflw/oscrypto/_asymmetric.pyr3   -   s"    



	
z_PrivateKeyBase.unwrapc                 C   s   | j jS zO
        :return:
            A unicode string of "rsa", "dsa" or "ec"
        r1   r0   r4   r7   r7   r8   r0   K   s    z_PrivateKeyBase.algorithmc                 C   s   | j jd S H
        :return:
            A unicode string of EC curve name
        r   r1   curver;   r7   r7   r8   r?   T   s    z_PrivateKeyBase.curvec                 C   s   | j jS zS
        :return:
            The number of bits in the key, as an integer
        r1   bit_sizer;   r7   r7   r8   rB   ]   s    z_PrivateKeyBase.bit_sizec                 C   s   | j jS zT
        :return:
            The number of bytes in the key, as an integer
        r1   	byte_sizer;   r7   r7   r8   rE   f   s    z_PrivateKeyBase.byte_size)__name__
__module____qualname__r1   _fingerprintr3   propertyr0   r?   rB   rE   r7   r7   r7   r8   r#   (   s   


r#   c                   @   sX   e Zd ZdZdZdd Zedd Zedd Zedd	 Z	ed
d Z
edd ZdS )_PublicKeyBaseNc                 C   s    | j dkr| jd S | jd jS )a7  
        Unwraps a public key into an asn1crypto.keys.RSAPublicKey,
        asn1crypto.core.Integer (for DSA) or asn1crypto.keys.ECPointBitString
        object

        :return:
            An asn1crypto.keys.RSAPublicKey, asn1crypto.core.Integer or
            asn1crypto.keys.ECPointBitString object
        r/   r.   )r0   r1   r2   r;   r7   r7   r8   r3   u   s    

z_PublicKeyBase.unwrapc                 C   s   | j dkrt | jd| _ | j S )aZ  
        Creates a fingerprint that can be compared with a private key to see if
        the two form a pair.

        This fingerprint is not compatible with fingerprints generated by any
        other software.

        :return:
            A byte string that is a sha256 hash of selected components (based
            on the key type)
        N)rI   r1   r;   r7   r7   r8   fingerprint   s    
z_PublicKeyBase.fingerprintc                 C   s   | j jS r9   r:   r;   r7   r7   r8   r0      s    z_PublicKeyBase.algorithmc                 C   s   | j jd S r<   r>   r;   r7   r7   r8   r?      s    z_PublicKeyBase.curvec                 C   s   | j jS r@   rA   r;   r7   r7   r8   rB      s    z_PublicKeyBase.bit_sizec                 C   s   | j jS rC   rD   r;   r7   r7   r8   rE      s    z_PublicKeyBase.byte_size)rF   rG   rH   r1   rI   r3   rJ   rL   r0   r?   rB   rE   r7   r7   r7   r8   rK   p   s   



rK   c                   @   s@   e Zd ZdZedd Zedd Zedd Zedd	 ZdS )
_CertificateBaseNc                 C   s   | j jS r9   )r.   r0   r;   r7   r7   r8   r0      s    z_CertificateBase.algorithmc                 C   s   | j jS )r=   )r.   r?   r;   r7   r7   r8   r?      s    z_CertificateBase.curvec                 C   s   | j jS )zZ
        :return:
            The number of bits in the public key, as an integer
        )r.   rB   r;   r7   r7   r8   rB      s    z_CertificateBase.bit_sizec                 C   s   | j jS )z[
        :return:
            The number of bytes in the public key, as an integer
        )r.   rE   r;   r7   r7   r8   rE      s    z_CertificateBase.byte_size)	rF   rG   rH   r1   rJ   r0   r?   rB   rE   r7   r7   r7   r8   rM      s   


rM   c                 C   s   | j }|dks|dkr | d jS |dkrz| d d }| d j}td|d |d	 |d
 tt|d
 j|j|d j|dS |dkr| d j}| d d |d< |S td| j  dS )a  
    Unwraps an asn1crypto.keys.PrivateKeyInfo object into an
    asn1crypto.keys.RSAPrivateKey, asn1crypto.keys.DSAPrivateKey
    or asn1crypto.keys.ECPrivateKey.

    :param key_info:
        An asn1crypto.keys.PrivateKeyInfo object

    :return:
        One of:
         - asn1crypto.keys.RSAPrivateKey
         - asn1crypto.keys.DSAPrivateKey
         - asn1crypto.keys.ECPrivateKey
    r$   Z
rsassa_pssr%   r&   r'   r(   r   r)   r*   r+   r,   r/   z#Unsupported key_info.algorithm "%s"N)r0   r2   r	   r   pownative
ValueError)key_infoZkey_algr5   r2   r7   r7   r8   _unwrap_private_key_info   s.    


rR   c                 C   s  t | tr| d j}| jdkr:d|d j|d jf }n| jdkr| d d }tt|d	 j| d jj|d
 j}d|d
 j|d j|d	 j|jf }nT| jdkr|d j}|dkr|| j}|jd jj}d| j	d  }|
d}||7 }t |tr|
d}t| S t | tr| jdkrN| d j}d|d j|d jf }n~| jdkr| d j}| d d }d|d
 j|d j|d	 j|jf }n6| jdkr| d j}d| j	d  }|
d}||7 }t |tr|
d}t| S ttdt| dS )a5  
    Returns a fingerprint used for correlating public keys and private keys

    :param key_object:
        An asn1crypto.keys.PrivateKeyInfo or asn1crypto.keys.PublicKeyInfo

    :raises:
        ValueError - when the key_object is not of the proper type

    ;return:
        A byte string fingerprint
    r%   r$   z%d:%dmoduluspublic_exponentr&   r'   r(   r+   r)   z%d:%d:%d:%dr*   r/   r.   Nz%s:r   zutf-8r0   z
        key_object must be an instance of the
        asn1crypto.keys.PrivateKeyInfo or asn1crypto.keys.PublicKeyInfo
        classes, not %s
        )
isinstancer   r2   r0   rO   r   rN   r.   r1   r?   encoder!   hashlibsha256digestr   rP   r   r"   )Z
key_objectload_private_keykeyZto_hashr5   r.   Zpublic_key_objectr7   r7   r8   rI     sv    













rI   )rc2rc4des	tripledesaesc                 C   s(  t | tsttdt| d}td| dk	rft| \}}} |dkrRttd|dkrft	
| dS |dksv|dkrzt	| }|j |W S  tk
r   Y nX zt| }|j t	
|dW S  tk
r   Y nX |dks|dkrzt| }|d	 d
 }|W S  tk
r   Y nX tddS )a  
    Loads a public key from a DER or PEM-formatted file. Supports RSA, DSA and
    EC public keys. For RSA keys, both the old RSAPublicKey and
    SubjectPublicKeyInfo structures are supported. Also allows extracting a
    public key from an X.509 certificate.

    :param data:
        A byte string to load the public key from

    :raises:
        ValueError - when the data does not appear to contain a public key

    :return:
        An asn1crypto.keys.PublicKeyInfo object
    <
            data must be a byte string, not %s
            N   \s*-----private keyz
                The data specified does not appear to be a public key or
                certificate, but rather a private key
                r$   
public keycertificatetbs_certificatesubject_public_key_infozQThe data specified does not appear to be a known public key or certificate format)rU   r    	TypeErrorr   r"   rematch_unarmor_pemrP   r   wraploadrO   r   r   )datakey_typealgopkiZrpkZparsed_certrQ   r7   r7   r8   parse_public~  sF    




rr   c                 C   s   t | tsttdt| d}td| dk	rft| \}}} |dkrRttd|dkrfttd|dksv|dkrzt	
| W S  tk
r   Y nX ttd	dS )
a@  
    Loads a certificate from a DER or PEM-formatted file. Supports X.509
    certificates only.

    :param data:
        A byte string to load the certificate from

    :raises:
        ValueError - when the data does not appear to contain a certificate

    :return:
        An asn1crypto.x509.Certificate object
    ra   Nrb   rc   z
                The data specified does not appear to be a certificate, but
                rather a private key
                rd   z
                The data specified does not appear to be a certificate, but
                rather a public key
                re   zU
        The data specified does not appear to be a known certificate format
        )rU   r    rh   r   r"   ri   rj   rk   rP   r   rm   )rn   ro   _r7   r7   r8   parse_certificate  s0    
rt   c           
      C   s  t | tsttdt| |dk	rBt |tsFttdt|nd}td| dk	rt| |\}}} |dkrzttd|dkrttd	zt	
| }|j |W S  tk
r   Y nX z>t
| }|d
 }|d j}t|||}t	
|}|j |W S  tk
r   Y nX zt
| }	|	j t	|	dW S  tk
rD   Y nX zt
| }	|	j t	|	dW S  tk
rz   Y nX zt
| }	|	j t	|	dW S  tk
r   Y nX ttddS )a%  
    Loads a private key from a DER or PEM-formatted file. Supports RSA, DSA and
    EC private keys. Works with the follow formats:

     - RSAPrivateKey (PKCS#1)
     - ECPrivateKey (SECG SEC1 V2)
     - DSAPrivateKey (OpenSSL)
     - PrivateKeyInfo (RSA/DSA/EC - PKCS#8)
     - EncryptedPrivateKeyInfo (RSA/DSA/EC - PKCS#8)
     - Encrypted RSAPrivateKey (PEM only, OpenSSL)
     - Encrypted DSAPrivateKey (PEM only, OpenSSL)
     - Encrypted ECPrivateKey (PEM only, OpenSSL)

    :param data:
        A byte string to load the private key from

    :param password:
        The password to unencrypt the private key

    :raises:
        ValueError - when the data does not appear to contain a private key, or the password is invalid

    :return:
        An asn1crypto.keys.PrivateKeyInfo object
    ra   NH
                password must be a byte string, not %s
                    rb   rd   z
                The data specified does not appear to be a private key, but
                rather a public key
                re   z
                The data specified does not appear to be a private key, but
                rather a certificate
                encryption_algorithmencrypted_datar$   r&   r/   zU
        The data specified does not appear to be a known private key format
        )rU   r    rh   r   r"   ri   rj   rk   rP   r   rm   rO   r   _decrypt_encrypted_datar   rl   r	   r
   )
rn   passwordro   rs   rq   Zparsed_wrapperencryption_algorithm_inforx   Zdecrypted_datar2   r7   r7   r8   parse_private  sv    








r|   c           
      C   s   t | \}}}d}t||}|s.ttd|d}|  } |tdddgkrr|d }d|t	|||fS | }	d	}|	d
krd}	n|	dkrd}	d}|	||fS )a3  
    Removes PEM-encoding from a public key, private key or certificate. If the
    private key is encrypted, the password will be used to decrypt it.

    :param data:
        A byte string of the PEM-encoded data

    :param password:
        A byte string of the encryption password, or None

    :return:
        A 3-element tuple in the format: (key_type, algorithm, der_bytes). The
        key_type will be a unicode string of "public key", "private key" or
        "certificate". The algorithm will be a unicode string of "rsa", "dsa"
        or "ec".
    zc^((DSA|EC|RSA) PRIVATE KEY|ENCRYPTED PRIVATE KEY|PRIVATE KEY|PUBLIC KEY|RSA PUBLIC KEY|CERTIFICATE)zx
            data does not seem to contain a PEM-encoded certificate, private
            key or public key
            r   zRSA PRIVATE KEYzDSA PRIVATE KEYzEC PRIVATE KEY   rc   Nzencrypted private keyzrsa public keyrd   r$   )
r   ri   rj   rP   r   groupstripsetlower_unarmor_pem_openssl_private)
rn   rz   Zobject_typeheadersZ	der_bytesZ
type_regexZ
armor_typeZ
pem_headerrp   ro   r7   r7   r8   rk   v  s(    
rk   c                 C   sD  d}d}d}d| krB| d }| ddkr>| d\}}nd}|sJ|S |r^t|d}| }ddddd	d	dd
dd
dddddddd
d
d| }t||dd
  	 }|t
|kr|t|| |dd
  	 7 }q|d| }dddddddddddddddddddd| }	t|	 }
|	dkr8|
||S |
|||S )a  
    Parses a PKCS#1 private key, or encrypted private key

    :param headers:
        A dict of "Name: Value" lines from right after the PEM header

    :param data:
        A byte string of the DER-encoded PKCS#1 private key

    :param password:
        A byte string of the password to use if the private key is encrypted

    :return:
        A byte string of the DER-encoded private key
    NzDEK-Info,RC4ascii                )zaes-128-cbczaes-128zaes-192-cbczaes-192zaes-256-cbczaes-256r]   zrc4-64zrc4-40z
rc2-64-cbcz
rc2-40-cbczrc2-cbcr\   zdes-ede3-cbczdes-ede3Zdes3zdes-ede-cbczdes-cbcr^   r   r`   r]   r\   r_   r^   )findr   splitbinascii	unhexlifyrV   r   rW   md5rY   lencrypto_funcs)r   rn   rz   Zenc_algoZ
enc_iv_hexenc_ivr5   Zenc_key_lengthenc_keyZenc_algo_namedecrypt_funcr7   r7   r8   r     s    $

r   c                    s  t | tsttdt| |dk	rBt |tsFttdt|nd}i  i }t| }|d }|d jdkrzttd|j	}|d	 }|r|d
 d d j}dddddddd| }	t
|||d j|d j|	d}
tt|}t|
|d j| }|d
 d j}t||std|D ]~}|d }t |trJt|j ||| nPt |tr|d }|d }|d j}t|||}t| ||| nttdqt| }t  }tt||@ }d}d}g }t|dkr|d | }  } fdd  D }|||fS t|dkr@tt| d }|| }t dkrptt  d } | } |= t dkrtt  d!d" d#}|||fS )$aY  
    Parses a PKCS#12 ANS.1 DER-encoded structure and extracts certs and keys

    :param data:
        A byte string of a DER-encoded PKCS#12 file

    :param password:
        A byte string of the password to any encrypted data

    :param load_private_key:
        A callable that will accept a byte string and return an
        oscrypto.asymmetric.PrivateKey object

    :raises:
        ValueError - when any of the parameters are of the wrong type or value
        OSError - when an error is returned by one of the OS decryption functions

    :return:
        A three-element tuple of:
         1. An asn1crypto.keys.PrivateKeyInfo object
         2. An asn1crypto.x509.Certificate object
         3. A list of zero or more asn1crypto.x509.Certificate objects that are
            "extra" certificates, possibly intermediates from the cert chain
    ra   Nru   rv   	auth_safecontent_typern   zV
            Only password-protected PKCS12 files are currently supported
            mac_datamacZdigest_algorithmr0         r   0   @   )sha1sha224rX   sha384sha512Z
sha512_224Z
sha512_256Zmac_saltZ
iterations   contentrY   zPassword provided is invalidencrypted_content_infoZcontent_encryption_algorithmencrypted_contentz[
                Public-key-based PKCS12 files are not currently supported
                r   r   c                    s   g | ]}|kr | qS r7   r7   ).0fcertsrL   r7   r8   
<listcomp>|  s      z!_parse_pkcs12.<locals>.<listcomp>c                 S   s   | j jS )N)subjectZhuman_friendly)cr7   r7   r8   <lambda>  rv   z_parse_pkcs12.<locals>.<lambda>)r[   )rU   r    rh   r   r"   r   rm   rO   rP   authenticated_safer   getattrrW   hmacnewcontentsrY   r   r   _parse_safe_contentsr   ry   r   keyssortedlistr   values)rn   rz   rZ   private_keyspfxr   r   r   Zmac_algo
key_lengthZmac_keyZhash_modZcomputed_hmacZstored_hmacZcontent_infor   r   r{   r   Zdecrypted_contentZkey_fingerprintsZcert_fingerprintsZcommon_fingerprintsr[   certZother_certsZ	first_keyr7   r   r8   _parse_pkcs12  s    


	



r   c                 C   s   t | trt| } | D ]}|d }t |trh|d jdkr|d j}|d d }|d j|t|d< qt |tr||t||< qt |t	r|d }	|d	 j}
t
|	|
|}t|}||t||< qt |trt||||| qqdS )
a&  
    Parses a SafeContents PKCS#12 ANS.1 structure and extracts certs and keys

    :param safe_contents:
        A byte string of ber-encoded SafeContents, or a asn1crypto.pkcs12.SafeContents
        parsed object

    :param certs:
        A dict to store certificates in

    :param keys:
        A dict to store keys in

    :param password:
        A byte string of the password to any encrypted data

    :param load_private_key:
        A callable that will accept a byte string and return an
        oscrypto.asymmetric.PrivateKey object
    	bag_valueZcert_idx509Z
cert_valuerf   rg   Nrw   rx   )rU   r    r   rm   r   rO   r2   rI   r   r   ry   r   )Zsafe_contentsr   r   rz   rZ   Zsafe_bagr   r   Zpublic_key_infor{   Zencrypted_key_bytesZdecrypted_key_bytesr%   r7   r7   r8   r     s(    








r   c                 C   s  t | j }| jdkrV| jdkr*ttdt| j|| j| j| j	}| j
}||||}n| jdkrt| j|| j| j| j	d }|dd }|dd }||||}nb| jdkrt| j|| j| j| j	d	}| jd
kr|||}n&t| j|| j| j| jd}||||}|S )al  
    Decrypts encrypted ASN.1 data

    :param encryption_algorithm_info:
        An instance of asn1crypto.pkcs5.Pkcs5EncryptionAlgorithm

    :param encrypted_content:
        A byte string of the encrypted content

    :param password:
        A byte string of the encrypted content's password

    :return:
        A byte string of the decrypted plaintext
    r   Zrc5zc
                PBES2 encryption scheme utilizing RC5 encryption is not supported
                r   r   r   r   r   r   r]   r}   )r   Zencryption_cipherkdfrP   r   r   Zkdf_hmacZkdf_saltZkdf_iterationsr   Zencryption_ivr   r   Zencryption_block_size)r{   r   rz   r   r   r   	plaintextZderived_outputr7   r7   r8   ry     s^    





ry   )N)N)9
__future__r   r   r   r   rW   r   ri   r   Z_asn1r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Z	symmetricr   r   r   r   r   utilr   _errorsr   _typesr    r!   r"   r#   rK   rM   rR   rI   r   rr   rt   r|   rk   r   r   r   ry   r7   r7   r7   r8   <module>   s<   DHK)-e	I:
u
3[ 4