
    >wgܚ                       d Z ddlmZmZmZmZ ddlmZmZ ddlm	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mZmZmZmZ ddlmZmZ ddlmZm Z m!Z!m"Z"m#Z#m$Z$ ejJ                  dk  rddl&m'Z( e)Z*dZ+nddl,m(Z( dZ+ ejZ                          dddddZ.dddddddddZ/dddZ0 ejb                  d      Z2i Z3ddZ4 G d d e5      Z6 G d! d"      Z7 G d# d$e5      Z8 G d% d&e5      Z9 G d' d(e6      Z: e:       Z; G d) d*e6      Z< G d+ d,e6      Z= G d- d.e5      Z> G d/ d0e6      Z? G d1 d2e9e?      Z@ G d3 d4e?      ZA G d5 d6e?e7      ZB G d7 d8e5      ZC G d9 d:eCe9e8e?e7      ZD G d; d<e9e8e?      ZE G d= d>eCe9e8e?      ZF G d? d@e9e8e?      ZG G dA dBe9e8e?      ZH G dC dDe9e8e?      ZI G dE dFeI      ZJ G dG dHe?      ZK G dI dJe?e7      ZL G dK dLe?      ZM G dM dNe?      ZN G dO dPe?      ZO G dQ dReB      ZP G dS dTe@      ZQ G dU dVeL      ZR G dW dXe6      ZS G dY dZe6      ZT G d[ d\eS      ZU G d] d^eT      ZV G d_ d`eS      ZW G da dbe@      ZX G dc dde@      ZY G de dfe@      ZZ G dg dheG      Z[ G di dje@      Z\ G dk dle@      Z] G dm dne]      Z^ G do dpe]      Z_ G dq dre@      Z` G ds dte@      Za G du dve@      Zb G dw dxe@      Zc G dy dze@      Zd G d{ d|e@      Zed} Zfd~ Zgd Zhd Zid Zji deAdeBdeDdeGdeKdeLdeMdeNdeOdePdeWdeQdeRdeSdeUdeXdeYeZe[e\e^e_e`eaebecedeedZkddZlddZmy)a  
ASN.1 type classes for universal types. Exports the following items:

 - load()
 - Any()
 - Asn1Value()
 - BitString()
 - BMPString()
 - Boolean()
 - CharacterString()
 - Choice()
 - EmbeddedPdv()
 - Enumerated()
 - GeneralizedTime()
 - GeneralString()
 - GraphicString()
 - IA5String()
 - InstanceOf()
 - Integer()
 - IntegerBitString()
 - IntegerOctetString()
 - Null()
 - NumericString()
 - ObjectDescriptor()
 - ObjectIdentifier()
 - OctetBitString()
 - OctetString()
 - PrintableString()
 - Real()
 - RelativeOid()
 - Sequence()
 - SequenceOf()
 - Set()
 - SetOf()
 - TeletexString()
 - UniversalString()
 - UTCTime()
 - UTF8String()
 - VideotexString()
 - VisibleString()
 - VOID
 - Void()

Other type classes are defined that help compose the types listed above.
    )unicode_literalsdivisionabsolute_importprint_function)datetime	timedelta)FractionN   )_teletex_codec)unwrap)OrderedDict)	type_namestr_clsbyte_cls	int_typeschr_cls)_parse_dump_header)int_to_bytesint_from_bytestimezoneextended_datetimecreate_timezoneutc_with_dst)   )StringIOT)BytesIOF	universalapplicationcontextprivate)r   r
      r   r"   r   )r   r   r    r!   r   r
   r"   r   	primitiveconstructed)r   r
   z^\d+(\.\d+)*$c                 0    t         j                  | |      S )a5  
    Loads a BER/DER-encoded byte string and construct a universal object based
    on the tag value:

     - 1: Boolean
     - 2: Integer
     - 3: BitString
     - 4: OctetString
     - 5: Null
     - 6: ObjectIdentifier
     - 7: ObjectDescriptor
     - 8: InstanceOf
     - 9: Real
     - 10: Enumerated
     - 11: EmbeddedPdv
     - 12: UTF8String
     - 13: RelativeOid
     - 16: Sequence,
     - 17: Set
     - 18: NumericString
     - 19: PrintableString
     - 20: TeletexString
     - 21: VideotexString
     - 22: IA5String
     - 23: UTCTime
     - 24: GeneralizedTime
     - 25: GraphicString
     - 26: VisibleString
     - 27: GeneralString
     - 28: UniversalString
     - 29: CharacterString
     - 30: BMPString

    :param encoded_data:
        A byte string of BER or 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 strict is True and trailing data is present
        ValueError - when the encoded value tag a tag other than listed above
        ValueError - when the ASN.1 header length is longer than the data
        TypeError - when encoded_data is not a byte string

    :return:
        An instance of the one of the universal classes
    )strict)	Asn1Valueload)encoded_datar&   s     F/var/www/horilla/myenv/lib/python3.12/site-packages/asn1crypto/core.pyr(   r(   s   s    f >>,v>66    c                       e Zd ZdZdZdZdZdZdZdZ	dZ
dZdZdZedd       Z	 	 ddZd Zd Zd	 Zd
 Zd Zd Zd Zd ZddZd Zd ZddZddZy)r'   z'
    The basis of all ASN.1 values
    NFr+   c                     t        |t              st        dt        |      z        d}| j                  | }t        ||||      \  }}|S )a  
        Loads a BER/DER-encoded byte string using the current class as the spec

        :param encoded_data:
            A byte string of BER or 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

        :return:
            An instance of the current class
        *encoded_data must be a byte string, not %sNspecspec_paramsr&   )
isinstancer   	TypeErrorr   tag_parse_build)clsr)   r&   kwargsr0   value_s          r*   r(   zAsn1Value.load   sS      ,1H9UaKbbcc77D4VTZ[qr+   c           	         	 | j                   t        vrl| j                   }|j                  /t        |j                  d   t              r|j                  f|_        t        |d      r| j                          dt        |<   |!t        |t              r|d}||f}|dk(  rd}d}|!t        |t              r|d}||f}|dk(  rd}d}|6|d}|dk(  r||f}n(|dk(  r||f}nt        t        dt        |                  |t        |      d	k(  rt        |d
   t              r|f}|D ]  \  }}d}t        |t              r|t        vr|}n|t        vr|}t        |   }|t        t        dt        |                  |.t        |t              st        t        dt        |                  | j                  ||ff| _        | j                  ||ffz   | _         n|x|\  }}|t        vrt        t        dt        |                  |.t        |t              st        t        dt        |                  t        |   | _        || _        d| _        nR|4|t        vrt        t        dt        |                  t        |   | _        | j                  d| _        ||| _        |
C|
t%        g d      vrt        t        dt        |
                  |
dk(  rd}
n|
dk(  rd
}
|
| _        |rd| _        |	|	| _        y|| j%                  |       yy# t        t        f$ r=}|j*                  d
d }|j*                  d   dt        |       z  z   f|z   |_        |d}~ww xY w)a  
        The optional parameter is not used, but rather included so we don't
        have to delete it from the parameter dictionary when passing as keyword
        args

        :param explicit:
            An int tag number for explicit tagging, or a 2-element tuple of
            class and tag.

        :param implicit:
            An int tag number for implicit tagging, or a 2-element tuple of
            class and tag.

        :param no_explicit:
            If explicit tagging info should be removed from this instance.
            Used internally to allow contructing the underlying value that
            has been wrapped in an explicit tag.

        :param tag_type:
            None for normal values, or one of "implicit", "explicit" for tagged
            values. Deprecated in favor of explicit and implicit params.

        :param class_:
            The class for the value - defaults to "universal" if tag_type is
            None, otherwise defaults to "context". Valid values include:
             - "universal"
             - "application"
             - "context"
             - "private"
            Deprecated in favor of explicit and implicit params.

        :param tag:
            The integer tag to override - usually this is used with tag_type or
            class_. Deprecated in favor of explicit and implicit params.

        :param optional:
            Dummy parameter that allows "optional" key in spec param dicts

        :param default:
            The default value to use if the value is currently None

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

        :param method:
            The method for the value - no default value since this is
            normally set on a class. Valid values include:
             - "primitive" or 0
             - "constructed" or 1

        :raises:
            ValueError - when implicit, explicit, tag_type, class_ or tag are invalid values
        Nr   _setupTr    explicitimplicitzh
                        tag_type must be one of "implicit", "explicit", not %s
                        r"   r
   z
                            explicit class must be one of "universal", "application",
                            "context", "private", not %s
                            zi
                                explicit tag must be an integer, not %s
                                z
                        implicit class must be one of "universal", "application",
                        "context", "private", not %s
                        za
                            implicit tag must be an integer, not %s
                            z
                            class_ must be one of "universal", "application",
                            "context", "private", not %s
                            )r#   r   r$   r
   z
                        method must be one of "primitive" or "constructed",
                        not %s
                        r#   r$   
    while constructing %s)	__class___SETUP_CLASSESr<   r2   r   hasattrr;   
ValueErrorr   reprlenCLASS_NUM_TO_NAME_MAPCLASS_NAME_TO_NUM_MAPr3   r   class_r4   r=   setmethodcontentsargs)selfr<   r=   no_explicittag_typerG   r4   optionaldefaultrJ   rI   r6   invalid_classerK   s                  r*   __init__zAsn1Value.__init__   s   pT	~~^3nn <<+
3<<?I0V$'LL#3CL3)KKM&*s# #h	2~!* &1Hz)#HC#h	2~!* &1Hz)#HC #>&Fz) &}H+ &}H$V X	&   #x=A%*Xa[)*L (|H#+ JKFC$(M!&)4!)>>,2M!)>>,2M!6v!>$0(  !/*   )#y9"+F!$ !*#	- #  }},*0#(9(,&#8I(I9J< %&!66$V V&   ?%c95'  &cN	)   4F; $%%::(  !L*   #8"?DK;;&"#DK?"DH!%G!HH$V V&   [(F},F$ $# ($! % I& 	66!":DffQi"?)D/"QQSVZZAFG	s   K>L L M"%8MM"c                 N    t         r| j                         S | j                         S z
        Since str is different in Python 2 and 3, this calls the appropriate
        method, __unicode__() or __bytes__()

        :return:
            A unicode string
        _PY2	__bytes____unicode__rL   s    r*   __str__zAsn1Value.__str__  #     >>####%%r+   c           	          t         r5dt        |       dt        |       dt        | j	                               dS dt        |       dt        |       dt        | j	                               dS )7
        :return:
            A unicode string
        < z b>)rW   r   idrC   dumprZ   s    r*   __repr__zAsn1Value.__repr__  sN     $-dORXtDIIK?PQQ  $-T?BtHd499;>OPPr+   c                 @    | j                         j                  d      S )z
        A fall-back method for print() in Python 2

        :return:
            A byte string of the output of repr()
        utf-8)rd   encoderZ   s    r*   rX   zAsn1Value.__bytes__  s     }}%%g..r+   c                 "    | j                         S )z
        A fall-back method for print() in Python 3

        :return:
            A unicode string of the output of repr()
        )rd   rZ   s    r*   rY   zAsn1Value.__unicode__  s     }}r+   c                     | j                         }| j                  |_        | j                  |_        | j                  |_        | j                  |_        |S )z
        Constructs a new copy of the current object, preserving any tagging

        :return:
            An Asn1Value object
        )r?   rG   r4   r=   r<   rL   new_objs     r*   _new_instancezAsn1Value._new_instance  sC     .."hh====r+   c                 f    | j                         }|j                  | t        j                         |S )z
        Implements the copy.copy() interface

        :return:
            A new shallow copy of the current Asn1Value object
        )rl   _copycopyrj   s     r*   __copy__zAsn1Value.__copy__  s)     $$&dDII&r+   c                     | j                         }||t        |       <   |j                  | t        j                         |S )z
        Implements the copy.deepcopy() interface

        :param memo:
            A dict for memoization

        :return:
            A new deep copy of the current Asn1Value object
        )rl   rb   rn   ro   deepcopyrL   memork   s      r*   __deepcopy__zAsn1Value.__deepcopy__  s6     $$& RXdDMM*r+   c                 ,    t        j                  |       S )z}
        Copies the object, preserving any special tagging from it

        :return:
            An Asn1Value object
        ro   rr   rZ   s    r*   ro   zAsn1Value.copy       }}T""r+   c                     t        |t              s||i}| j                  |j                  d      |j                  d            }|j	                  | t
        j                         |S )a}  
        Copies the object, applying a new tagging to it

        :param tagging:
            A dict containing the keys "explicit" and "implicit". Legacy
            API allows a unicode string of "implicit" or "explicit".

        :param tag:
            A integer tag number. Only used when tagging is a unicode string.

        :return:
            An Asn1Value object
        r<   r=   )r<   r=   )r2   dictr?   getrn   ro   rr   )rL   taggingr4   rk   s       r*   retagzAsn1Value.retag  sS      '4(nG..'++j*AGKKXbLc.ddDMM*r+   c                 f    | j                         }|j                  | t        j                         |S )z{
        Copies the object, removing any special tagging from it

        :return:
            An Asn1Value object
        )r?   rn   ro   rr   rj   s     r*   untagzAsn1Value.untag/  s'     .."dDMM*r+   c           	          | j                   |j                   k7  r(t        t        dt        |      t        |                   |j                  | _         ||j
                        | _        y)a!  
        Copies the contents of another Asn1Value object to itself

        :param object:
            Another instance of the same class

        :param copy_func:
            An reference of copy.copy() or copy.deepcopy() to use when copying
            lists, dicts and objects
        Q
                Can not copy values from %s object to %s object
                N)r?   r3   r   r   rJ   _nativerL   other	copy_funcs      r*   rn   zAsn1Value._copy;  s[     >>U__,F % $    /r+   c                    d|z  }t        | d      }t        ||        |r| j                  j                  |dz          yt        | d      r| j                  j                  |dz          yt
        r>t        | j                  t              r$t        |dt        | j                               yt        |d| j                         y)J
        Show the binary data and parsed data in a tree structure
          parsedr"   chosenz    Native: bz    Native: N)rA   _basic_debugr   debugr   rW   r2   nativer   printrC   )rL   
nest_levelprefix
has_parseds       r*   r   zAsn1Value.debugS  s    
 
" T8,
VT"KKj1n-T8$KKj1n-
4;;9VT$++5FGHFDKK@Ar+   c                    | j                   }| j                  | j                  dd dk(  rd}| j                  |rt        | t              r| j                  rd| _        t        | j                  | j
                  | j                  | j                         }| j                  2| j                  D ]#  \  }}t        |d||| j                   z         |z   }% || _        d| _
        | j                  |z   | j                  z   S )  
        Encodes the value using DER

        :param force:
            If the encoded contents already exist, clear them and regenerate
            to ensure they are in DER format instead of BER format

        :return:
            A byte string of the DER-encoded value
        N   Tr   r
   r+   )rJ   _headerr2   Constructable_indefiniterI   r   rG   r4   r<   _trailer)rL   forcerJ   headerrG   r4   s         r*   rc   zAsn1Value.dumpi  s     == <<#RS(9W(DE<<5$.43C3C!$++t{{DHHdmmTF}}(#'== [KFC)&!S&4==:PQTZZF[ "DLDM||h&66r+   F)
NNFNNNNNNNNr
   )__name__
__module____qualname____doc__rI   rG   r4   _bad_tagr=   r<   r   rJ   r   r   classmethodr(   rS   r[   rd   rX   rY   rl   rp   ru   ro   r}   r   rn   r   rc    r+   r*   r'   r'      s    
 F F C H H H G H H G 2 imDHL\&	Q/
 #,
00B,7r+   r'   c                       e Zd ZdZdZdZd Zy)ValueMapzl
    Basic functionality that allows for mapping values from ints or OIDs to
    python unicode strings
    Nc                     | j                   }|j                  |j                  yi |_        |j                  j                         D ]  \  }}||j                  |<    y)2
        Generates _reverse_map from _map
        N)r?   _map_reverse_mapitems)rL   r6   keyr8   s       r*   r;   zValueMap._setup  s[    
 nn88s//;((..* 	*JC&)CU#	*r+   )r   r   r   r   r   r   r;   r   r+   r*   r   r     s     D L
*r+   r   c                       e Zd ZdZd Zy)Castablez
    A mixin to handle converting an object between different classes that
    represent the same encoded value, but with different rules for converting
    to and from native Python values
    c           	         |j                   | j                  j                   k7  rHt        t        dt	        |      t	        |       |j                   | j                  j                                |       }| j
                  |_        | j                  |_        | j                  |_        | j                  |_        | j                  |_	        | j                  |_
        t        | t              r"| j                  |_        | j                  |_        |S )a+  
        Converts the current object into an object of a different class. The
        new class must use the ASN.1 encoding for the value.

        :param other_class:
            The class to instantiate the new object from

        :return:
            An instance of the type other_class
        z
                Can not covert a value from %s object to %s object since they
                use different tags: %d versus %d
                )r4   r?   r3   r   r   rG   r=   r<   r   rJ   r   r2   r   rI   r   )rL   other_classrk   s      r*   castzCastable.cast  s     ??dnn000F +&$""	 	 	 -====,,====dM*![[GN"&"2"2Gr+   N)r   r   r   r   r   r   r+   r*   r   r     s    "r+   r   c                   8     e Zd ZdZdZd Zd Zd Z fdZ xZ	S )r   z
    A mixin to handle string types that may be constructed from chunks
    contained within an indefinite length BER-encoded container
    Fc                 @   | j                   s| j                         S d}t        | j                        }d}||k  rQt	        | j                  || j
                        \  }}||j                         }n||j                         z  }||k  rQ|| j                         S |S )zc
        :return:
            A concatenation of the native values of the contained chunks
        r   N)r0   )r   	_as_chunkrD   rJ   r5   r?   _merge_chunks)rL   pointercontents_lenoutput	sub_values        r*   r   zConstructable._merge_chunks  s     >>##4==)$!-dmmW4>>!ZIw~"002)1133 $ >>>##r+   c                     | j                   S )a  
        A method to return a chunk of data that can be combined for
        constructed method values

        :return:
            A native Python value that can be added together. Examples include
            byte strings, unicode strings or tuples.
        rJ   rZ   s    r*   r   zConstructable._as_chunk  s     }}r+   c                     | j                   S )a  
        Returns a native value that can be round-tripped into .set(), to
        result in a DER encoding. This differs from .native in that .native
        is designed for the end use, and may account for the fact that the
        merged value is further parsed as ASN.1, such as in the case of
        ParsableOctetString() and ParsableOctetBitString().

        :return:
            A python value that is valid to pass to .set()
        )r   rZ   s    r*   _setable_nativezConstructable._setable_native  s     {{r+   c                     t         t        |   ||       |j                  r | j	                  |j                                yy)a%  
        Copies the contents of another Constructable object to itself

        :param object:
            Another instance of the same class

        :param copy_func:
            An reference of copy.copy() or copy.deepcopy() to use when copying
            lists, dicts and objects
        N)superr   rn   r   rH   r   rL   r   r   r?   s      r*   rn   zConstructable._copy  s;     	mT(	: HHU**,- r+   )
r   r   r   r   r   r   r   r   rn   __classcell__r?   s   @r*   r   r     s(     K4
. .r+   r   c                   D    e Zd ZdZdZd Zd Zd Zd Ze	d        Z
d
dZy	)Voidz
    A representation of an optional value that is not present. Has .native
    property and .dump() method to be compatible with other value classes.
    r+   c                 4    |j                   | j                   k(  S )u
        :param other:
            The other Primitive to compare to

        :return:
            A boolean
        r   rL   r   s     r*   __eq__zVoid.__eq__+  s     $..00r+   c                      y)NFr   rZ   s    r*   __nonzero__zVoid.__nonzero__6  s    r+   c                      yNr   r   rZ   s    r*   __len__zVoid.__len__9  s    r+   c                     t        d      S )Nr   )iterrZ   s    r*   __iter__zVoid.__iter__<  s    Bxr+   c                      yzl
        The native Python datatype representation of this value

        :return:
            None
        Nr   rZ   s    r*   r   zVoid.native?       r+   c                      y)r   r+   r   rL   r   s     r*   rc   z	Void.dumpJ  s     r+   Nr   )r   r   r   r   rJ   r   r   r   r   propertyr   rc   r   r+   r*   r   r   #  s;    
 H	1  r+   r   c                   ^     e Zd ZdZdZd	dZed        Zed        Zd
dZ	 fdZ
ddZ xZS )Anyz
    A value class that can contain any value, and allows for easy parsing of
    the underlying encoded value using a spec. This is normally contained in
    a Structure that has an ObjectIdentifier field and _oid_pair and _oid_specs
    defined.
    Nc                    t        j                  | fi | 	 |Xt        |t               st        t	        dt        |                  ||j                  df| _        |j                         | _	        yy# t        t        f$ r=}|j                  dd }|j                  d   dt        |       z  z   f|z   |_        |d}~ww xY w)z
        Sets the value of the object before passing to Asn1Value.__init__()

        :param value:
            An Asn1Value object that will be set as the parsed value
        Nz`
                        value must be an instance of Asn1Value, not %s
                        r
   r   r>   )r'   rS   r2   r3   r   r   r?   _parsedrc   rJ   rB   rK   )rL   r8   r7   rR   rK   s        r*   rS   zAny.__init__g  s     	4*6*	 !%3#F "%(	%   !&u= %

 ! I& 	66!":DffQi"?)D/"QQSVZZAFG	s   AA3 3B?8B::B?c                 l    | j                   | j                          | j                   d   j                  S )z
        The native Python datatype representation of this value

        :return:
            The .native value from the parsed value object
        r   )r   parser   rZ   s    r*   r   z
Any.native  s+     <<JJL||A%%%r+   c                 X    | j                   | j                          | j                   d   S zw
        Returns the parsed object from .parse()

        :return:
            The object returned by .parse()
        r   r   r   rZ   s    r*   r   z
Any.parsed  %     <<JJL||Ar+   c                 b   | j                   | j                   dd ||fk7  r	 |xs i }t        |       | j                  )d|v r| j                  |d   z   |d<   n| j                  |d<   | j                  | j                  z   | j
                  z   }t        |||      \  }}|||f| _         d| _        d| _        d| _        d| _        || _        d| _        | j                   d   S # t        t        f$ r=}|j                  dd }|j                  d   d	t        |       z  z   f|z   |_        |d}~ww xY w)
v  
        Parses the contents generically, or using a spec with optional params

        :param spec:
            A class derived from Asn1Value that defines what class_ and tag the
            value should have, and the semantics of the encoded value. The
            return value will be of this type. If omitted, the encoded value
            will be decoded using the standard universal tag based on the
            encoded tag number.

        :param spec_params:
            A dict of params to pass to the spec object

        :return:
            An object of the type spec, or if not present, a child of Asn1Value
        Nr
   r   r<   r0   r1   Fr+   r   
    while parsing %s)r   _tag_type_to_explicit_implicitr<   r   rJ   r   r5   r4   r=   rB   r3   rK   r   )	rL   r0   r1   passed_paramsrJ   parsed_valuer9   rR   rK   s	            r*   r   z	Any.parse  sE   $ <<4<<!#4{8K#K + 1r.}===,!]248MMMR\D]4]j148MMj1<<$--7$--G". -#a
 !-dK@   $ %" ( # ||A	 	* vvabz&&)&>4&PPRUYYs   B1C" "D.18D))D.c                 \    t         t        |   ||        ||j                        | _        y)a  
        Copies the contents of another Any object to itself

        :param object:
            Another instance of the same class

        :param copy_func:
            An reference of copy.copy() or copy.deepcopy() to use when copying
            lists, dicts and objects
        N)r   r   rn   r   r   s      r*   rn   z	Any._copy  s&     	c4ui0 /r+   c                 x    | j                   | j                          | j                   d   j                  |      S )r   r   r   )r   r   rc   r   s     r*   rc   zAny.dump  s3     <<JJL||A##%#00r+   r   NNr   )r   r   r   r   r   rS   r   r   r   r   rn   rc   r   r   s   @r*   r   r   \  sL     G8 & &  0d01r+   r   c                        e Zd ZdZdZdZdZdZdZdZ	dZ
edd       Zd ZddZed        Zej"                  d        Zed        Zd	 Zed
        Zed        Zd Zd Z fdZddZ xZS )ChoicezF
    A class to handle when a value may be one of several options
    Nc                 x    t        |t              st        dt        |      z        t	        || ||      \  }}|S )a  
        Loads a BER/DER-encoded byte string using the current class as the spec

        :param encoded_data:
            A byte string of BER or 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

        :return:
            A instance of the current class
        r.   r/   )r2   r   r3   r   r5   )r6   r)   r&   r7   r8   r9   s         r*   r(   zChoice.load  s?      ,1H9UaKbbcc3FSYZqr+   c                    | j                   }i |_        i |_        t        |j                        D ][  \  }}t        |      dk  r|i fz   }||j                  |<   t        |d   |d         }||j                  |<   ||j                  |d   <   ] y)zS
        Generates _id_map from _alternatives to allow validating contents
        r   r"   r
   r   N)r?   _id_map	_name_map	enumerate_alternativesrD   _build_id_tuple)rL   r6   indexinfoid_s        r*   r;   zChoice._setup+  s    
 nn$S%6%67 	+KE44y1}re|+/!!%(!$q'473C$CKK%*CMM$q'"	+r+   c           	         t        |       t        j                  | fi | 	 |j                  d      t	        t        d            |=t        |t              rUt        |      dk7  r(t	        t        dt        |       t        |                  t        |j                               d   \  }}t        |t              r@t        |      dk7  r(t	        t        dt        |       t        |                  |d   }|d   }|| j                  vrt	        t        d	|t        |                   | j                  |   | _        | j                  | j                     \  }}}t        ||      s
 ||fi |}nt!        ||      }|| _        yy# t        t$        f$ r=}|j&                  dd }|j&                  d   d
t        |       z  z   f|z   |_        |d}~ww xY w)aq  
        Checks to ensure implicit tagging is not being used since it is
        incompatible with Choice, then forwards on to Asn1Value.__init__()

        :param name:
            The name of the alternative to be set - used with value.
            Alternatively this may be a dict with a single key being the name
            and the value being the value, or a two-element tuple of the name
            and the value.

        :param value:
            The alternative value to set - used with name

        :raises:
            ValueError - when implicit param is passed (or legacy tag_type param is "implicit")
        r=   Nz
                    The Choice type can not be implicitly tagged even if in an
                    implicit module - due to its nature any tagging must be
                    explicit
                    r
   z
                            When passing a dict as the "name" argument to %s,
                            it must have a single key/value - however %d were
                            present
                            r   r"   z
                            When passing a tuple as the "name" argument to %s,
                            it must have two elements, the name and value -
                            however %d were present
                            z
                        The name specified, "%s", is not a valid alternative
                        for %s
                        r>   )r   r'   rS   r{   rB   r   r2   rz   rD   r   listr   tupler   _choicer   _fix_taggingr   r3   rK   )	rL   namer8   r7   r9   r0   paramsrR   rK   s	            r*   rS   zChoice.__init__;  s   $ 	'v.4*6*<	zz*%1 "   dD)4yA~( 
 &dOI*   #'tzz|"4Q"7KD%dE*4yA~( 
 &dOI*   !GE7Dt~~-$V !$&    $~~d3"&"4"4T\\"B4!%. 1&1E(7E$[  ^ I& 	66!":DffQi"?)D/"QQSVZZAFG	s   E$F	 	G8GGc                 ^    | j                   | j                   j                  S | j                  S )zj
        :return:
            A byte string of the DER-encoded contents of the chosen alternative
        )r   rJ   	_contentsrZ   s    r*   rJ   zChoice.contents  s(     <<#<<(((~~r+   c                     || _         y)zo
        :param value:
            A byte string of the DER-encoded contents of the chosen alternative
        Nr  rL   r8   s     r*   rJ   zChoice.contents       r+   c                 t    | j                   s!| j                  | j                     d   | _         | j                   S )zc
        :return:
            A unicode string of the field name of the chosen alternative
        r   )_namer   r   rZ   s    r*   r   zChoice.name  s0     zz++DLL9!<DJzzr+   c                 d   | j                   J	 | j                  | j                     \  }}}t        | j                  ||      \  | _         }| j                   S | j                   S # t
        t        f$ r=}|j                  dd }|j                  d   dt        |       z  z   f|z   |_        |d}~ww xY w)z}
        Parses the detected alternative

        :return:
            An Asn1Value object of the chosen alternative
        Nr   r
   r   r   )	r   r   r   r5   r  rB   r3   rK   r   )rL   r9   r0   r   rR   rK   s         r*   r   zChoice.parse  s     <<"&"4"4T\\"B4".t~~DV\"]a
 ||t||	 	* vvabz&&)&>4&PPRUYYs   =A# #B/28B**B/c                 "    | j                         S )zT
        :return:
            An Asn1Value object of the chosen alternative
        )r   rZ   s    r*   r   zChoice.chosen  s     zz|r+   c                 .    | j                   j                  S )z
        The native Python datatype representation of this value

        :return:
            The .native value from the contained value object
        )r   r   rZ   s    r*   r   zChoice.native  s     {{!!!r+   c           
         ||f}| j                   S| j                   d   |k7  rt        t        dt        |                   t	        |t        |            \  \  }}}}}}}||f}|| j                  v r| j                  |   | _        y| j                  e| j                  Yt        | j                        dkD  rt        t        dt        |                   || j                  | j                  fk(  rd| _        y| j                  ||      }| j                  D cg c]  }| j                  |d   |d          }}t        t        d|t        |       dj                  |                  c c}w )	a  
        Ensures that the class and tag specified exist as an alternative

        :param class_:
            The integer class_ from the encoded value header

        :param tag:
            The integer tag from the encoded value header

        :param contents:
            A byte string of the contents of the value - used when the object
            is explicitly tagged

        :raises:
            ValueError - when value is not a valid alternative
        Nr   z
                    %s was explicitly tagged, but the value provided does not
                    match the class and tag
                    r
   z|
                    %s was implicitly tagged, but more than one alternative
                    exists
                    r   zs
            Value %s did not match the class and tag of any of the alternatives
            in %s: %s
            , )r<   rB   r   r   r   rD   r   r   rG   r4   r   _format_class_tagjoin)	rL   rG   r4   rJ   r   r9   asn1pairasn1ss	            r*   validatezChoice.validate  sv   $ sm==$}}R C'  dO"   .4Hc(m-L*&faaA3-C$,,<<,DL ;;"txx';4%%&*  dO"   t{{DHH-- %%fc2FJllSd''Qa9SS dOIIe
  	 Ts   E(c                 >    dt         |   j                         d|dS )zo
        :return:
            A unicode string of a human-friendly representation of the class and tag
        [r`   ])rE   upper)rL   rG   r4   s      r*   r  zChoice._format_class_tag  s     2&9??A3GGr+   c                     t         t        |   ||       |j                  | _        |j                  | _         ||j
                        | _        y)a  
        Copies the contents of another Choice object to itself

        :param object:
            Another instance of the same class

        :param copy_func:
            An reference of copy.copy() or copy.deepcopy() to use when copying
            lists, dicts and objects
        N)r   r   rn   r   r  r   r   s      r*   rn   zChoice._copy  s<     	fd!%3}}[[
 /r+   c                    | j                   | j                   dd dk(  rd}| j                  j                  |      | _        | j                   |r^d| _         | j                  K| j                  D ]<  \  }}t        |d|| j                   | j                  z         | j                   z   | _         > | j                   | j                  z   S )r   Nr   r   Tr   r+   r
   )r   r   rc   r  r<   r   )rL   r   rG   r4   s       r*   rc   zChoice.dump-  s     <<#RS(9W(DE)))6<<5DL}}(#'== nKFC#/3t~~@]#^aeamam#mDLn||dnn,,r+   r   r   )r   r   r   r   r   r  r   r  r   r   r   r   r(   r;   rS   r   rJ   setterr   r   r   r   r  r  rn   rc   r   r   s   @r*   r   r     s    
 G E G I M G I *+ Rh 	 	 __   $   " ">@H0"-r+   r   c                       e Zd ZdZdZdZedd       ZddZd Z	d Z
d Zd Zd	 Zd
 Zd Zd ZddZddZed        Zd Zd Zd Zd Zy)Concata  
    A class that contains two or more encoded child values concatentated
    together. THIS IS NOT PART OF THE ASN.1 SPECIFICATION! This exists to handle
    the x509.TrustedCertificate() class for OpenSSL certificates containing
    extra information.
    Nc                      | ||      S )a  
        Loads a BER/DER-encoded byte string using the current class as the spec

        :param encoded_data:
            A byte string of BER or 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

        :return:
            A Concat object
        )rJ   r&   r   )r6   r)   r&   s      r*   r(   zConcat.loadS  s      L88r+   c                 <   |y	 t        |      }g | _        d}| j                  D ];  }||k  rt        |||      \  }}n |       }| j                  j	                  |       = |r||k7  r||z
  }t        d|z        |P| j                  dgt        | j                        z  | _        t        |      D ]  \  }}| j                  ||        yy# t
        t        f$ r=}	|	j                  dd }
|	j                  d   dt        |       z  z   f|
z   |	_        |	d}	~	ww xY w)a  
        :param value:
            A native Python datatype to initialize the object value with

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

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

        :raises:
            ValueError - when an error occurs with one of the children
            TypeError - when an error occurs with one of the children
        Nr   )r   r0   4Extra data - %d bytes of trailing data were providedr
   r>   )rD   	_children_child_specsr5   appendrB   r3   rK   r   r   __setitem__)rL   r8   rJ   r&   r   offsetr0   child_valueextra_bytesrR   rK   r   datas                r*   rS   zConcat.__init__e  sA   " "8}!# -- 7D,.:8VZ^._+V&*fNN))+67 f4"."7K$%[^i%ijj ~~%"&#d.?.?*@!@(/ .t  -.  	* vvabz&&)&CiPTo&UUWZ^^s   A8C D8DDc                 N    t         r| j                         S | j                         S rU   rV   rZ   s    r*   r[   zConcat.__str__  r\   r+   c                 "    | j                         S )z;
        A byte string of the DER-encoded contents
        rc   rZ   s    r*   rX   zConcat.__bytes__  s    
 yy{r+   c                     t        |       S r^   )rC   rZ   s    r*   rY   zConcat.__unicode__  s     Dzr+   c           	      l    dt        |       dt        |       dt        | j                               dS )r^   r_   r`   ra   )r   rb   rC   rc   rZ   s    r*   rd   zConcat.__repr__  s$      )4$tyy{:KLLr+   c                 f    | j                         }|j                  | t        j                         |S )z|
        Implements the copy.copy() interface

        :return:
            A new shallow copy of the Concat object
        )r?   rn   ro   rj   s     r*   rp   zConcat.__copy__  s'     .."dDII&r+   c                     | j                         }||t        |       <   |j                  | t        j                         |S )z
        Implements the copy.deepcopy() interface

        :param memo:
            A dict for memoization

        :return:
            A new deep copy of the Concat object and all child objects
        )r?   rb   rn   ro   rr   rs   s      r*   ru   zConcat.__deepcopy__  s4     .." RXdDMM*r+   c                 ,    t        j                  |       S )zQ
        Copies the object

        :return:
            A Concat object
        rw   rZ   s    r*   ro   zConcat.copy  rx   r+   c           	          | j                   |j                   k7  r(t        t        dt        |      t        |                    ||j                        | _        y)a  
        Copies the contents of another Concat object to itself

        :param object:
            Another instance of the same class

        :param copy_func:
            An reference of copy.copy() or copy.deepcopy() to use when copying
            lists, dicts and objects
        r   N)r?   r3   r   r   r  r   s      r*   rn   zConcat._copy  sP     >>U__,F % $   #5??3r+   c                     d|z  }t        |t        |       dt        |              t        |d       | j                  D ]  }|j	                  |dz           y)r   r   	 Object #z  Children:r"   N)r   r   rb   r  r   rL   r   r   childs       r*   r   zConcat.debug  sS    
 
"69T?BtHEF)*^^ 	(EKK
Q'	(r+   c                 V    d}| j                   D ]  }||j                  |      z  } |S )r   r+   r   )r  rc   rL   r   rJ   r4  s       r*   rc   zConcat.dump  s6     ^^ 	0E


//H	0r+   c                 "    | j                         S )z`
        :return:
            A byte string of the DER-encoded contents of the children
        r)  rZ   s    r*   rJ   zConcat.contents  s     yy{r+   c                 ,    t        | j                        S z.
        :return:
            Integer
        )rD   r  rZ   s    r*   r   zConcat.__len__  s     4>>""r+   c           	          |t        | j                        dz
  kD  s|dk  rt        t        d|t	        |                   | j
                  |   S )z
        Allows accessing children by index

        :param key:
            An integer of the child index

        :raises:
            KeyError - when an index is invalid

        :return:
            The Asn1Value object of the child specified
        r
   r   zN
                No child is definition for position %d of %s
                )rD   r   KeyErrorr   r   r  rL   r   s     r*   __getitem__zConcat.__getitem__!  sX     T&&'!++sQw6 $   ~~c""r+   c           	          |t        | j                        dz
  kD  s|dk  rt        t        d|t	        |                   t        |t              st        t        d|t	        |                   || j                  |<   y)aG  
        Allows settings children by index

        :param key:
            An integer of the child index

        :param value:
            An Asn1Value object to set the child to

        :raises:
            KeyError - when an index is invalid
            ValueError - when the value is not an instance of Asn1Value
        r
   r   zK
                No child is defined for position %d of %s
                zz
                Value for child %s of %s is not an instance of
                asn1crypto.core.Asn1Value
                N)	rD   r   r;  r   r   r2   r'   rB   r  )rL   r   r8   s      r*   r"  zConcat.__setitem__:  s     T&&'!++sQw6 $   %+V $   $sr+   c                 ,    t        | j                        S )zB
        :return:
            An iterator of child values
        )r   r  rZ   s    r*   r   zConcat.__iter__^  s     DNN##r+   r   )NNFr   )r   r   r   r   r   r  r   r(   rS   r[   rX   rY   rd   rp   ru   ro   rn   r   rc   r   rJ   r   r=  r"  r   r   r+   r*   r  r  F  s     LI9 9"+.Z&M
 #4.	("  ##2"$H$r+   r  c                   :    e Zd ZdZdZdZd	dZd Zd
dZd Z	d Z
y)	PrimitivezO
    Sets the class_ and method attributes for primitive, universal values
    r   Nc                 4   t        j                  | fi | 	 ||| _        y|| j                  |       y|| j                  |       yy# t        t
        f$ r=}|j                  dd }|j                  d   dt        |       z  z   f|z   |_        |d}~ww xY w)a^  
        Sets the value of the object before passing to Asn1Value.__init__()

        :param value:
            A native Python datatype to initialize the object value with

        :param default:
            The default value if no value is specified

        :param contents:
            A byte string of the encoded contents of the value
        Nr
   r   r>   )r'   rS   rJ   rH   rB   r3   rK   r   )rL   r8   rP   rJ   r7   rR   rK   s          r*   rS   zPrimitive.__init__p  s     	4*6*	# ("$! % I& 	66!":DffQi"?)D/"QQSVZZAFG	s!   	A A A B8BBc           	          t        |t              s(t        t        dt	        |       t	        |                  || _        || _        d| _        | j                  dk7  rd| _        yy)_
        Sets the value of the object

        :param value:
            A byte string
        H
                %s value must be a byte string, not %s
                Nr+   )	r2   r   r3   r   r   r   rJ   r   r   r  s     r*   rH   zPrimitive.set  sg     %*F $%    ==CDM  r+   c                     | j                   | j                   dd dk(  rd}|r$| j                  }d| _        | j                  |       t        j                  |       S )r   Nr   r   T)r   r   rJ   rH   r'   rc   rL   r   r   s      r*   rc   zPrimitive.dump  sS     <<#RS(9W(DE[[F DMHHV~~d##r+   c                     | |k(   S r   r   r   s     r*   __ne__zPrimitive.__ne__  s    5=  r+   c                    t        |t              sy| j                  |j                  k7  ry| j                  j                  |j                  j                  k7  ry| j                  |j                  k(  r| j                  |j                  k(  ryt        | j                  j                        t        | j                  g      z  t        t        t        t        g      z
  }t        |j                  j                        t        |j                  g      z  t        t        t        t        g      z
  }||z  r| j                  |j                  k(  S | j                  s$| j                  s|j                  s|j                  r=| j                         j                         |j                         j                         k(  S | j                         |j                         k(  S )r   FT)r2   rA  rJ   r?   r4   rH   	__bases__r'   r   r=   r<   r   rc   )rL   r   
self_basesother_basess       r*   r   zPrimitive.__eq__  sR    %+==ENN* >>!4!44>>U__,%..1P $..223c4>>:J6KKsT]_hjrSsOtt
5??445U__<M8NNRUW`bkmuVvRww#==ENN22 ==DMMU^^u~~::<$$&%++-*<*<*>>>yy{ejjl**r+   NNNr   )r   r   r   r   rG   rI   rS   rH   rc   rI  r   r   r+   r*   rA  rA  g  s,     FF> .$.!#+r+   rA  c                   F     e Zd ZdZdZdZd Zd Z fdZe	d        Z
 xZS )AbstractStringz
    A base class for all strings that have a known encoding. In general, we do
    not worry ourselves with confirming that the decoded values match a specific
    set of characters, only that they are decoded into a Python unicode string
    latin1Nc           	      2   t        |t              s(t        t        dt	        |       t	        |                  || _        |j                  | j                        | _        d| _	        | j                  rd| _
        d| _        | j                  dk7  rd| _        yy)zb
        Sets the value of the string

        :param value:
            A unicode string
        K
                %s value must be a unicode string, not %s
                NFr   r+   )r2   r   r3   r   r   _unicoderg   	_encodingrJ   r   r   rI   r   r  s     r*   rH   zAbstractString.set  s     %)F $%    T^^4$DDK==CDM  r+   c                     | j                   y| j                  .| j                         j                  | j                        | _        | j                  S )r^    )rJ   rT  r   decoderU  rZ   s    r*   rY   zAbstractString.__unicode__  sD     == ==  ..077GDM}}r+   c                 P    t         t        |   ||       |j                  | _        y)a&  
        Copies the contents of another AbstractString object to itself

        :param object:
            Another instance of the same class

        :param copy_func:
            An reference of copy.copy() or copy.deepcopy() to use when copying
            lists, dicts and objects
        N)r   rP  rn   rT  r   s      r*   rn   zAbstractString._copy  s!     	nd)%;r+   c                 <    | j                   y| j                         S z
        The native Python datatype representation of this value

        :return:
            A unicode string or None
        N)rJ   rY   rZ   s    r*   r   zAbstractString.native(  s      == !!r+   )r   r   r   r   rU  rT  rH   rY   rn   r   r   r   r   s   @r*   rP  rP    s9     I H 4
' " "r+   rP  c                   6    e Zd ZdZdZd Zd Zd Zed        Z	y)Booleanz7
    Represents a boolean in both ASN.1 and Python
    r
   c                 v    t        |      | _        |sdnd| _        d| _        | j                  dk7  rd| _        yy)z
        Sets the value of the object

        :param value:
            True, False or another value that works with bool()
               Nr+   )boolr   rJ   r   r   r  s     r*   rH   zBoolean.set>  s9     E{','==CDM  r+   c                 "    | j                         S )4
        :return:
            True or False
        )__bool__rZ   s    r*   r   zBoolean.__nonzero__M  s    
 }}r+   c                      | j                   dk7  S )rc  r_  r   rZ   s    r*   rd  zBoolean.__bool__T  s    
 }}''r+   c                 v    | j                   y| j                  | j                         | _        | j                  S )z{
        The native Python datatype representation of this value

        :return:
            True, False or None
        N)rJ   r   rd  rZ   s    r*   r   zBoolean.native[  s2     == <<==?DL||r+   N)
r   r   r   r   r4   rH   r   rd  r   r   r   r+   r*   r]  r]  7  s1     C (  r+   r]  c                   0    e Zd ZdZdZd Zd Zed        Zy)Integerz8
    Represents an integer in both ASN.1 and Python
    r"   c           	      "   t        |t              rg| j                  t        t	        dt        |                   || j                  vrt        t	        dt        |       |            | j                  |   }n8t        |t              s(t        t	        dt        |       t        |                  | j                  r|| j                  v r| j                  |   n|| _	        t        |d      | _        d| _        | j                  dk7  rd| _        yy)z
        Sets the value of the object

        :param value:
            An integer, or a unicode string if _map is set

        :raises:
            ValueError - when an invalid value is passed
        Nz\
                    %s value is a unicode string, but no _map provided
                    zR
                    %s value, %s, is not present in the _map
                    z
                %s value must be an integer or unicode string when a name_map
                is provided, not %s
                Tsignedr+   )r2   r   r   rB   r   r   r   r   r3   r   r   rJ   r   r   r  s     r*   rH   zInteger.sets  s    eW%yy   dO	"   D---  dO"   %%e,EE9-F $%    ,099$))9Ktyy'QV$U48==CDM  r+   c                 0    t        | j                  d      S )1
        :return:
            An integer
        Trj  )r   rJ   rZ   s    r*   __int__zInteger.__int__  s    
 dmmD99r+   c                     | j                   y| j                  W| j                         | _        | j                  6| j                  | j                  v r| j                  | j                     | _        | j                  S zz
        The native Python datatype representation of this value

        :return:
            An integer or None
        N)rJ   r   rn  r   rZ   s    r*   r   zInteger.native  s_     == <<<<>DLyy$)B#yy6||r+   N)	r   r   r   r   r4   rH   rn  r   r   r   r+   r*   rh  rh  l  s-     C. `:  r+   rh  c                   B     e Zd ZdZdZd Zd Z fdZed        Z	 xZ
S )_IntegerBitStringzY
    A mixin for IntegerBitString and BitString to parse the contents as an integer.
    r   c                    | j                   rg S t        rt        | j                  d         n| j                  d   }t	        | j                  dd       }t        | j                        dz
  dz  }|s||dfgS t        | j                        dk(  rt        dj                  |            |dkD  rt        dj                  |            t        |d|z  dz
  z  |      }||z  }||z  }|||fgS )	a  
        Parse the contents of a primitive BitString encoding as an integer value.
        Allows reconstructing indefinite length values.

        :raises:
            ValueError - when an invalid value is passed

        :return:
            A list with one tuple (value, bits, unused_bits) where value is an integer
            with the value of the BitString, bits is the bit count of value and
            unused_bits is a tuple of 1s and 0s.
        r   r
   N   r   $Empty bit string has {0} unused bits   Bit string has {0} unused bits)	r   rW   ordrJ   r   rD   rB   format_int_to_bit_tuple)rL   unused_bits_lenr8   bitsunused_bitss        r*   r   z_IntegerBitString._as_chunk  s     I37#dmmA./T]]1=Mt}}QR01DMM"Q&!+D"%&&t}}"CJJ?[\\Q=DD_UVV'!2F!1K(Lo^/!k*++r+   c                     | j                   s| j                         d   S d}d}d}| j                         D ]#  \  }}}|dz  rt        d      ||z  }||z  |z  }% |||fS )aa  
        Combines the chunks into a single value.

        :raises:
            ValueError - when an invalid value is passed

        :return:
            A tuple (value, bits, unused_bits) where value is an integer with the
            value of the BitString, bits is the bit count of value and unused_bits
            is a tuple of 1s and 0s.
        r   r   rv  4Only last chunk in a bit string may have unused bits)r   r   r   rB   )rL   r8   
total_bitsr}  chunkr|  s         r*   _chunks_to_intz _IntegerBitString._chunks_to_int  s     >>#A&&
 )-(:(:(< 	,$E4A~ !WXX$Jd]e+E	, j+--r+   c                 P    t         t        |   ||       |j                  | _        y)a)  
        Copies the contents of another _IntegerBitString object to itself

        :param object:
            Another instance of the same class

        :param copy_func:
            An reference of copy.copy() or copy.deepcopy() to use when copying
            lists, dicts and objects
        N)r   rr  rn   _unused_bitsr   s      r*   rn   z_IntegerBitString._copy  s%     	,UI>!..r+   c                 2    | j                    | j                  S zp
        The unused bits of the bit string encoding.

        :return:
            A tuple of 1s and 0s
        r   r  rZ   s    r*   r}  z_IntegerBitString.unused_bits       	   r+   )r   r   r   r   r  r   r  rn   r   r}  r   r   s   @r*   rr  rr    s3    
 L%,N.>/ ! !r+   rr  c                   @    e Zd ZdZdZdZd Zd Zd Zd Z	e
d        Zy)		BitStringzK
    Represents a bit string from ASN.1 as a Python tuple of 1s and 0s
    r   Nc                     t         j                  |        | j                  }|j                  ,t	        | j                  j                               dz   |_        yy)r   Nr
   )r   r;   r?   r   maxkeys_size)rL   r6   s     r*   r;   zBitString._setup2  sD    
 	nn88DIINN,-1CI  r+   c           
         t        |t              r| j                  t        t	        dt        |                   dg| j                  z  }|| _        t        d| j                        D ]*  }| j                  j                  |      }|!||v s&d||<   , dj                  t        t        |            }n|j                  t        k(  r| j                  || _        n\t               | _        t        |      D ]?  \  }}|s	| j                  j                  ||      }| j                  j!                  |       A dj                  t        t        |            }n(t#        t	        dt        |       t        |                  | j                  \t%        |      | j                  kD  r3t        t	        dt        |       | j                  t%        |                  |j'                  d      }t%        |      }|d	z  }d}	|dk7  rd	|z
  }	|d|	z  z  }t)        t+        j,                  |d	z              }
|	rt/        |	      }nd
}|dk(  rd}nt/        t)        |d            }t%        |      |
k7  rd
|
t%        |      z
  z  |z   }||z   | _        d|	z  | _        d| _        | j6                  rd| _        d| _        | j:                  dk7  rd| _        yy)z
        Sets the value of the object

        :param value:
            An integer or a tuple of integers 0 and 1

        :raises:
            ValueError - when an invalid value is passed
        NF
                    %s._map has not been defined
                    r   r
   rW  z
                %s value must be a tuple of ones and zeros or a set of unicode
                strings, not %s
                zf
                    %s value must be at most %s bits long, specified was %s long
                    0rt  r_  r+   r"   )r   F)r2   rH   r   rB   r   r   r  r   ranger{   r  mapr   r?   r   r   addr3   rD   rstripintmathceilr   rJ   r  r   r   rI   r   )rL   r8   r|  r   r   bitr   sizesize_mod
extra_bitssize_in_bytesextra_bits_bytevalue_bytess                r*   rH   zBitString.set=  s    eS!yy   dO	"   3#D DLq$**- $iimmE*;%<"#DK$ GGC./E__%yy $"u"+E"2 /JE3#yy}}UE:((./ GGC/0E F $%    99 5zDJJ&  dOJJJ"   LL%E5z!8
q=XJS:%%EDIIdQh/0*:6O%OB;K&s5!}5K{},"mc+6F&FG;VK'+5 :-$DDK==CDM  r+   c                    t        |t              }|set        | j                  t              st	        t        dt        |                   || j                  vrt	        t        dt        |       |            | j                  | j                   | j                  4t        | j                        |dz   k\  rt        | j                  |         S y|r| j                  j                  ||      }|| j                  v S )aG  
        Retrieves a boolean version of one of the bits based on a name from the
        _map

        :param key:
            The unicode string of one of the bit names

        :raises:
            ValueError - when _map is not set or the key name is invalid

        :return:
            A boolean if the bit is set
        r  T
                    %s._map does not contain an entry for "%s"
                    r
   F)r2   r   r   rz   rB   r   r   r   r   r   rD   ra  r{   )rL   r   is_ints      r*   r=  zBitString.__getitem__  s     C+dii.  dO	"   $+++  dO"   <<KK994<< C!G+DLL-..))--S)Cdll""r+   c                    t        |t              }|sW| j                  t        t	        dt        |                   || j                  vrt        t	        dt        |       |            | j                  | j                   | j                  Zt        | j                        }t        |      dz
  }||kD  r|j                  dg||z
  z         |rdnd||<   t        |      | _        ns|r| j                  j                  ||      }|r*|| j                  vrE| j                  j                  |       n)|| j                  v r| j                  j                  |       | j!                  | j                         y)a  
        Sets one of the bits based on a name from the _map

        :param key:
            The unicode string of one of the bit names

        :param value:
            A boolean value

        :raises:
            ValueError - when _map is not set or the key name is invalid
        Nr  r  r
   r   )r2   r   r   rB   r   r   r   r   r   r   rD   extendr   r{   r  removerH   )rL   r   r8   r  
new_nativemax_keys         r*   r"  zBitString.__setitem__  sN    C+yy   dO	"   $+++  dO"   <<KK99dll+J*o)GW}!!1#w"78#(aaJsO ,DL iimmC-dll*LL$$S)$,,&LL'',r+   c                    | j                   7| j                  | j                  d       n| j                  t                      | j                  | j	                         \  }}| _        t        ||      }| j                  rht               | _        t        |      D ]?  \  }}|s	| j                  j                  ||      }| j                  j                  |       A | j                  S || _        | j                  S )z
        The native Python datatype representation of this value

        :return:
            If a _map is set, a set of names, or if no _map is set, a tuple of
            integers 1 and 0. None if no value.
        r   )
rJ   r   rH   r   r  r  rz  r   r{   r  )rL   	int_value	bit_countr|  r   r  r   s          r*   r   zBitString.native	  s     == yy <<6:6I6I6K3Iy$"3$Y	:Dyy"u"+D/ /JE3#yy}}UE:((./ ||  $||r+   )r   r   r   r   r4   r  r;   rH   r=  r"  r   r   r   r+   r*   r  r  )  s?     CE	2a F-#^7r  r+   r  c                   `     e Zd ZdZdZdZdZd Zd Z fdZ	d Z
ed	        Zed
        Z xZS )OctetBitStringzB
    Represents a bit string in ASN.1 as a Python byte string
    r   Nr   c           	         t        |t              s(t        t        dt	        |       t	        |                  || _        d|z   | _        d| _        d| _        | j                  rd| _	        d| _
        | j                  dk7  rd| _        yy)
        Sets the value of the object

        :param value:
            A byte string

        :raises:
            ValueError - when an invalid value is passed
        rE  r_  r   NFr   r+   )r2   r   r3   r   r   _bytesrJ   r  r   r   rI   r   r  s     r*   rH   zOctetBitString.set5	  s     %*F $%    %$DDK==CDM  r+   c                 t   | j                   y| j                  | j                  s,| j                         d   \  | _        | _        | j                  S | j                         }d| _        |D ]#  }| j                  rt        d      |d   | _        % dj                  d |D              | _        | j                  S )4
        :return:
            A byte string
        r+   r   r   r  r
   c              3   &   K   | ]	  }|d      yw)r   Nr   ).0r  s     r*   	<genexpr>z+OctetBitString.__bytes__.<locals>.<genexpr>g	  s     &DEuQx&Ds   )rJ   r  r   r   r  r   rB   r  )rL   chunksr  s      r*   rX   zOctetBitString.__bytes__T	  s     == ;;##151A!1D.T. {{ ++-$&!# 1E((()_``(-aD%	1
 "hh&DV&DD{{r+   c                 r    t         t        |   ||       |j                  | _        |j                  | _        y)a&  
        Copies the contents of another OctetBitString object to itself

        :param object:
            Another instance of the same class

        :param copy_func:
            An reference of copy.copy() or copy.deepcopy() to use when copying
            lists, dicts and objects
        N)r   r  rn   r  r  r   s      r*   rn   zOctetBitString._copyk	  s/     	nd)%;ll!..r+   c                    t         rt        | j                  d         n| j                  d   }|s| j                  dd dfgS t        | j                        dk(  rt	        dj                  |            |dkD  rt	        dj                  |            d|z  dz
  }t         rt        | j                  d         n| j                  d   }|| z  }| j                  dd t         rt        |      nt        |f      z   }t        ||z  |      }||fgS )	z
        Allows reconstructing indefinite length values

        :raises:
            ValueError - when an invalid value is passed

        :return:
            List with one tuple, consisting of a byte string and an integer (unused bits)
        r   r
   Nr   ru  rv  rw  r   )	rW   rx  rJ   rD   rB   ry  chrbytesrz  )rL   r{  mask	last_bytezeroed_byter8   r}  s          r*   r   zOctetBitString._as_chunk{	  s    48#dmmA./T]]1=M]]12&+,,t}}"CJJ?[\\Q=DD_UVV_$).2Cb)*b8I	  4%'a#4s;'7UK>EZ['	D(8/J$%%r+   c                 <    | j                   y| j                         S }
        The native Python datatype representation of this value

        :return:
            A byte string or None
        NrJ   rX   rZ   s    r*   r   zOctetBitString.native	       == ~~r+   c                 2    | j                    | j                  S r  r  rZ   s    r*   r}  zOctetBitString.unused_bits	  r  r+   )r   r   r   r   r4   r  r  rH   rX   rn   r   r   r   r}  r   r   s   @r*   r  r  (	  sZ     C F L >./  &D     ! !r+   r  c                   *    e Zd ZdZdZd Zed        Zy)IntegerBitStringz>
    Represents a bit string in ASN.1 as a Python integer
    r   c           	      r   t        |t              s(t        t        dt	        |       t	        |                  |dk  rt        t        dt	        |       |            || _        dt        |d      z   | _        d| _	        d| _
        | j                  rd	| _        d| _        | j                  d
k7  rd
| _        yy)
        Sets the value of the object

        :param value:
            An integer

        :raises:
            ValueError - when an invalid value is passed
        M
                %s value must be a positive integer, not %s
                r   M
                %s value must be a positive integer, not %d
                r_  Trj  r   NFr+   )r2   r   r3   r   r   rB   r   r   rJ   r  r   r   rI   r   r  s     r*   rH   zIntegerBitString.set	  s     %+F $%    19V $   ,uT"BB$DDK==CDM  r+   c                     | j                   y| j                  | j                         \  | _        }| _        | j                  S rp  )rJ   r   r  r  )rL   __s     r*   r   zIntegerBitString.native	  s?     == <<262E2E2G/DL"d/||r+   Nr   r   r   r   r4   rH   r   r   r   r+   r*   r  r  	  s(     C& P  r+   r  c                   F     e Zd ZdZdZdZd Zd Z fdZe	d        Z
 xZS )OctetStringz;
    Represents a byte string in both ASN.1 and Python
       Nc           	          t        |t              s(t        t        dt	        |       t	        |                  || _        || _        d| _        | j                  rd| _        d| _	        | j                  dk7  rd| _
        yyrD  rE  NFr   r+   r2   r   r3   r   r   r  rJ   r   r   rI   r   r  s     r*   rH   zOctetString.set
       %*F $%    $DDK==CDM  r+   c                 v    | j                   y| j                  | j                         | _        | j                  S r  r+   rJ   r  r   rZ   s    r*   rX   zOctetString.__bytes__
  5     == ;;,,.DK{{r+   c                 P    t         t        |   ||       |j                  | _        y)a#  
        Copies the contents of another OctetString object to itself

        :param object:
            Another instance of the same class

        :param copy_func:
            An reference of copy.copy() or copy.deepcopy() to use when copying
            lists, dicts and objects
        N)r   r  rn   r  r   s      r*   rn   zOctetString._copy+
  s!     	k4&ui8llr+   c                 <    | j                   y| j                         S r  r  rZ   s    r*   r   zOctetString.native:
  r  r+   )r   r   r   r   r4   r  rH   rX   rn   r   r   r   r   s   @r*   r  r  	  s9     C F 4
#    r+   r  c                   4    e Zd ZdZdZdZd Zed        Zd Z	y)IntegerOctetStringz?
    Represents a byte string in ASN.1 as a Python integer
    r  Nc           	      t   t        |t              s(t        t        dt	        |       t	        |                  |dk  rt        t        dt	        |       |            || _        t        |d| j                        | _	        d| _
        | j                  rd| _        d| _        | j                  dk7  rd| _        yy)r  r  r   r  F)rk  widthNr+   )r2   r   r3   r   r   rB   r   r   _encoded_widthrJ   r   r   rI   r   r  s     r*   rH   zIntegerOctetString.setV
  s     %+F $%    19V $   $U5@S@ST$DDK==CDM  r+   c                     | j                   y| j                  t        | j                               | _        | j                  S rp  )rJ   r   r   r   rZ   s    r*   r   zIntegerOctetString.native|
  s:     == <<)$*<*<*>?DL||r+   c                     || _         | j                  5t        | j                        |k7  r| j                  | j                         yyy)z
        Set the explicit enoding width for the integer

        :param width:
            An integer byte width to encode the integer to
        N)r  rJ   rD   rH   r   )rL   r  s     r*   set_encoded_widthz$IntegerOctetString.set_encoded_width
  s?     $==$T]]);u)DHHT[[! *E$r+   )
r   r   r   r   r4   r  rH   r   r   r  r   r+   r*   r  r  I
  s4     C N$ L  "r+   r  c                   t     e Zd ZdZdZdZddZd ZddZd Z	d Z
 fdZed	        Zed
        ZddZ xZS )ParsableOctetStringr  Nc                     d}|$|"t        |t              r|j                         }d}t        j                  | fd|i| |r||j
                  df| _        yy)a  
        Allows providing a parsed object that will be serialized to get the
        byte string value

        :param value:
            A native Python datatype to initialize the object value with

        :param parsed:
            If value is None and this is an Asn1Value object, this will be
            set as the parsed value, and the value will be obtained by calling
            .dump() on this object.
        FNTr8   )r2   r'   rc   rA  rS   r?   r   )rL   r8   r   r7   
set_parseds        r*   rS   zParsableOctetString.__init__
  s`     
=V/Jvy4QKKMEJ47u77"F$4$4d;DL r+   c           	          t        |t              s(t        t        dt	        |       t	        |                  || _        || _        d| _        | j                  rd| _        d| _	        | j                  dk7  rd| _
        yyr  r  r  s     r*   rH   zParsableOctetString.set
  r  r+   c                     | j                   | j                   dd ||fk7  r)t        | j                         ||      \  }}|||f| _         | j                   d   S )r   r
   r   r   r   )r   r5   rX   )rL   r0   r1   r   r9   s        r*   r   zParsableOctetString.parse
  s[    $ <<4<<!#4{8K#K*4>>+;$T_`OL!($<DL||Ar+   c                 v    | j                   y| j                  | j                         | _        | j                  S r  r  rZ   s    r*   rX   zParsableOctetString.__bytes__
  r  r+   c                 "    | j                         S )z
        Returns a byte string that can be passed into .set()

        :return:
            A python value that is valid to pass to .set()
        )rX   rZ   s    r*   r   z#ParsableOctetString._setable_native
  s     ~~r+   c                 ~    t         t        |   ||       |j                  | _         ||j                        | _        y)a+  
        Copies the contents of another ParsableOctetString object to itself

        :param object:
            Another instance of the same class

        :param copy_func:
            An reference of copy.copy() or copy.deepcopy() to use when copying
            lists, dicts and objects
        N)r   r  rn   r  r   r   s      r*   rn   zParsableOctetString._copy  s2     	!4.ui@ll /r+   c                     | j                   y| j                  | j                  d   j                  S | j                         S )r  Nr   )rJ   r   r   rX   rZ   s    r*   r   zParsableOctetString.native  s<     == <<#<<?)))>>##r+   c                 X    | j                   | j                          | j                   d   S r   r   rZ   s    r*   r   zParsableOctetString.parsed#  r   r+   c                     | j                   rd}|rM| j                  | j                  j                  |      }n| j                  }d| _        | j                  |       t        j                  |       S )r   TNr   )r   r   r   rc   r   rJ   rH   r'   rG  s      r*   rc   zParsableOctetString.dump1  sa     E||')))6 DMHHV~~d##r+   r   r   )r   r   r   r4   r   r  rS   rH   r   rX   r   rn   r   r   r   rc   r   r   s   @r*   r  r  
  s_    
CG F<0 4.
 0  $ $   $r+   r  c                       e Zd ZdZd Zd Zy)ParsableOctetBitStringr   c           	         t        |t              s(t        t        dt	        |       t	        |                  || _        d|z   | _        d| _        | j                  rd| _        d| _	        | j                  dk7  rd| _
        yy)r  rE  r_  NFr   r+   r  r  s     r*   rH   zParsableOctetBitString.setP  s     %*F $%    %$DDK==CDM  r+   c                     t         rt        | j                  d         n| j                  d   }|rt        d      | j                  dd S )z
        Allows reconstructing indefinite length values

        :raises:
            ValueError - when an invalid value is passed

        :return:
            A byte string
        r   z1ParsableOctetBitString should have no unused bitsr
   N)rW   rx  rJ   rB   )rL   r{  s     r*   r   z ParsableOctetBitString._as_chunkn  sD     48#dmmA./T]]1=MPQQ}}QR  r+   N)r   r   r   r4   rH   r   r   r+   r*   r  r  L  s    
C <!r+   r  c                   .    e Zd ZdZdZdZd Zed        Zy)Nullz<
    Represents a null value in ASN.1 as None in Python
       r+   c                     d| _         y)zV
        Sets the value of the object

        :param value:
            None
        r+   Nr   r  s     r*   rH   zNull.set  s     r+   c                      yr   r   rZ   s    r*   r   zNull.native  r   r+   N)	r   r   r   r   r4   rJ   rH   r   r   r   r+   r*   r  r    s,     CH  r+   r  c                   d    e Zd ZdZdZdZed        Zed        Zd Z	d Z
ed        Zed	        Zy)
ObjectIdentifier`
    Represents an object identifier in ASN.1 as a Python unicode dotted
    integer string
       Nc                     | j                   t        t        dt        |                   t	        |t
              st        t        dt        |                  | j                   j                  ||      S )a^  
        Converts a dotted unicode string OID into a mapped unicode string

        :param value:
            A dotted unicode string OID

        :raises:
            ValueError - when no _map dict has been defined on the class
            TypeError - when value is not a unicode string

        :return:
            A mapped unicode string
        >
                %s._map has not been defined
                H
                value must be a unicode string, not %s
                )r   rB   r   r   r2   r   r3   r{   r6   r8   s     r*   r  zObjectIdentifier.map  sv      88V #	   %)F % 	   xx||E5))r+   c                    | t         vr |        j                          dt         | <   | j                  t        t	        dt        |                   t        |t              st        t	        dt        |                  || j                  v r| j                  |   S t        j                  |      st        t	        dt        |       |            |S )a  
        Converts a mapped unicode string value into a dotted unicode string OID

        :param value:
            A mapped unicode string OR dotted unicode string OID

        :raises:
            ValueError - when no _map dict has been defined on the class or the value can't be unmapped
            TypeError - when value is not a unicode string

        :return:
            A dotted unicode string OID
        Tr  r  zL
                %s._map does not contain an entry for "%s"
                )r@   r;   r   rB   r   r   r2   r   r3   r   _OID_REmatchr  s     r*   unmapzObjectIdentifier.unmap  s      n$ELLN"&N388V #	   %)F % 	   C$$$##E**}}U#V #   r+   c           	         t        |t              s(t        t        dt	        |       t	        |                  || _        | j                  || j                  v r| j                  |   }d| _        d}t        |j                  d            D ]  \  }}t        |      }|dk(  r|}|dk(  rS|dkD  rt        t        dt        |                  |dk  r#|d	k\  rt        t        d
t        |                  |d	z  |z   }t        d|z        }|dz	  }|dkD  rt        dd|z  z        |z   }|dz	  }|dkD  r| xj                  |z  c_         d| _        | j                   dk7  rd| _        yy)a  
        Sets the value of the object

        :param value:
            A unicode string. May be a dotted integer string, or if _map is
            provided, one of the mapped values.

        :raises:
            ValueError - when an invalid value is passed
        rS  Nr+   .r   r
   r"   z\
                        First arc must be one of 0, 1 or 2, not %s
                        (   z
                        Second arc must be less than 40 if first arc is 0 or
                        1, not %s
                           rv     )r2   r   r3   r   r   r   r   r   rJ   r   splitr  rB   rC   r   r   r   )rL   r8   firstr   partencoded_parts         r*   rH   zObjectIdentifier.set  s    %)F $%    99 )))))%0$U[[%56 	*KE4t9D z!19$V U	&   QY42:$V T
&   
d*"4$;/L19D(&ttd{';<|Kqy ( MM\)M=	*@ ==CDM  r+   c                     | j                   S r+  )dottedrZ   s    r*   rY   zObjectIdentifier.__unicode__?  s     {{r+   c                    | j                   -g }d}| j                  D ]  }t        rt        |      }|dz  }||dz  z  }|dz  dk(  s+t	        |      dk(  r|dk\  r8|j                  t        d             |j                  t        |dz
               n|dk\  r8|j                  t        d             |j                  t        |dz
               nO|j                  t        d             |j                  t        |             n|j                  t        |             d} dj                  |      | _         | j                   S )	z
        :return:
            A unicode string of the object identifier in dotted notation, thus
            ignoring any mapped value
        r   r  r  P   r"   r  r
   r  )_dottedrJ   rW   rx  rD   r!  r   r  )rL   r   r	  bytes       r*   r  zObjectIdentifier.dottedG  s    <<FD t9Dczs
"$;!#6{a'2:"MM'!*5"MM'$)*<=!RZ"MM'!*5"MM'$)*<="MM'!*5"MM'$-8gdm4D'* 88F+DL||r+   c                     | j                   y| j                  | j                  | _        | j                  6| j                  | j                  v r| j                  | j                     | _        | j                  S )aC  
        The native Python datatype representation of this value

        :return:
            A unicode string or None. If _map is not defined, the unicode string
            is a string of dotted integers. If _map is defined and the dotted
            string is present in the _map, the mapped value is returned.
        N)rJ   r   r  r   rZ   s    r*   r   zObjectIdentifier.nativek  s]     == <<;;DL99 T\\TYY%>99T\\2DL||r+   )r   r   r   r   r4   r  r   r  r  rH   rY   r   r  r   r   r+   r*   r  r    sq    
 C G* *B / /b? B ! !F  r+   r  c                       e Zd ZdZdZy)ObjectDescriptorzO
    Represents an object descriptor from ASN.1 - no Python implementation
    rv  Nr   r   r   r   r4   r   r+   r*   r  r         Cr+   r  c                       e Zd ZdZdZy)
InstanceOfzF
    Represents an instance from ASN.1 - no Python implementation
    rt  Nr  r   r+   r*   r  r    r  r+   r  c                       e Zd ZdZdZy)RealzH
    Represents a real number from ASN.1 - no Python implementation
    	   Nr  r   r+   r*   r  r    r  r+   r  c                   *    e Zd ZdZdZd Zed        Zy)
Enumeratedz\
    Represents a enumerated list of integers from ASN.1 as a Python
    unicode string
    
   c           	         t        |t              s8t        |t              s(t        t	        dt        |       t        |                  t        |t              r=|| j                  vrt        t	        dt        |       |            | j                  |   }n-|| j                  vrt        t	        dt        |       |            t        j                  | |       y)z
        Sets the value of the object

        :param value:
            An integer or a unicode string from _map

        :raises:
            ValueError - when an invalid value is passed
        zY
                %s value must be an integer or a unicode string, not %s
                zL
                    %s value "%s" is not a valid value
                    zB
                %s value %s is not a valid value
                N)r2   r   r   r3   r   r   r   rB   r   rh  rH   r  s     r*   rH   zEnumerated.set  s     %+Jug4NF $%    eW%D---  dO"   %%e,E$))#V $   	D% r+   c                     | j                   y| j                  "| j                  | j                            | _        | j                  S r[  )rJ   r   r   rn  rZ   s    r*   r   zEnumerated.native  s;     == <<99T\\^4DL||r+   Nr  r   r+   r*   r  r    s(    
 C)!V  r+   r  c                       e Zd ZdZdZdZy)
UTF8StringzI
    Represents a UTF-8 string from ASN.1 as a Python unicode string
       rf   Nr   r   r   r   r4   rU  r   r+   r*   r!  r!         CIr+   r!  c                       e Zd ZdZdZy)RelativeOidr     Nr  r   r+   r*   r&  r&    s    
 Cr+   r&  c                       e Zd ZdZdZdZdZdZdZdZ	g Z
dZdZdZdZdZdZdZddZed        Zej*                  d	        Zd
 Zd Zd Zd Zd Zd Zd ZddZd Zd Zd Z ddZ!d Z"ed        Z# fdZ$ddZ%ddZ& xZ'S )Sequencezf
    Represents a sequence of fields from ASN.1 as a Python object with a
    dict-like interface
       r   r
   NFc                    t        j                  | fi | d}|1|/d}| j                  | j                  d}n| j	                          |}|0	 | j
                  r6| j
                  D cg c]  }|d   	 }}t        |j                               }n|j                         }t        |      }|D ]  }|rR| j                  |   }	|	t        | j                        k  r+| j                  |	   t        ur||v r|j                  |       W||v s\| j                  |||          |j                  |        t        |      r@t        t        dt        |       dj!                  t#        t%        |                              yyc c}w # t        t&        f$ r=}
|
j(                  dd }|
j(                  d   dt        |       z  z   f|z   |
_        |
d}
~
ww xY w)	a"  
        Allows setting field values before passing everything else along to
        Asn1Value.__init__()

        :param value:
            A native Python datatype to initialize the object value with

        :param default:
            The default value if no value is specified
        FNTr   z
                        One or more unknown fields was passed to the constructor
                        of %s: %s
                        r  r
   r>   )r'   rS   childrenrJ   _parse_children_fieldsrH   r  
_field_maprD   VOIDr  r"  rB   r   r   r  sortedr   r3   rK   )rL   r8   rP   r7   check_existingr   r  unused_keysr   r   rR   rK   s               r*   rS   zSequence.__init__'  s    	4*6*=W0!N}}$==(%*N((*E& <<04=DG=D="%ejjl"3K ::<D"%d)K 0C & $ 4 3t}}#55$--:NVZ:Z"k1 + 2 23 7$e|((eCj9#**3/0 {#$V "$		&k):";<&   $5  >< 	* vvabz&&)&CiPTo&UUWZ^^s2   F *F 6BF A3F  F G8GGc                     | j                   | j                  S | j                         r| j                          | j                  S z`
        :return:
            A byte string of the DER-encoded contents of the sequence
        r,  r  _is_mutated_set_contentsrZ   s    r*   rJ   zSequence.contentsh  :     == >>! ~~r+   c                     || _         yze
        :param value:
            A byte string of the DER-encoded contents of the sequence
        Nr  r  s     r*   rJ   zSequence.contentsw  r  r+   c                     | j                   }| j                  F| j                  D ]7  }t        |t              st        |t              s$|xs |j                         }9 |S z~
        :return:
            A boolean - if the sequence or any children (recursively) have been
            mutated
        _mutatedr,  r2   r)  
SequenceOfr7  rL   mutatedr4  s      r*   r7  zSequence._is_mutated  W     --==$ =eX.*UJ2O%<):):)<G= r+   c                 x    | j                   |   }|j                  t        k(  rt        | x}| j                   |<   |S z]
        Builds a child object if the child has only been parsed into a tuple so far
        r,  r?   r   _buildrL   r   r4  s      r*   _lazy_childzSequence._lazy_child  s:    
 e$??e#+15>9EDMM%(r+   c                 d    | j                   | j                          t        | j                         S r9  r,  r-  rD   rZ   s    r*   r   zSequence.__len__  )     ==   "4==!!r+   c           	         | j                   | j                          t        |t              s<|| j                  vrt        t        d|t        |                   | j                  |   }|t        | j                         k\  rt        t        d|t        |                   	 | j                  |      S # t        t        f$ r=}|j                  dd }|j                  d   dt        |       z  z   f|z   |_        |d}~ww xY w)a9  
        Allows accessing fields by name or index

        :param key:
            A unicode string of the field name, or an integer of the field index

        :raises:
            KeyError - when a field name or index is invalid

        :return:
            The Asn1Value object of the field specified
        NL
                    No field named "%s" defined for %s
                    zL
                No field numbered %s is present in this %s
                r
   r   r   )r,  r-  r2   r   r/  r;  r   r   rD   rI  rB   r3   rK   )rL   r   rR   rK   s       r*   r=  zSequence.__getitem__  s    ==   "#y)$//)v dO    //#&C#dmm$$6 $  	##C((I& 	66!":DffQi":Yt_"LLNQUUAFG	s   !B2 2C>8C99C>c           	      |   | j                   | j                          t        |t              s<|| j                  vrt        t        d|t        |                   | j                  |   }| j                  |      \  }}}}}| j                  |||||      }d}	t        |t              r|j                  du }	n|j                  du }	|	rt        t        d|t        |                   || j                   |<   | j                  6| j                   |   j                  | j                  | j                   |   d   <   d| _        y)a  
        Allows settings fields by name or index

        :param key:
            A unicode string of the field name, or an integer of the field index

        :param value:
            A native Python datatype to set the field value to. This method will
            construct the appropriate Asn1Value object from _fields.

        :raises:
            ValueError - when a field name or index is invalid
        NrN  FzG
                Value for field "%s" of %s is not set
                r   T)r,  r-  r2   r   r/  r;  r   r   _determine_spec_make_valuer   r   rJ   rB   r   r   r.  r?  )
rL   r   r8   
field_name
field_spec
value_specfield_paramsr9   	new_valueinvalid_values
             r*   r"  zSequence.__setitem__  s=     ==   "#y)$//)v dO    //#&C>B>R>RSV>W;
J
L!$$ZZW\]	i%%,,4M%..$6MV $   'c<<#15s1C1J1JDLLc*1-.r+   c           	         | j                   | j                          t        |t              s<|| j                  vrt        t        d|t        |                   | j                  |   }| j                  |   \  }}}|rd|vr#d|vrt        t        d|t        |                   d|v r6t        | j                   |<   | j                  )d| j                  |<   d| _        y| j                  |d       d| _        y)a/  
        Allows deleting optional or default fields by name or index

        :param key:
            A unicode string of the field name, or an integer of the field index

        :raises:
            ValueError - when a field name or index is invalid, or the field is not optional or defaulted
        NrN  rP   rO   z
                Can not delete the value for the field "%s" of %s since it is
                not optional or defaulted
                T)r,  r-  r2   r   r/  r;  r   r   r.  rB   r0  r   r"  r?  )rL   r   r   r9   r   s        r*   __delitem__zSequence.__delitem__	  s    ==   "#y)$//)v dO    //#&C,,s+a)61j6NV $   !%DMM#||'%)T"  S$'r+   c              #   <   K   | j                   D ]	  }|d     yw)zE
        :return:
            An iterator of field key names
        r   N)r.  )rL   r   s     r*   r   zSequence.__iter__6  s$      LL 	Dq'M	s   c                 L   | j                   | j                          t               }t        | j                        D ]  \  }}| j                   |   }|d}n[|j
                  t        k(  r6|r"| j                  |      j                  |      }n$|d   |d   z   |d   z   }n|j                  |      }|d   r)d|d   v r" |d	   d
i |d   }|j                         |k(  r|j                  |        |j                         | _        d| _        | j                  dk7  rd| _        yy)a   
        Updates the .contents attribute of the value with the encoded value of
        all of the child objects

        :param force:
            Ensure all contents are in DER format instead of possibly using
            cached BER-encoded data
        Nr+   r   r   r  r  r"   rP   r
   r   )r,  r-  r   r   r.  r?   r   rI  rc   writegetvaluer  r   r   )rL   r   rJ   r   r   r4  
child_dumpdefault_values           r*   r8  zSequence._set_contents?  s'    ==   "9$T\\2 	'KE4MM%(E} 
E)!%!1!1%!8!=!=E!=!JJ!&qE!H!4uQx!?J"ZZeZ4
Aw9Q/ 'Q 2$q' 2 %%':5NN:&!	'" "**,==CDM  r+   c                 *   | j                   }i |_        g |_        g |_        t	        |j
                        D ]e  \  }}t        |      dk  r|i fz   }||j
                  |<   ||j                  |d   <   |j                  j                  t        |d   |d                g |j                  =|j                  |j                  d      |j                  |j                  d      f|_
        t	        |j
                        D ]  \  }}|j                  duxr |d   |j                  v }|j                  duxr |j                  d   |k(  }|s|r|j                  j                  d       i|j                  j                  |d   |d   |d   |d   df        yzS
        Generates _field_map, _field_ids and _oid_nums for use in parsing
        r   r   r"   r
   N)r?   r/  
_field_ids_precomputed_specsr   r.  rD   r!  r   	_oid_pair	_oid_nums_spec_callbacksrL   r6   r   fieldhas_callbackis_mapped_oids         r*   r;   zSequence._setupd  s   
 nn!#%ckk2 	GLE55zA~%*E"',CNN58$NN!!/%(E!H"EF	G ==$ ^^CMM!,<=s~~cmm\]N^?_`CM%ckk2 	^LE5..d:^uQx3K^K^?^LMM5S#--:Je:SM}&&--d3&&--uQxq58USTXW[.\]	^r+   c                    | j                   |   \  }}}|}d}| j                  `|| j                  v rR| j                  |   } ||       }|r|j                  t        k(  rt	        |      dk(  r|\  }}|v|}d}nq||}|}d}nh|}ne| j
                  Y| j
                  d   |k(  rG| j                  | j
                  d         j                  }|| j                  v r| j                  |   }|}|||||fS )a  
        Determine how a value for a field should be constructed

        :param index:
            The field number

        :return:
            A tuple containing the following elements:
             - unicode string of the field name
             - Asn1Value class of the field spec
             - Asn1Value class of the value spec
             - None or dict of params to pass to the field spec
             - None or Asn1Value class indicating the value spec was derived from an OID or a spec callback
        Nr"   r
   r   )	r.  rf  r?   r   rD   re  rI  r   
_oid_specs)	rL   r   r   rS  rU  rT  spec_overridecallbackoids	            r*   rP  zSequence._determine_spec  s     *.e)<&j,
+8L8L0L++D1H$TNM !**e3M8Ja8O-:*J
!)%/
(,'!.J!+J$(M!.J^^'DNN1,=,F""4>>!#45<<Cdoo% $ 4*
j*lMJJr+   c           
         |
d|v rt         S ||k7  }t        |t              }t        |t              rt	        |t
              }t	        |t              xr t        |      dk(  }	t	        |t              xr t        |      dk(  }
|s#|	s!|
st        t        d|t        |                  |	s|
r ||      }t	        ||      sB |       }|j                  |j                  |j                  |j                         ||_        |}n|}nt	        ||      r|}|r|j#                  |       n|r|rSt	        ||      sG|r|r9t	        |t
              r)t%        t        d|t        |      t        |                   ||fi |}nt	        ||      r|}nAt	        |t
              r)t%        t        d|t        |      t        |                   ||      }|r0|s. |d	d|j'                         i|}||j(                  df|_        |}t+        ||      }|S )
a&  
        Contructs an appropriate Asn1Value object for a field

        :param field_name:
            A unicode string of the field name

        :param field_spec:
            An Asn1Value class that is the field spec

        :param value_spec:
            An Asn1Value class that is the vaue spec

        :param field_params:
            None or a dict of params for the field spec

        :param value:
            The value to construct an Asn1Value object from

        :return:
            An instance of a child class of Asn1Value
        NrO   r"   r
   z
                    Can not set a native python value to %s, which has the
                    choice type of %s - value must be an instance of Asn1Value
                    zE
                    %s value must be %s, not %s
                    zM
                        %s value must be %s, not %s
                        r8   r   )r0  
issubclassr   r   r2   r'   r   rD   rz   rB   r   r   r  rG   r4   rJ   r   r   r3   rc   r?   r   )rL   rR  rS  rT  rU  r8   specs_differentis_anyis_asn1valueis_tupleis_dictwrapperrV  s                r*   rQ  zSequence._make_value  s
   . =Z<7K$
2J,j&)%eY7L!%/CCJ!OH -A#e*/G  j)"   7"5)eZ0$,  uyy%..I"'#	!	z*I
+!VZz5Ro:eY3O j)e$!   #59L9I %,!	eY/#F #!*-!%(%   'u-	
 v$L9>>+;L|L#,i.A.A4"H#	 L9	r+   c                    | j                   }| j                  | j                  rt        gt	        | j                        z  | _        t        | j                        D ]l  \  }\  }}}d|v s|j                  |   r|j                  |   \  }}}}	}n| j                  |      \  }}}}	}| j                  ||||	d      | j
                  |<   n y	 g | _        t	        | j                        }
d}d}t	        | j                        }d}||
k  }|r^|t        | j                  |
|      \  }}||
k  }||k  r	|j                  |   xs | j                  |      \  }}}}	}|	rd|	v sd|	v r| j                  |   |d   |d   fk7  r|t        k7  rd}t        |t              r'	  |di |	}|j                  |d   |d   |d          d	}|sNd|	v r | j
                  j#                  t               n!| j
                  j#                   |di |	       |d
z  }d	}	||rt        |t              r|}d}|r	|||	|fz   }n|||	fz   }n|dkD  r|d
z   |k  rg }|d
z
  }|dk\  rK| j                  |   }t	        |      dk  rn-d|d   v sd|d   v r|j#                  |d          |d
z  }|dk\  rKt	        |      d
kD  rdnd}dj%                  |      }t!        t'        d|d
z   t(        j+                  |d         t,        j+                  |d
         |d   ||            |}|r0t/        | }t1        |t2        t4        f      r|j7                  d	       | j
                  j#                  |       |d
z  }d}|r^t	        | j
                        }||k  r~| j                  |   \  }}}	d|	v r"| j
                  j#                   |di |	       n9d|	v r | j
                  j#                  t               nt!        t'        d|            |d
z  }||k  r}yy# t         $ r Y Mw xY w# t         t8        f$ rD}d| _        |j:                  d
d }|j:                  d   dt=        |       z  z   f|z   |_        |d}~ww xY w)Q  
        Parses the contents and generates Asn1Value objects based on the
        definitions from _fields.

        :param recurse:
            If child objects that are Sequence or SequenceOf objects should
            be recursively parsed

        :raises:
            ValueError - when an error occurs parsing child objects
        NrP   r   r   rO   r"   Fr  Tr
   r   srW  r  z
                        Data for field %s (%s class, %s method, tag %s) does
                        not match the field definition%s of %s
                        recursezV
                        Field "%s" is missing from structure
                        r   r   )r?   r  r.  r0  rD   r,  r   rc  rP  rQ  r   rb  r   rq  r   r  rB   r!  r  r   rE   r{   METHOD_NUM_TO_NAME_MAPrG  r2   r)  r@  r-  r3   rK   r   )rL   r}  r6   r   r9   r   rR  rS  rT  rU  contents_lengthchild_pointerrh  	field_lenpartsagainrm  choice_matchtesterr4  missed_fields
prev_fieldprev_field_infopluralmissed_field_namesr   rR   rK   s                               r*   r-  zSequence._parse_children  s    nn>>!||!%T\\): :-6t||-D x)E>Aq& F*11%8RURhRhinRoOJ
JaRVRfRfglRmOJ
Ja/3/?/?
JXbdprv/we,x l	DM!$..1OMEDLL)IE!O3E=+1$../[h+i(E=%79$..u5T9M9Me9T KAz:|] $|)CyT`G`??51eAha5IIj\_N_ ,1L)*f=!)-7-G,-GF$*OOE!HeAha$Q37L $0#-#=$(MM$8$8$>$(MM$8$89Sl9S$T %
(, (!)m
:WZ@[%/
(,$ %\:(N N %\(B B ]uqyI'=$&M!&J$/*.,,z*B/!3!%);;yO\]L^?^)001CD"a
 %/ %($6$:SF)-=)A&$V 	-11%(;.2258<a*&   "E"ENE!%(J)?@--d-;$$U+
] ` &E)#15e1D.j,,MM(()Cl)CD</MM((.$V 	&   
 )#y )3 !)$(!)V I& 	 DM66!":DffQi":Yt_"LLNQUUAFG		sL   CP &P CP !CP *BP 	PP PP Q&"?Q!!Q&c           	         t        |t              st        t        dt	        |                  | j
                  (t        t        dt        |      t	        |                   | j                  |   }| j                  |      }|d   S )a  
        Determines the spec to use for the field specified. Depending on how
        the spec is determined (_oid_pair or _spec_callbacks), it may be
        necessary to set preceding field values before calling this. Usually
        specs, if dynamic, are controlled by a preceding ObjectIdentifier
        field.

        :param field_name:
            A unicode string of the field name to get the spec for

        :return:
            A child class of asn1crypto.core.Asn1Value that the field must be
            encoded using
        zM
                field_name must be a unicode string, not %s
                z
                Unable to retrieve spec for field %s in the class %s because
                _fields has not been set
                r"   )
r2   r   r3   r   r   r.  rB   rC   r/  rP  )rL   rR  r   r   s       r*   r0   zSequence.spec  s      *g.F *%	   <<V Z $   
+##E*Awr+   c                    | j                   y| j                  | j                  | j                  d       	 t	               | _        t        | j                        D ][  \  }}|j                  t        k(  rt        | }|| j                  |<   	 | j                  |   d   }|j                  | j                  |<   ] 	 | j                  S | j                  S # t        $ r t        |      }Y Jw xY w# t        t        f$ rD}d| _        |j                  dd }|j                  d   dt!        |       z  z   f|z   |_        |d}~ww xY w)z
        The native Python datatype representation of this value

        :return:
            An OrderedDict or None. If an OrderedDict, all child values are
            recursively converted to native representation also.
        NTr|  r   r
   r   )rJ   r   r,  r-  r   r   r?   r   rG  r.  
IndexErrorr   r   rB   r3   rK   r   )rL   r   r4  r   rR   rK   s         r*   r   zSequence.native  s6    == <<}}$$$T$2*}$-dmm$< 6LE5%/ &/4e,.#||E215 */DLL&6 ||t|| ' .&u~. 	* #vvabz&&)&>4&PPRUYY	s<   AC. C C. C+(C. *C++C. .E=?D<<Ec                 (   t         t        |   ||       | j                  qg | _        |j                  D ]Z  }|j                  t
        k(  r| j                  j                  |       2| j                  j                  |j                                \ yy)a   
        Copies the contents of another Sequence object to itself

        :param object:
            Another instance of the same class

        :param copy_func:
            An reference of copy.copy() or copy.deepcopy() to use when copying
            lists, dicts and objects
        N)r   r)  rn   r,  r?   r   r!  ro   rL   r   r   r4  r?   s       r*   rn   zSequence._copy  su     	h#E95==$DM 7??e+MM((/MM((6	7 %r+   c                    | j                   | j                          d|z  }t        ||        | D ]N  }| j                  | j                  |         }|t
        us*t        |d|d       |j                  |dz          P y)r   Nr   z    Field ""r   )r,  r-  r   rI  r/  r0  r   r   )rL   r   r   rR  r4  s        r*   r   zSequence.debug  s{    
 ==   "
"VT" 	,J$$T__Z%@AED FJ?@JN+		,r+   c                    | j                   | j                   dd dk(  rd}|r#| j                  g k(  r| j                  t        u rd}|r| j	                  |       | j                  r`| j
                  Tt        | j                        D ]<  \  }\  }}}| j
                  |   t        ur d|v sd|v r)t        t        d	|             t        j                  |       S )
r   Nr   r   TFr   rP   rO   zN
                    Field "%s" is missing from structure
                    )r   r.  r?   r)  r8  r,  r   r0  rB   r   r'   rc   )rL   r   r   rR  r9   r   s         r*   rc   zSequence.dump  s     <<#RS(9W(DE T\\R'DNNh,FEU+<<DMM52;DLL2I 
..
Av=='t3&**>  	"  
 ~~d##r+   r   r   r   )(r   r   r   r   r4   rG   rI   r,  r  r?  r.  rf  r/  rb  rd  rl  re  rc  rS   r   rJ   r  r7  rI  r   r=  r"  rY  r   r8  r;   rP  rQ  r-  r0   r   rn   r   rc   r   r   s   @r*   r)  r)    s
   
 CFF H I H G O J J
 I J I ?B   __ 	",\5n+Z# J^6-K^^@FP%N  B7*, $$r+   r)  c                        e Zd ZdZdZdZdZdZdZdZ	dZ
ddZed        Zej                  d	        Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd ZddZddZd Zed        Z fdZddZddZ xZ S )r@  z
    Represents a sequence (ordered) of a single type of values from ASN.1 as a
    Python object with a list-like interface
    r*  r   r
   NFc                    |r|| _         t        j                  | fi | 	 ||| _        y|||}|Ct	        |      D ]  \  }}| j                  ||        | j                  | j                          yyy# t        t        f$ r=}|j                  dd }	|j                  d   dt        |       z  z   f|	z   |_	        |d}~ww xY w)a  
        Allows setting child objects and the _child_spec via the spec parameter
        before passing everything else along to Asn1Value.__init__()

        :param value:
            A native Python datatype to initialize the object value with

        :param default:
            The default value if no value is specified

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

        :param spec:
            A class derived from Asn1Value to use to parse children
        Nr
   r   r>   )_child_specr'   rS   rJ   r   r"  r8  rB   r3   rK   r   )
rL   r8   rP   rJ   r0   r7   r   r4  rR   rK   s
             r*   rS   zSequenceOf.__init__C  s    $ #D4*6*	# (=W%8#E$(1%(8 7u((67 }},**, - % I& 	66!":DffQi"?)D/"QQSVZZAFG	s   	A7 A	A7 7C8B>>Cc                     | j                   | j                  S | j                         r| j                          | j                  S r5  r6  rZ   s    r*   rJ   zSequenceOf.contentsn  r9  r+   c                     || _         yr;  r  r  s     r*   rJ   zSequenceOf.contents}  r  r+   c                     | j                   }| j                  F| j                  D ]7  }t        |t              st        |t              s$|xs |j                         }9 |S r=  r>  rA  s      r*   r7  zSequenceOf._is_mutated  rC  r+   c                 x    | j                   |   }|j                  t        k(  rt        | }|| j                   |<   |S rE  rF  rH  s      r*   rI  zSequenceOf._lazy_child  s:    
 e$??e#ENE#(DMM% r+   c                 t   t        || j                        r|}nt        | j                  t              r1t        |t              r|}nt        t        dt        |                   t        | j                  t              rt        |t              s3t        t        dt        |       | j                  j                              t        || j                        sJ| j                         }|j                  |j                  |j                  |j                         ||_        |}|}n| j                  |      S i }| j                  j                  r| j                  j                  |d<   | j                  j                   r/| j                  j                  | j                  j                  f|d<   t#        ||      S )a  
        Constructs a _child_spec value from a native Python data type, or
        an appropriate Asn1Value object

        :param value:
            A native Python value, or some child of Asn1Value

        :return:
            An object of type _child_spec
        z
                    Can not set a native python value to %s where the
                    _child_spec is Any - value must be an instance of Asn1Value
                    z
                    Can not set a native python value to %s where the
                    _child_spec is the choice type %s - value must be an
                    instance of Asn1Value
                    )r8   r<   r=   )r2   r  rq  r   r'   rB   r   r   r   r   r  rG   r4   rJ   r   r<   r=   r   )rL   r8   rV  rw  r   s        r*   rQ  zSequenceOf._make_value  sy    eT--.I((#.%+!	  dO"   ((&1eY/ 
 dO$$--"   eT%5%56**,  uyy%..I"'I ##%#00$$!%!1!1!:!:F:$$"&"2"2"9"94;K;K;O;O!PF:Iv..r+   c                 d    | j                   | j                          t        | j                         S )rm  rK  rZ   s    r*   r   zSequenceOf.__len__  rL  r+   c                 \    | j                   | j                          | j                  |      S )zm
        Allows accessing children via index

        :param key:
            Integer index of child
        )r,  r-  rI  r<  s     r*   r=  zSequenceOf.__getitem__  s+     ==   "$$r+   c                    | j                   | j                          | j                  |      }|t        | j                         k(  rB| j                   j	                  d       | j
                  | j
                  j	                  d       || j                   |<   | j
                  &| j                   |   j                  | j
                  |<   d| _        y)z
        Allows overriding a child via index

        :param key:
            Integer index of child

        :param value:
            Native python datatype that will be passed to _child_spec to create
            new child object
        NT)r,  r-  rQ  rD   r!  r   r   r?  )rL   r   r8   rV  s       r*   r"  zSequenceOf.__setitem__  s     ==   "$$U+	 #dmm$$MM  &||'##D)&c<<# $c 2 9 9DLLr+   c                     | j                   | j                          | j                   j                  |       | j                  | j                  j                  |       d| _        y)zk
        Allows removing a child via index

        :param key:
            Integer index of child
        NT)r,  r-  popr   r?  r<  s     r*   rY  zSequenceOf.__delitem__  sO     ==   "#<<#LLS!r+   c              #      K   | j                   | j                          t        dt        | j                               D ]  }| j	                  |        yw)zA
        :return:
            An iter() of child objects
        Nr   )r,  r-  r  rD   rI  )rL   r   s     r*   r   zSequenceOf.__iter__!  sN      ==   "1c$--01 	*E""5))	*s   AAc           
          ||t         u ryt        || j                        s<t        t	        dt        |       t        | j                        t        |                  | D ]	  }||k(  s	 y y)z
        :param item:
            An object of the type cls._child_spec

        :return:
            A boolean if the item is contained in this SequenceOf
        Fzy
                Checking membership in %s is only available for instances of
                %s, not %s
                T)r0  r2   r  r3   r   r   )rL   itemr4  s      r*   __contains__zSequenceOf.__contains__.  sy     <44<$ 0 01F $$**+$    	E}	 r+   c                    | j                   | j                          | j                   j                  | j                  |             | j                  2| j                  j                  | j                   d   j
                         d| _        y)z
        Allows adding a child to the end of the sequence

        :param value:
            Native python datatype that will be passed to _child_spec to create
            new child object
        Nr   T)r,  r-  r!  rQ  r   r   r?  r  s     r*   r!  zSequenceOf.appendK  si     ==   "T--e45<<#LLb 1 8 89r+   c                    | j                   | j                          t               }| D ]#  }|j                  |j	                  |             % |j                         | _        d| _        | j                  dk7  rd| _        yy)z
        Encodes all child objects into the contents for this object

        :param force:
            Ensure all contents are in DER format instead of possibly using
            cached BER-encoded data
        Nr   r+   )	r,  r-  r   r\  rc   r]  r  r   r   r6  s       r*   r8  zSequenceOf._set_contents_  sv     ==   "9 	4ENN5::E:23	4!**,==CDM  r+   c                 .   	 g | _         | j                  yt        | j                        }d}||k  rt        | j                  ||      \  }}| j                  r|| j                  fz   }n|}|r0t        | }t        |t        t        f      r|j                  d       | j                   j                  |       ||k  ryy# t        t        f$ rD}d| _         |j                  dd }|j                  d   dt        |       z  z   f|z   |_        |d}~ww xY w)aU  
        Parses the contents and generates Asn1Value objects based on the
        definitions from _child_spec.

        :param recurse:
            If child objects that are Sequence or SequenceOf objects should
            be recursively parsed

        :raises:
            ValueError - when an error occurs parsing child objects
        Nr   rz  Tr|  r
   r   )r,  r  rD   r   r  rG  r2   r)  r@  r-  r!  rB   r3   rK   r   )rL   r}  r  r  r  r4  rR   rK   s           r*   r-  zSequenceOf._parse_childrens  s   	DM~~%!$..1OM/1'-dnnoWd'e$}##!T%5%5$77E!E"ENE!%(J)?@--d-;$$U+  /1 I& 	 DM66!":DffQi":Yt_"LLNQUUAFG		s   C B(C D?DDc                     | j                   S )z
        Determines the spec to use for child values.

        :return:
            A child class of asn1crypto.core.Asn1Value that child values must be
            encoded using
        )r  rZ   s    r*   r0   zSequenceOf.spec  s     r+   c                    | j                   y| j                  J| j                  | j                  d       	 | D cg c]  }|j                   c}| _        | j                  S | j                  S c c}w # t
        t        f$ r=}|j                  dd }|j                  d   dt        |       z  z   f|z   |_        |d}~ww xY w)z
        The native Python datatype representation of this value

        :return:
            A list or None. If a list, all child values are recursively
            converted to native representation also.
        NTr|  r
   r   r   )	rJ   r   r,  r-  r   rB   r3   rK   r   )rL   r4  rR   rK   s       r*   r   zSequenceOf.native  s     == <<}}$$$T$2:>??
 ||t||  @	* vvabz&&)&>4&PPRUYYs(   A5 A0A5 0A5 5C8B<<Cc                 (   t         t        |   ||       | j                  qg | _        |j                  D ]Z  }|j                  t
        k(  r| j                  j                  |       2| j                  j                  |j                                \ yy)a"  
        Copies the contents of another SequenceOf object to itself

        :param object:
            Another instance of the same class

        :param copy_func:
            An reference of copy.copy() or copy.deepcopy() to use when copying
            lists, dicts and objects
        N)r   r@  rn   r,  r?   r   r!  ro   r  s       r*   rn   zSequenceOf._copy  su     	j$%eY7==$DM 7??e+MM((/MM((6	7 %r+   c                     | j                   | j                          d|z  }t        ||        | D ]  }|j                  |dz           y)r   Nr   r
   )r,  r-  r   r   r3  s       r*   r   zSequenceOf.debug  sM    
 ==   "
"VT" 	(EKK
Q'	(r+   c                     | j                   | j                   dd dk(  rd}|r| j                  |       t        j                  |       S )r   Nr   r   Tr   )r   r8  r'   rc   r   s     r*   rc   zSequenceOf.dump  sH     <<#RS(9W(DEU+~~d##r+   )NNNNr   r   )!r   r   r   r   r4   rG   rI   r,  r  r?  r  rS   r   rJ   r  r7  rI  rQ  r   r=  r"  rY  r   r  r!  r8  r-  r0   r   rn   r   rc   r   r   s   @r*   r@  r@  +  s    
 CFF H I H K)V   __ 	5/n	"%>$*:( ("H	   .7*($r+   r@  c                   6    e Zd ZdZdZdZdZdZd Zd	dZ	d	dZ
y)
Setzm
    Represents a set of fields (unordered) from ASN.1 as a Python object with a
    dict-like interface
    r
   r      Nc                    | j                   }i |_        i |_        g |_        t	        |j
                        D ]Y  \  }}t        |      dk  r|i fz   }||j
                  |<   ||j                  |d   <   ||j                  t        |d   |d         <   [ |j                  =|j                  |j                  d      |j                  |j                  d      f|_	        t	        |j
                        D ]  \  }}|j                  duxr |d   |j                  v }|j                  duxr |j                  d   |k(  }|s|r|j                  j                  d       i|j                  j                  |d   |d   |d   |d   df        yra  )r?   r/  rb  rc  r   r.  rD   r   rd  re  rf  r!  rg  s         r*   r;   z
Set._setup   s~   
 nn!#%ckk2 	HLE55zA~%*E"',CNN58$BGCNN?58U1X>?	H ==$ ^^CMM!,<=s~~cmm\]N^?_`CM%ckk2 	^LE5..d:^uQx3K^K^?^LMM5S#--:Je:SM}&&--d3&&--uQxq58USTXW[.\]	^r+   c                    | j                   }| j                  | j                  rt        gt	        | j                        z  | _        t        | j                        D ]l  \  }\  }}}d|v s|j                  |   r|j                  |   \  }}}}	}n| j                  |      \  }}}}	}| j                  ||||	d      | j
                  |<   n y	 i }
t	        | j                        }d}d}||k  rt        | j                  ||      \  }}|d   |d   f}| j                  j                  |      }|Gt        t        d|t         j                  |d         t"        j                  |d         |d               |j                  |   xs | j                  |      \  }}}}	}||rt%        |t&              r|}d}|r	|||	|fz   }n|||	fz   }|r0t)        | }t+        |t,        t.        f      r|j1                  d	       ||
|<   |dz  }||k  rt	        | j                        }t3        d|      D ]  }||
v r|j                  |   xs | j                  |      \  }}}}	}||rt%        |t&              r|}d}d
}|	sd}n(d|	vrd|	vrd}nd|	v r
t        |
|<   nd|	v r |di |	|
|<   |szt        t        d|t5        |                    g | _        t3        d|      D ]   }| j
                  j7                  |
|          " y# t        t8        f$ r=}|j:                  dd }|j:                  d   dt5        |       z  z   f|z   |_        |d}~ww xY w)ry  NrP   r   rz  r"   z
                        Data for field %s (%s class, %s method, tag %s) does
                        not match any of the field definitions
                        r
   Tr|  FrO   zU
                        Missing required field "%s" from %s
                        r   r   )r?   r  r.  r0  rD   r,  r   rc  rP  rQ  rJ   r   rb  r{   rB   r   rE   r~  rq  r   rG  r2   r)  r@  r-  r  r   r!  r3   rK   )rL   r}  r6   r   r9   r   rR  rS  rT  rU  	child_mapr  r  
seen_fieldr  r   rh  rm  r4  total_fieldsr   missingrR   rK   s                           r*   r-  zSet._parse_children  s    nn>>!||!%T\\): :-6t||-D x)E>Aq& F*11%8RURhRhinRoOJ
JaRVRfRfglRmOJ
Ja/3/?/?
JXbdprv/we,x S	I!$--0OMJ/1'-dmm_Vc'd$}Qxq*++C0=$V #-11%(;.2258<a	& 	 	 **51PT5I5I%5P G:z< %-JzSV<W!+J$(M !Zz$JJE!Z$>>E"ENE!%(J)?@--d-;#(	% a
I  /1L t||,Lq,/ I% **51PT5I5I%5P Jj*lM %-JzSV<W!+J$(M#"G|3	8U"G</'+Ie$,.'1'AL'AIe$$V !$&  /> DMq,/ 7$$Yu%567 I& 	66!":DffQi":Yt_"LLNQUUAFG	s'   D=K> BK> 'AK> >M
8MM
c                    | j                   | j                          g }t        | j                         D ]e  \  }}|j                  |      }| j                  |   \  }}}d|v r |di |j                         |k(  rI|j                  |j                  |f       g |j                  d        dj                  |D 	cg c]  }	|	d   	 c}	      | _	        d| _
        | j                  dk7  rd| _        yyc c}	w )	ac  
        Encodes all child objects into the contents for this object.

        This method is overridden because a Set needs to be encoded by
        removing defaulted fields and then sorting the fields by tag.

        :param force:
            Ensure all contents are in DER format instead of possibly using
            cached BER-encoded data
        Nr   rP   c                     | d   S r   r   )cts    r*   <lambda>z#Set._set_contents.<locals>.<lambda>  s
    1 r+   )r   r+   r
   r   )r,  r-  r   rc   r.  r!  r4   sortr  r  r   r   )
rL   r   child_tag_encodingsr   r4  child_encodingr   r0   rU  r  s
             r*   r8  zSet._set_contents  s     ==   " %dmm4 		DLE5"ZZeZ4N (,||E':$D$L(',',,..@&&		>'BC		D 	  %5 63F"GR2a5"GH==CDM   #Hs   >C5r   )r   r   r   r   rI   rG   r4   rb  r;   r-  r8  r   r+   r*   r  r    s1    
 FF
C J^6m^ r+   r  c                       e Zd ZdZdZddZy)SetOfz~
    Represents a set (unordered) of a single type of values from ASN.1 as a
    Python object with a list-like interface
    r  c                 
   | j                   | j                          g }| D ]#  }|j                  |j                  |             % dj	                  t        |            | _        d| _        | j                  dk7  rd| _        yy)aD  
        Encodes all child objects into the contents for this object.

        This method is overridden because a SetOf needs to be encoded by
        sorting the child encodings.

        :param force:
            Ensure all contents are in DER format instead of possibly using
            cached BER-encoded data
        Nr   r+   )	r,  r-  r!  rc   r  r1  r  r   r   )rL   r   child_encodingsr4  s       r*   r8  zSetOf._set_contents  s}     ==   " 	<E""5::E:#:;	< &"9:==CDM  r+   Nr   )r   r   r   r   r4   r8  r   r+   r*   r  r    s    
 C r+   r  c                       e Zd ZdZdZy)EmbeddedPdvz
    A sequence structure
       Nr  r   r+   r*   r  r         Cr+   r  c                       e Zd ZdZdZdZy)NumericStringzK
    Represents a numeric string from ASN.1 as a Python unicode string
       rQ  Nr#  r   r+   r*   r  r         CIr+   r  c                       e Zd ZdZdZdZy)PrintableStringzM
    Represents a printable string from ASN.1 as a Python unicode string
       rQ  Nr#  r   r+   r*   r  r    r  r+   r  c                       e Zd ZdZdZdZy)TeletexStringzK
    Represents a teletex string from ASN.1 as a Python unicode string
       teletexNr#  r   r+   r*   r  r    s     CIr+   r  c                       e Zd ZdZdZy)VideotexStringzI
    Represents a videotex string from ASN.1 as a Python byte string
       Nr  r   r+   r*   r  r    r  r+   r  c                       e Zd ZdZdZdZy)	IA5StringzH
    Represents an IA5 string from ASN.1 as a Python unicode string
       asciiNr#  r   r+   r*   r  r    r$  r+   r  c                   0    e Zd ZdZed        Zed        Zy)AbstractTimezK
    Represents a time from ASN.1 as a Python datetime.datetime object
    c           
         t        |       }| j                  j                  |      }|st        t	        d|t        |                   |j                         }d}|d   rt        j                  }nF|d   rA|d   dk(  rdnd}t        |t        t        |d         t        |d	   xs d
            z        }|d   rZt        t        |d         dt        |d         z        dz  }|d   |dz  }n
|d   |dz  }t        |j                  d            }nd
}t        |d         t        |d         t        |d         t        |d         t        |d   xs d
      t        |d   xs d
      ||dS )z
        The parsed datetime string.

        :raises:
            ValueError - when an invalid value is passed

        :return:
            A dict with the parsed values
        z:
                Error parsing %s to a %s
                Nzuludsign+r
   r   dhourdminuter   )hoursminutesfractionr  i@B minutei  second<   yearmonthdayhour)r  r  r  r  r  r  tzinfor  )r   _TIMESTRING_REr   rB   r   r   	groupdictr   utcr   r   r  r	   rD   limit_denominator)rL   stringmgroupstzsignfract
fract_usecs           r*   _parsed_timezAbstractTime._parsed_time  s    %%f-V $   &>BG_w3.1BD 	&/*F9-23) " B
 *F:&'c&,-- E
 h'!)U44Q78J J v')ve}%v'&*/a0&*/a0"	
 		
r+   c                     | j                   y| j                  G| j                  }|j                  dd      }| j	                  |      }|r|t        |      z  }|| _        | j                  S )aF  
        The native Python datatype representation of this value

        :return:
            A datetime.datetime object, asn1crypto.util.extended_datetime object or
            None. The datetime object is usually timezone aware. If it's naive, then
            it's in the sender's local time; see X.680 sect. 42.3
        Nr  r   )microseconds)rJ   r   r  r  _get_datetimer   )rL   r   r  r8   s       r*   r   zAbstractTime.nativeF  si     == <<&&Fzz*a0H&&v.E99 DL||r+   N)r   r   r   r   r   r  r   r   r+   r*   r  r    s0     =
 =
~  r+   r  c                   Z    e Zd ZdZdZ ej                  dej                        Zd Z	d Z
y)UTCTimez^
    Represents a UTC time from ASN.1 as a timezone aware Python datetime.datetime object
       a  
        ^
        # YYMMDD
        (?P<year>\d{2})
        (?P<month>\d{2})
        (?P<day>\d{2})

        # hhmm or hhmmss
        (?P<hour>\d{2})
        (?P<minute>\d{2})
        (?P<second>\d{2})?

        # Matches nothing, needed because GeneralizedTime uses this.
        (?P<fraction>)

        # Z or [-+]hhmm
        (?:
            (?P<zulu>Z)
            |
            (?:
                (?P<dsign>[-+])
                (?P<dhour>\d{2})
                (?P<dminute>\d{2})
            )
        )
        $
    c                 ^   t        |t              r|j                  st        d      |j	                  t
              }d|j                  cxk  rdk  st        d       t        d      |j                  d      }t        r|j                  d      }t        j                  | |       d| _        y)z
        Sets the value of the object

        :param value:
            A unicode string or a datetime.datetime object

        :raises:
            ValueError - when an invalid value is passed
        Must be timezone awarei  i  zMYear of the UTCTime is not in range [1950, 2049], use GeneralizedTime insteadz%y%m%d%H%M%SZr  N)r2   r   r  rB   
astimezoner   r  strftimerW   rX  rP  rH   r   r  s     r*   rH   zUTCTime.set  s     eX&<< !9:: $$\2E5::-- !pqq . !pqqNN?3EW-4' r+   c                 ^    |d   dk  r|dxx   dz  cc<   n|dxx   dz  cc<   t        di |S )z
        Create a datetime object from the parsed time.

        :return:
            An aware datetime.datetime object
        r  2   i  il  r   )r   rL   r   s     r*   r  zUTCTime._get_datetime  s:     &>B6Nd"N6Nd"N!&!!r+   Nr   r   r   r   r4   recompileXr  rH   r  r   r+   r*   r  r  c  s8     C  RZZ !4 
5N8<"r+   r  c                   Z    e Zd ZdZdZ ej                  dej                        Zd Z	d Z
y)GeneralizedTimez
    Represents a generalized time from ASN.1 as a Python datetime.datetime
    object or asn1crypto.util.extended_datetime object in UTC
       aO  
        ^
        # YYYYMMDD
        (?P<year>\d{4})
        (?P<month>\d{2})
        (?P<day>\d{2})

        # hh or hhmm or hhmmss
        (?P<hour>\d{2})
        (?:
            (?P<minute>\d{2})
            (?P<second>\d{2})?
        )?

        # Optional fraction; [.,]dddd (one or more decimals)
        # If Seconds are given, it's fractions of Seconds.
        # Else if Minutes are given, it's fractions of Minutes.
        # Else it's fractions of Hours.
        (?:
            [,.]
            (?P<fraction>\d+)
        )?

        # Optional timezone. If left out, the time is in local time.
        # Z or [-+]hh or [-+]hhmm
        (?:
            (?P<zulu>Z)
            |
            (?:
                (?P<dsign>[-+])
                (?P<dhour>\d{2})
                (?P<dminute>\d{2})?
            )
        )?
        $
    c                    t        |t        t        f      r|j                  st	        d      |j                  t              }|j                  r7dt        |j                        j                  d      j                  d      z   }nd}|j                  d      |z   dz   }t        r|j                  d      }t        j                  | |       d	| _        y	)
a  
        Sets the value of the object

        :param value:
            A unicode string, a datetime.datetime object or an
            asn1crypto.util.extended_datetime object

        :raises:
            ValueError - when an invalid value is passed
        r  r  r  r  rW  z%Y%m%d%H%M%SZr  N)r2   r   r   r  rB   r  r   microsecondstrzfillr  r  rW   rX  rP  rH   r   )rL   r8   r  s      r*   rH   zGeneralizedTime.set  s     eh(9:;<< !9:: $$\2E  U%6%6!7!=!=a!@!G!G!LLNN>2X=CEW-4' r+   c                 >    |d   dk(  rt        di |S t        di |S )z
        Create a datetime object from the parsed time.

        :return:
            A datetime.datetime object or asn1crypto.util.extended_datetime object.
            It may or may not be aware.
        r  r   r   )r   r   r  s     r*   r  zGeneralizedTime._get_datetime  s,     &>Q$.v..%f%%r+   Nr  r   r+   r*   r  r    s<    
 C  RZZ #!F 
G#NJB&r+   r  c                       e Zd ZdZdZdZy)GraphicStringzK
    Represents a graphic string from ASN.1 as a Python unicode string
       rQ  Nr#  r   r+   r*   r  r         CIr+   r  c                       e Zd ZdZdZdZy)VisibleStringzK
    Represents a visible string from ASN.1 as a Python unicode string
       rQ  Nr#  r   r+   r*   r  r  "  r  r+   r  c                       e Zd ZdZdZdZy)GeneralStringzK
    Represents a general string from ASN.1 as a Python unicode string
       rQ  Nr#  r   r+   r*   r  r  +  r  r+   r  c                       e Zd ZdZdZdZy)UniversalStringzM
    Represents a universal string from ASN.1 as a Python unicode string
       z	utf-32-beNr#  r   r+   r*   r  r  5       CIr+   r  c                       e Zd ZdZdZdZy)CharacterStringzM
    Represents a character string from ASN.1 as a Python unicode string
       rQ  Nr#  r   r+   r*   r  r  >  r  r+   r  c                       e Zd ZdZdZdZy)	BMPStringzG
    Represents a BMP string from ASN.1 as a Python unicode string
       z	utf-16-beNr#  r   r+   r*   r!  r!  H  r  r+   r!  c           
      P   t        | t        |      dt        |             |j                  r@t        | dt	        j
                  |j                  xs d      j                  d             |j                  duxr |j                  duxr |j                  du}|r>t        j                  |j                        }t        j                  |j                        }|j                  ^|j                  D ],  \  }}t        | dt        j                  |      d|d       . |rst        | d	d
d
|j                         nR|j                  r$|rDt        | dd
d|j                  d       n"|r t        | dd
d|j                         |j                  r@t        | dt	        j
                  |j                  xs d      j                  d             t        | dt	        j
                  |j                   xs d      j                  d             y)a7  
    Prints out basic information about an Asn1Value object. Extracted for reuse
    among different classes that customize the debug information.

    :param prefix:
        A unicode string of spaces to prefix output line with

    :param self:
        The object to print the debugging information about
    r2  z  Header: 0xr+   rf   Nz    z tag z (explicitly tagged)z      r`   z (implicitly tagged)z  Trailer: 0xz
  Data: 0x)r   r   rb   r   binasciihexlifyrX  rI   rG   r4   r~  r{   rE   r<   r=   r   rJ   )r   rL   
has_headermethod_name
class_namerG   r4   s          r*   r   r   Q  s    
vy4
AB||FH,<,<T\\=PS,Q,X,XY`,abcD(]T[[-D]Y]I]J,00=*..t{{;
}} == 	KFC )--f5		 ZRS	fkS]_c_g_ghi	fk:txxPQ}}VX-=-=dmm>Rs-S-Z-Z[b-cde	fh&6&6t}}7K&L&S&ST[&\
]^r+   c                     d| v rT| d   dk(  r| j                  dd      | d   f| d<   n"| d   dk(  r| j                  dd      | d   f| d<   | d= | d= d| v r| d= yyy)z
    Converts old-style "tag_type" and "tag" params to "explicit" and "implicit"

    :param params:
        A dict of parameters to convert from tag_type/tag to explicit/implicit
    rN   r<   classr"   r4   r=   N)r{   )r   s    r*   r   r     s     V*+"(**Wa"8&-!HF:J:-"(**Wa"8&-!HF::5Mfw  r+   c                 f   t        |       d}d|vr| j                  dur^d}n[t        |d   t              r	|d   \  }}n|d   }d}| j                  du rd}n'| j                  t
        |   k7  s| j                  |k7  rd}|j                  d      | j                  k7  rd}|r| j                  |      S | S )z
    Checks if a value is properly tagged based on the spec, and re/untags as
    necessary

    :param value:
        An Asn1Value object

    :param params:
        A dict of spec params

    :return:
        An Asn1Value that is properly tagged
    Fr=   Tr    r<   )
r   r=   r2   r   rG   rF   r4   r{   r<   r}   )r8   r   r}   rG   r4   s        r*   r   r     s     #6*E>>&EfZ(%0 ,KFC$CF>>U"E\\26::eii3>NEzz*/{{6""Lr+   c                 r   |y|j                   }|j                  }t        |        d| v r$t        | d   t              r	| d   \  }}n/d}| d   }n'd| v r#t        | d   t              r	| d   \  }}nd}| d   }|t        |t
              s	t        |   }| j                  d|      }| j                  d|      }||fS )aP  
    Builds a 2-element tuple used to identify fields by grabbing the class_
    and tag from an Asn1Value class and the params dict being passed to it

    :param params:
        A dict of params to pass to spec

    :param spec:
        An Asn1Value class

    :return:
        A 2-element integer tuple in the form (class_, tag)
    r   r<   r"   r=   rG   r4   )rG   r4   r   r2   r   r   rF   r{   )r   r0   required_classrequired_tags       r*   r   r     s      |[[N88L"6*VfZ(%0+1*+=(NLN!*-L	v	fZ(%0+1*+=(NLN!*-L!*^Y*O.~>ZZ.9N::e\2LL))r+   c                     | s|syt        t        t        t        | dj                  |                        }t	        |      |k7  r$t        dj                  t	        |      |            |S )z
    Format value as a tuple of 1s and 0s.

    :param value:
        A non-negative integer to format

    :param bits:
        Number of bits in the output

    :return:
        A tuple of 1s and 0s with bits members.
    r   z0{0}bzResult too large: {0} > {1})r   r  r  ry  rD   rB   )r8   r|  results      r*   rz  rz    s[     3sF5'..*>?@AF
6{d6==c&k4PQQMr+   r  r  r  rv  rt  r  r  r  r"  r'  r*  r  r  r  )r  r  r  r  r  r  r  r  r  r  r"  c	                    |t        |       |t        S d}	|a|xr d|v }
|
sx|j                  s|rid|v rd|r	 |di |}n |       }|j                  }t        |      }| }|}|}|}|}|xs d}|D ]  \  }}||k7  rGt	        t        dt        |      t        j                  |      t        j                  ||                  |dk7  rGt	        t        dt        |      t        j                  d      t        j                  ||                  ||k7  r t	        t        d	t        |      ||            t        |t        |            \  }}|\  }}}}}}t        |t              r||z  }||z   } t        |dd
id}||_        ||_        ||_        d
}	n|r |dd|i|}n	 ||      }|t"        u rnt        |t              r<|j%                  | ||       	 ||j&                  z   |_        d}|j)                          n| |j.                  k7  rQt	        t        dt        |      t        j                  |j.                        t        j                  | |                   ||j0                  k7  r|dk(  xr |j0                  dk(  xr |dk(  }|rt        |t2              sQt	        t        dt        |      t        j                  |j0                        t        j                  ||                  ||_        d
|_        ||j6                  k7  rt        |j8                  t:              r||j8                  v }n||j8                  k(  }|skt	        t        dt        |      |j6                  |            |rd|v rt=        dd|i|}|j                  }|}|}|xs d}t        |      D ]0  \  }}t        |t        |            \  }}|\  }}}}}}||z  }||z   }2 t        |dd
id}||j                  z   |_        |xj                   |xs dz  c_        ||_        d
}	n|t>        vr=t	        t        dt        j                  |       t        j                  |      |            t>        |   } |||       }|dk(  xr |j0                  dk(  xr |dk(  }|rt        |t2              rd
|_        ||_        |	s||_        |xs d|_        d|_         |r	 |j)                  |       |S |S # t        t*        f$ r=}|j,                  dd }|j,                  d   dt        |      z  z   f|z   |_        |d}~ww xY w# t        t*        f$ r=}|j,                  dd }|j,                  d   dt        |      z  z   f|z   |_        |d}~ww xY w)a  
    Builds an Asn1Value object generically, or using a spec with optional params

    :param class_:
        An integer representing the ASN.1 class

    :param method:
        An integer representing the ASN.1 method

    :param tag:
        An integer representing the ASN.1 tag

    :param header:
        A byte string of the ASN.1 header (class, method, tag, length)

    :param contents:
        A byte string of the ASN.1 value

    :param trailer:
        A byte string of any ASN.1 trailer (only used by indefinite length encodings)

    :param spec:
        A class derived from Asn1Value that defines what class_ and tag the
        value should have, and the semantics of the encoded value. The
        return value will be of this type. If omitted, the encoded value
        will be decoded using the standard universal tag based on the
        encoded tag number.

    :param spec_params:
        A dict of params to pass to the spec object

    :param nested_spec:
        For certain Asn1Value classes (such as OctetString and BitString), the
        contents can be further parsed and interpreted as another Asn1Value.
        This parameter controls the spec for that sub-parsing.

    :return:
        An object of the type spec, or if not specified, a child of Asn1Value
    NFrM   r<   r+   z
                        Error parsing %s - explicitly-tagged class should have been
                        %s, but %s was found
                        r
   z
                        Error parsing %s - explicitly-tagged method should have
                        been %s, but %s was found
                        z
                        Error parsing %s - explicitly-tagged tag should have been
                        %s, but %s was found
                        Tr   rJ   r   r   r   z
                        Error parsing %s - class should have been %s, but %s was
                        found
                        s     zy
                            Error parsing %s - method should have been %s, but %s was found
                            zv
                            Error parsing %s - tag should have been %s, but %s was found
                            zO
                Unknown element - %s class, %s method, tag %s
                )rJ   rG   r   )!r   r0  r<   reversedrB   r   r   rE   r{   r~  r   rD   r2   r   rG  r   r   r   r  rJ   r   r3   rK   rG   rI   r   r   r4   r   r   r'   _UNIVERSAL_SPECSr   )rG   rI   r4   r   rJ   trailerr0   r1   nested_spec
header_setrM   r8   original_explicitexplicit_infoparsed_classparsed_method
parsed_tagto_parseexplicit_headerexplicit_trailerexpected_classexpected_tagr   r9   parsed_headerparsed_trailerrR   rK   	ber_indef
is_bad_tagoriginal_values                                  r*   rG  rG     s   R &{3~J  "Bm{&B+*P[B[+{+ %$%67M!L"MJH$O&~#0= $I,>1$V "%(-11.A-11,M&   !A%$V "%(.2215.22=-P&   -$V "%($"&   !3x=9acg`mZR`!%0#}4O'58H'H$I$IL Dt-9NOE+EM-EN.ENJ>h>+>h/s{E6*vsH5%+enn%<EN FKKM U\\)$V "%(-11%,,?-11&&A&   U\\) !'! \0A \gQ\F\I$Jum,L(  &e,266u||D266vvF*   (.,0)%))#!%..%8%(ENN%:
%(ENN%:
%(  &e,!II*   
{2"DHDD*33 ">c,45F,G 	A(NLXs8}5GD!?C<Aq!]Hn},O-0@@		A
 4mT5JK.'.S(*

 &&V &))&1&**62    $hv6aKPELLA$5P'[:P	E=9 $E C EM	KK$ L5LQ #I. 66!":DffQi*BYuEU*UUWZ^^AFGF I& 	66!":DffQi":Yu=M"MMORVVAFG	s0   "&S0 T? 0T<?8T77T<?V8VVc                     t        |       }t        | ||      \  }}|r|||z   k7  r||z   |z
  }t        d|z        t        |||d|fS )a  
    Parses a byte string generically, or using a spec with optional params

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

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

    :param spec:
        A class derived from Asn1Value that defines what class_ and tag the
        value should have, and the semantics of the encoded value. The
        return value will be of this type. If omitted, the encoded value
        will be decoded using the standard universal tag based on the
        encoded tag number.

    :param spec_params:
        A dict of params to pass to the spec object

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

    :return:
        A 2-element tuple:
         - 0: An object of the type spec, or if not specified, a child of Asn1Value
         - 1: An integer indicating how many bytes were consumed
    r  r   )rD   r   rB   rG  )	r)   r   r0   r1   r&   encoded_lenr   new_pointerr%  s	            r*   r5   r5   	  se    < l#K|['BD++;!66+k9OR]]^^Dt={KKr+   r   rN  )r   NNF)nr   
__future__r   r   r   r   r   r   	fractionsr	   r$  ro   r  r  sysrW  r   _errorsr   _ordereddictr   _typesr   r   r   r   r   parserr   r   utilr   r   r   r   r   r   version_info	cStringIOr   r   xranger  rW   ioregisterrE   rF   r~  r  r  r@   r(   objectr'   r   r   r   r   r0  r   r   r  rA  rP  r]  rh  rr  r  r  r  r  r  r  r  r  r  r  r  r  r  r!  r&  r)  r@  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r!  r   r   r   r   rz  r3  rG  r5   r   r+   r*   <module>rW     s  ,\ S R (     	 
   % D D ( j jt-ED D     	  	    "**%
& 37l_7 _7D* *6)v )XN.F N.b39 3l vS1) S1lQ-Y Q-h
^$V ^$B	|+	 |+~N"]I N"b2i 2jNi Nbi! i!X|!=(Ix |~O!]Hi O!d>(-9 >BK -9 K \N") N"bo$-9 o$d1!0 1!h9 >^y( ^By  9 A AH " z$y z$zD$ D$Nw ( w t J  B( N n N [  _> _DS"l S"l\&l \&~N N N n n  ,_^ &%P**Z0ww y {	
 t   z t 
  
     !" #$ 	9 @fR#Lr+   