U
    g#                     @   s   d Z ddlmZmZmZmZ ddlZddlmZm	Z	m
Z
 ddlmZmZ ejdkZdZd	Zd
d ZdddZdd ZdddZdd ZdS )z
Functions for parsing and dumping using the ASN.1 DER encoding. Exports the
following items:

 - emit()
 - parse()
 - peek()

Other type classes are defined that help compose the types listed above.
    )unicode_literalsdivisionabsolute_importprint_functionN   )byte_clschr_cls	type_name)int_from_bytesint_to_bytes)   z<Insufficient data - %s bytes requested but only %s available
   c                 C   s   t | tstdt|  | dk s*| dkr6td|  t |tsPtdt| |dk s`|dkrltd| t |tstdt| |dk rtd	| t |tstd
t| t| |||| S )a  
    Constructs a byte string of an ASN.1 DER-encoded value

    This is typically not useful. Instead, use one of the standard classes from
    asn1crypto.core, or construct a new class with specific fields, and call the
    .dump() method.

    :param class_:
        An integer ASN.1 class value: 0 (universal), 1 (application),
        2 (context), 3 (private)

    :param method:
        An integer ASN.1 method value: 0 (primitive), 1 (constructed)

    :param tag:
        An integer ASN.1 tag value

    :param contents:
        A byte string of the encoded byte contents

    :return:
        A byte string of the ASN.1 DER value (header and contents)
    z!class_ must be an integer, not %sr   r   z*class_ must be one of 0, 1, 2 or 3, not %sz!method must be an integer, not %sr   zmethod must be 0 or 1, not %sztag must be an integer, not %sz%tag must be greater than zero, not %s&contents must be a byte string, not %s)
isinstanceint	TypeErrorr	   
ValueErrorr   _dump_header)class_methodtagcontents r   5/tmp/pip-unpacked-wheel-etcy_95o/asn1crypto/parser.pyemit   s    



r   Fc                 C   sP   t | tstdt|  t| }t| |\}}|rL||krLtd||  |S )al  
    Parses a byte string of ASN.1 BER/DER-encoded data.

    This is typically not useful. Instead, use one of the standard classes from
    asn1crypto.core, or construct a new class with specific fields, and call the
    .load() class method.

    :param contents:
        A byte string of BER/DER-encoded data

    :param strict:
        A boolean indicating if trailing data should be forbidden - if so, a
        ValueError will be raised when trailing data exists

    :raises:
        ValueError - when the contents do not contain an ASN.1 header or are truncated in some way
        TypeError - when contents is not a byte string

    :return:
        A 6-element tuple:
         - 0: integer class (0 to 3)
         - 1: integer method
         - 2: integer tag
         - 3: byte string header
         - 4: byte string content
         - 5: byte string trailer
    r   z4Extra data - %d bytes of trailing data were provided)r   r   r   r	   len_parser   )r   strictZcontents_leninfoconsumedr   r   r   parseK   s    
r    c                 C   s0   t | tstdt|  t| t| \}}|S )aW  
    Parses a byte string of ASN.1 BER/DER-encoded data to find the length

    This is typically used to look into an encoded value to see how long the
    next chunk of ASN.1-encoded data is. Primarily it is useful when a
    value is a concatenation of multiple values.

    :param contents:
        A byte string of BER/DER-encoded data

    :raises:
        ValueError - when the contents do not contain an ASN.1 header or are truncated in some way
        TypeError - when contents is not a byte string

    :return:
        An integer with the number of bytes occupied by the ASN.1 value
    r   )r   r   r   r	   r   r   )r   r   r   r   r   r   peekr   s    
r!   c              	   C   s~  |t krtd|}||d k r4ttd|| f trDt| | n| | }|d7 }|d@ }|d? d@ }|dkrd}||d k rttd|| f trt| | n| | }	|d7 }|	dkr|dkrtd|d9 }||	d@ 7 }|	d	? dkrvqqv|dk rtd||d k r&ttd|| f tr8t| | n| | }
|d7 }d
}|
d	? dkrh||
d@  }n|
d@ }|r||| k rtt||| f ||7 }|t| || | dd }n`|std|}||d k s| ||d  dkrt| ||d|d d\}}q|d7 }d}||kr@tt|| || f |rN||fS |d? ||| || | ||t|  |f|fS )a  
    Parses a byte string into component parts

    :param encoded_data:
        A byte string that contains BER-encoded data

    :param data_len:
        The integer length of the encoded data

    :param pointer:
        The index in the byte string to parse from

    :param lengths_only:
        A boolean to cause the call to return a 2-element tuple of the integer
        number of bytes in the header and the integer number of bytes in the
        contents. Internal use only.

    :param depth:
        The recursion depth when evaluating indefinite-length encoding.

    :return:
        A 2-element tuple:
         - 0: A tuple of (class_, method, tag, header, content, trailer)
         - 1: An integer indicating how many bytes were consumed
    z*Indefinite-length recursion limit exceededr         r      zNon-minimal tag encoding          F)signedz-Indefinite-length element must be constructed   s     T)lengths_onlydepth   )
_MAX_DEPTHr   _INSUFFICIENT_DATA_MESSAGE_PY2ordr
   r   r   )Zencoded_dataZdata_lenpointerr*   r+   startZfirst_octetr   ZconstructednumZlength_octettrailerZcontents_endZlength_octets_r   r   r   r      sp    

$

r   c           	      C   s   d}d}|| d> O }||d> O }|dkrld}|dkrZt ||d@ B | }|sPd}|d? }q,t |dB | }n|t ||B 7 }t|}|dkr|t |7 }n$t|}|t dt|B 7 }||7 }|S )	a  
    Constructs the header bytes for an ASN.1 object

    :param class_:
        An integer ASN.1 class value: 0 (universal), 1 (application),
        2 (context), 3 (private)

    :param method:
        An integer ASN.1 method value: 0 (primitive), 1 (constructed)

    :param tag:
        An integer ASN.1 tag value

    :param contents:
        A byte string of the encoded byte contents

    :return:
        A byte string of the ASN.1 DER header
    r'   r   r,   r#   r"   r%   r$   r&   )r   r   r   )	r   r   r   r   headerZid_numZcont_bitlengthZlength_bytesr   r   r   r      s(    
r   )F)r   Fr   )__doc__
__future__r   r   r   r   sys_typesr   r   r	   utilr
   r   version_infor/   r.   r-   r   r    r!   r   r   r   r   r   r   <module>   s   
1
'
j