U
    g                     @   s   d dgZ ddlZddlmZmZmZmZ ddlmZ ddl	m
Z
mZ ddlmZmZmZ ddlmZ dd	lmZ dd
lmZmZ ddd Zdd ZdddZdS )encodedecode    N)
a2b_base64
b2a_base64hexlify	unhexlify)MD5)padunpad)DESDES3AES)PBKDF1)get_random_bytes)tobytestostrc           	         s   |dkrt }d| }|r|d}t||ddt}|t|| |ddt7 }t|tj|}|dtt|  7 }|	t
 |j n|dk	rtd fdd	td
t dD }|d|7 }|d| 7 }|S )a4  Encode a piece of binary data into PEM format.

    Args:
      data (byte string):
        The piece of binary data to encode.
      marker (string):
        The marker for the PEM block (e.g. "PUBLIC KEY").
        Note that there is no official master list for all allowed markers.
        Still, you can refer to the OpenSSL_ source code.
      passphrase (byte string):
        If given, the PEM block will be encrypted. The key is derived from
        the passphrase.
      randfunc (callable):
        Random number generation function; it accepts an integer N and returns
        a byte string of random data, N bytes long. If not given, a new one is
        instantiated.

    Returns:
      The PEM block, as a string.

    .. _OpenSSL: https://github.com/openssl/openssl/blob/master/include/openssl/pem.h
    Nz-----BEGIN %s-----
         z2Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,%s

zEmpty passwordc                    s$   g | ]}t t ||d   qS )0   )r   r   ).0idata 5/tmp/pip-unpacked-wheel-_q8s9isk/Cryptodome/IO/PEM.py
<listcomp>Z   s   zencode.<locals>.<listcomp>r   r    z-----END %s-----)r   r   r   r   newMODE_CBCr   r   upperZencryptr	   
block_size
ValueErrorrangelenjoin)	r   marker
passphraseZrandfuncoutsaltkeyZobjencchunksr   r   r   r   /   s(    
c                 C   sV   dg}|d d }t |D ](}t|d |  |  }|| qd|d | S )N       r   )r#   r   r   digestappendr%   )r   r)   Zkey_lendm_Zndr   r   r   _EVP_BytesToKeya   s    r4   c                 C   sr  t d}|| }|s td|d}t d}|| }|rP|d|krXtd| dd }t|dk r|td	|d 	d
r|std|d d}t|dks|d dkrtd|d d\}}t
t|}d}	|dkrt||d}
t|
tj|}n|dkr8t||d}
t|
tj|}n|dkrht||dd d}
t|
tj|}n|dkrt||dd d}
t|
tj|}nv|dkrt||dd d}
t|
tj|}nF| dkrt||dd d}
tj|
tj|d}d}	ntd | |dd }nd}td|dd! }d}|rh|	rZt|||j}n
||}d}|||fS )"a  Decode a PEM block into binary.

    Args:
      pem_data (string):
        The PEM block.
      passphrase (byte string):
        If given and the PEM block is encrypted,
        the key will be derived from the passphrase.

    Returns:
      A tuple with the binary data, the marker string, and a boolean to
      indicate if decryption was performed.

    Raises:
      ValueError: if decoding fails, if the PEM file is encrypted and no passphrase has
                  been provided or if the passphrase is incorrect.
    z\s*-----BEGIN (.*)-----\s+zNot a valid PEM pre boundaryr   z-----END (.*)-----\s*$zNot a valid PEM post boundary r      z%A PEM file must have at least 3 lineszProc-Type:4,ENCRYPTEDz-PEM is encrypted, but no passphrase available   :r   zDEK-Infoz$PEM encryption format not supported.,TzDES-CBCr   zDES-EDE3-CBC   zAES-128-CBCNr   zAES-192-CBCzAES-256-CBC    zid-aes256-gcm)nonceFz(Unsupport PEM encryption algorithm (%s).r.   )recompilematchr"   groupsearchreplacesplitr$   
startswithr   r   r4   r   r   r   r   r   lowerZMODE_GCMr   r%   r
   Zdecryptr!   )Zpem_datar'   rr2   r&   linesZDEKalgor)   paddingr*   Zobjdecr   Zenc_flagr   r   r   r   j   sf    










)NN)N)__all__r=   binasciir   r   r   r   ZCryptodome.Hashr   ZCryptodome.Util.Paddingr	   r
   ZCryptodome.Cipherr   r   r   ZCryptodome.Protocol.KDFr   ZCryptodome.Randomr   ZCryptodome.Util.py3compatr   r   r   r4   r   r   r   r   r   <module>"   s   
2	