U
    cx                     @   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-c04l8219/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modulusZ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)rT   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    




rq   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
    r`   Nra   rb   z
                The data specified does not appear to be a certificate, but
                rather a private key
                rc   z
                The data specified does not appear to be a certificate, but
                rather a public key
                rd   zU
        The data specified does not appear to be a known certificate format
        )rT   r    rg   r   r"   rh   ri   rj   rP   r   rl   )rm   rn   _r7   r7   r8   parse_certificate  s0    
rs   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
    r`   NH
                password must be a byte string, not %s
                    ra   rc   z
                The data specified does not appear to be a private key, but
                rather a public key
                rd   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
        )rT   r    rg   r   r"   rh   ri   rj   rP   r   rl   rO   r   _decrypt_encrypted_datar   rk   r	   r
   )
rm   passwordrn   rr   rp   Zparsed_wrapperencryption_algorithm_inforw   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   rb   Nzencrypted private keyzrsa public keyrc   r$   )
r   rh   ri   rP   r   groupstripsetlower_unarmor_pem_openssl_private)
rm   ry   Zobject_typeheadersZ	der_bytesZ
type_regexZ
armor_typeZ
pem_headerro   rn   r7   r7   r8   rj   v  s(    
rj   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,Z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	unhexlifyrU   r   rV   md5rX   lencrypto_funcs)r   rm   ry   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
    r`   Nrt   ru   	auth_safecontent_typerm   zV
            Only password-protected PKCS12 files are currently supported
            mac_datamacZdigest_algorithmr0         r   0   @   )sha1sha224rW   sha384sha512Z
sha512_224Z
sha512_256Zmac_saltZ
iterations   contentrX   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>  ru   z_parse_pkcs12.<locals>.<lambda>)rZ   )rT   r    rg   r   r"   r   rl   rO   rP   authenticated_safer   getattrrV   hmacnewcontentsrX   r   r   _parse_safe_contentsr   rx   r   keyssortedlistr   values)rm   ry   rY   private_keyspfxr   r   r   Zmac_algo
key_lengthZmac_keyZhash_modZcomputed_hmacZstored_hmacZcontent_infor   r   rz   r   Zdecrypted_contentZkey_fingerprintsZcert_fingerprintsZcommon_fingerprintsrZ   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_valuere   rf   Nrv   rw   )rT   r    r   rl   r   rO   r2   rI   r   r   rx   r   )Zsafe_contentsr   r   ry   rY   Zsafe_bagr   r   Zpublic_key_inforz   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)rz   r   ry   r   r   r   	plaintextZderived_outputr7   r7   r8   rx     s^    





rx   )N)N)9
__future__r   r   r   r   rV   r   rh   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   rq   rs   r{   rj   r   r   r   rx   r7   r7   r7   r8   <module>   s<   DHK)-e	I:
u
3[ 4