o
    5hI                     @   s   d dl Z d dlmZmZmZ d dlmZmZ g dZdddZ	G dd	 d	e
ZG d
d de
ZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZdS )    N)byte_stringbchrbord)long_to_bytesbytes_to_long)		DerObject
DerInteger
DerBooleanDerOctetStringDerNullDerSequenceDerObjectIdDerBitStringDerSetOfFc                 C   s4   d}z| | }W n
 t y   Y dS w | p| dkS )Nr   F)	TypeError)xonly_non_negativetest r   d/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/Crypto/Util/asn1.py
_is_number(   s   r   c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )BytesIO_EOFzeThis class differs from BytesIO in that a ValueError exception is
    raised whenever EOF is reached.c                 C   s   || _ d| _d | _d S Nr   )_buffer_index	_bookmark)selfinitial_bytesr   r   r   __init__5   s   
zBytesIO_EOF.__init__c                 C   s   | j | _d S N)r   r   r   r   r   r   set_bookmark:      zBytesIO_EOF.set_bookmarkc                 C   s    | j d usJ | j| j | j S r   )r   r   r   r    r   r   r   data_since_bookmark=   s   zBytesIO_EOF.data_since_bookmarkc                 C   s   t | j| j S r   )lenr   r   r    r   r   r   remaining_dataA      zBytesIO_EOF.remaining_datac                 C   sH   | j | }|t| jkrtd|t| jf | j| j | }|| _ |S )Nz@Not enough data for DER decoding: expected %d bytes and found %d)r   r$   r   
ValueError)r   length	new_indexresultr   r   r   readD   s   
zBytesIO_EOF.readc                 C   s   t | dd S )N   r   )r   r+   r    r   r   r   	read_byteM      zBytesIO_EOF.read_byteN)
__name__
__module____qualname____doc__r   r!   r#   r%   r+   r-   r   r   r   r   r   1   s    	r   c                   @   sT   e Zd ZdZ		dddZdd Zed	d
 Zdd Zdd Z	dddZ
dd ZdS )r   zpBase class for defining a single DER object.

        This class should never be directly instantiated.
        N    Fc                 C   s   |du r	d| _ dS | |}|| _|rdnd}d||fvr!td|dur1d|B | |B | _ dS |durDd| |B | _ ||B | _dS ||B | _ dS )a  Initialize the DER object according to a specific ASN.1 type.

                :Parameters:
                  asn1Id : integer or byte
                    The universal DER tag number for this object
                    (e.g. 0x10 for a SEQUENCE).
                    If None, the tag is not known yet.

                  payload : byte string
                    The initial payload of the object (that it,
                    the content octets).
                    If not specified, the payload is empty.

                  implicit : integer or byte
                    The IMPLICIT tag number (< 0x1F) to use for the encoded object.
                    It overrides the universal tag *asn1Id*.
                    It cannot be combined with the ``explicit`` parameter.
                    By default, there is no IMPLICIT tag.

                  constructed : bool
                    True when the ASN.1 type is *constructed*.
                    False when it is *primitive* (default).

                  explicit : integer or byte
                    The EXPLICIT tag number (< 0x1F) to use for the encoded object.
                    It cannot be combined with the ``implicit`` parameter.
                    By default, there is no EXPLICIT tag.
                N    r   z1Explicit and implicit tags are mutually exclusive      )
_tag_octet_convertTagpayloadr'   _inner_tag_octet)r   asn1Idr9   implicitconstructedexplicitconstructed_bitr   r   r   r   W   s   
zDerObject.__init__c                 C   sP   t |st|dkrt|d }t |r"d|  kr!dk s&td td|S )zCheck if *tag* is a real DER tag (5 bits).
                Convert it from a character to number if necessary.
                r,   r      zWrong DER tag)r   r$   r   r'   )r   tagr   r   r   r8      s   zDerObject._convertTagc                 C   s,   | dkrt | }tt|d | S t| S )zXBuild length octets according to BER/DER
                definite form.
                   r5   )r   r   r$   )r(   encodingr   r   r   _definite_form   s   zDerObject._definite_formc                 C   sL   | j }t| drt| j| t| j  | j  }t| j| t| | S )z?Return this DER element, fully encoded as a binary byte string.r:   )r9   hasattrr   r:   rD   r$   r7   )r   output_payloadr   r   r   encode   s   
zDerObject.encodec                 C   sR   |  }|dkr'||d@ }t|d dkrtdt|}|dkr'td|S )z%Decode DER length octets from a file.rB   r   z$Invalid DER: length has leading zeroz5Invalid DER: length in long form but smaller than 128)r-   r+   r   r'   r   )r   sr(   encoded_lengthr   r   r   
_decodeLen   s   zDerObject._decodeLenc                 C   s<   t |stdt|}| || | dkrtd| S )a  Decode a complete DER element, and re-initializes this
                object with it.

                Args:
                  der_encoded (byte string): A complete DER element.

                Raises:
                  ValueError: in case of parsing errors.
                zInput is not a byte stringr   -Unexpected extra data after the DER structure)r   r'   r   _decodeFromStreamr%   )r   der_encodedstrictrH   r   r   r   decode   s   zDerObject.decodec                 C   s   |  }| jdur|| jkrtdn|| _| |}||| _t| drMt| j}|  }|| jkr8td| |}||| _|	 dkrOtddS dS )z*Decode a complete DER element from a file.NzUnexpected DER tagr:   zUnexpected internal DER tagr   rK   )
r-   r7   r'   rJ   r+   r9   rE   r   r:   r%   )r   rH   rN   idOctetr(   pinner_octetr   r   r   rL      s&   






	zDerObject._decodeFromStream)Nr3   NFNF)r/   r0   r1   r2   r   r8   staticmethodrD   rG   rJ   rO   rL   r   r   r   r   r   Q   s    
F
	
r   c                   @   4   e Zd ZdZdddZdd Zdd	d
Zdd ZdS )r   a  Class to model a DER INTEGER.

        An example of encoding is::

          >>> from Crypto.Util.asn1 import DerInteger
          >>> from binascii import hexlify, unhexlify
          >>> int_der = DerInteger(9)
          >>> print hexlify(int_der.encode())

        which will show ``020109``, the DER encoding of 9.

        And for decoding::

          >>> s = unhexlify(b'020109')
          >>> try:
          >>>   int_der = DerInteger()
          >>>   int_der.decode(s)
          >>>   print int_der.value
          >>> except ValueError:
          >>>   print "Not a valid DER INTEGER"

        the output will be ``9``.

        :ivar value: The integer value
        :vartype value: integer
        r   Nc                 C      t | dd|d| || _dS )aU  Initialize the DER object as an INTEGER.

                :Parameters:
                  value : integer
                    The value of the integer.

                  implicit : integer
                    The IMPLICIT tag to use for the encoded object.
                    It overrides the universal tag for INTEGER (2).
                   r3   FNr   r   valuer   rY   r<   r>   r   r   r   r   #  s   
zDerInteger.__init__c                 C   s|   | j }d| _	 tt|d@ | j | _d|  krdkr'n ntd| j | _d|  kr1dkr4n nn|dL }qt| S )zIReturn the DER INTEGER, fully encoded as a
                binary string.r3   T   r5   r   i   )rY   r9   r   intr   rG   )r   numberr   r   r   rG   3  s   
zDerInteger.encodeFc                 C   s   t j| ||dS )a  Decode a DER-encoded INTEGER, and re-initializes this
                object with it.

                Args:
                  der_encoded (byte string): A complete INTEGER DER element.

                Raises:
                  ValueError: in case of parsing errors.
                rN   r   rO   r   rM   rN   r   r   r   rO   B  s   zDerInteger.decodec                 C   s   t | || |r.t| jdkrtdt| jdkr.td| jdd d dk r.tdd| _d}| jD ]}|  jd	9  _|  jt|7  _|d
K }q6| jrbt| jd d@ rd|  j|8  _dS dS dS )z*Decode a complete DER INTEGER from a file.r   z/Invalid encoding for DER INTEGER: empty payloadrW   z>HNr5   z.Invalid encoding for DER INTEGER: leading zeror,      r\   )	r   rL   r$   r9   r'   structunpackrY   r   )r   rH   rN   bitsir   r   r   rL   O  s   ,

zDerInteger._decodeFromStream)r   NNrS   r/   r0   r1   r2   r   rG   rO   rL   r   r   r   r   r     s    

r   c                   @   s4   e Zd ZdZdddZdd Zddd	Zd
d ZdS )r	   aR  Class to model a DER-encoded BOOLEAN.

    An example of encoding is::

    >>> from Crypto.Util.asn1 import DerBoolean
    >>> bool_der = DerBoolean(True)
    >>> print(bool_der.encode().hex())

    which will show ``0101ff``, the DER encoding of True.

    And for decoding::

    >>> s = bytes.fromhex('0101ff')
    >>> try:
    >>>   bool_der = DerBoolean()
    >>>   bool_der.decode(s)
    >>>   print(bool_der.value)
    >>> except ValueError:
    >>>   print "Not a valid DER BOOLEAN"

    the output will be ``True``.

    :ivar value: The boolean value
    :vartype value: boolean
    FNc                 C   rV   )a  Initialize the DER object as a BOOLEAN.

        Args:
          value (boolean):
            The value of the boolean. Default is False.

          implicit (integer or byte):
            The IMPLICIT tag number (< 0x1F) to use for the encoded object.
            It overrides the universal tag for BOOLEAN (1).
            It cannot be combined with the ``explicit`` parameter.
            By default, there is no IMPLICIT tag.

          explicit (integer or byte):
            The EXPLICIT tag number (< 0x1F) to use for the encoded object.
            It cannot be combined with the ``implicit`` parameter.
            By default, there is no EXPLICIT tag.
        r,   r3   FNrX   rZ   r   r   r   r     s   
zDerBoolean.__init__c                 C   s   | j rdnd| _t| S )z9Return the DER BOOLEAN, fully encoded as a binary string.       rY   r9   r   rG   r    r   r   r   rG     s   
zDerBoolean.encodec                 C      t | ||S )zDecode a DER-encoded BOOLEAN, and re-initializes this object with it.

        Args:
            der_encoded (byte string): A DER-encoded BOOLEAN.

        Raises:
            ValueError: in case of parsing errors.
        r`   ra   r   r   r   rO     s   
zDerBoolean.decodec                 C   sd   t | || t| jdkrtdt| jd dkr d| _dS t| jd dkr.d| _dS td)	z)Decode a DER-encoded BOOLEAN from a file.r,   z7Invalid encoding for DER BOOLEAN: payload is not 1 byter   Fr[   TzInvalid payload for DER BOOLEANN)r   rL   r$   r9   r'   r   rY   r   rH   rN   r   r   r   rL     s   

zDerBoolean._decodeFromStream)FNNrS   rg   r   r   r   r   r	   f  s    

r	   c                   @   s   e Zd ZdZd%ddZdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zd&ddZd&ddZdd Zd'd!d"Zd#d$ ZdS )(r   a  Class to model a DER SEQUENCE.

        This object behaves like a dynamic Python sequence.

        Sub-elements that are INTEGERs behave like Python integers.

        Any other sub-element is a binary string encoded as a complete DER
        sub-element (TLV).

        An example of encoding is:

          >>> from Crypto.Util.asn1 import DerSequence, DerInteger
          >>> from binascii import hexlify, unhexlify
          >>> obj_der = unhexlify('070102')
          >>> seq_der = DerSequence([4])
          >>> seq_der.append(9)
          >>> seq_der.append(obj_der.encode())
          >>> print hexlify(seq_der.encode())

        which will show ``3009020104020109070102``, the DER encoding of the
        sequence containing ``4``, ``9``, and the object with payload ``02``.

        For decoding:

          >>> s = unhexlify(b'3009020104020109070102')
          >>> try:
          >>>   seq_der = DerSequence()
          >>>   seq_der.decode(s)
          >>>   print len(seq_der)
          >>>   print seq_der[0]
          >>>   print seq_der[:]
          >>> except ValueError:
          >>>   print "Not a valid DER SEQUENCE"

        the output will be::

          3
          4
          [4, 9, b'']

        Nc                 C   s0   t | dd|d| |du rg | _dS || _dS )aC  Initialize the DER object as a SEQUENCE.

                :Parameters:
                  startSeq : Python sequence
                    A sequence whose element are either integers or
                    other DER objects.

                  implicit : integer or byte
                    The IMPLICIT tag number (< 0x1F) to use for the encoded object.
                    It overrides the universal tag for SEQUENCE (16).
                    It cannot be combined with the ``explicit`` parameter.
                    By default, there is no IMPLICIT tag.

                  explicit : integer or byte
                    The EXPLICIT tag number (< 0x1F) to use for the encoded object.
                    It cannot be combined with the ``implicit`` parameter.
                    By default, there is no EXPLICIT tag.
                   r3   TN)r   r   _seq)r   startSeqr<   r>   r   r   r   r     s   

zDerSequence.__init__c                 C   s   | j |= d S r   rn   r   nr   r   r   __delitem__   r"   zDerSequence.__delitem__c                 C   
   | j | S r   rp   rq   r   r   r   __getitem__     
zDerSequence.__getitem__c                 C   s   || j |< d S r   rp   )r   keyrY   r   r   r   __setitem__  s   zDerSequence.__setitem__c                 C   s   || j ||< d S r   rp   )r   rf   jsequencer   r   r   __setslice__	  r.   zDerSequence.__setslice__c                 C   s   | j ||= d S r   rp   r   rf   ry   r   r   r   __delslice__  r&   zDerSequence.__delslice__c                 C   s   | j td|td| S r   )rn   maxr|   r   r   r   __getslice__  s   zDerSequence.__getslice__c                 C   
   t | jS r   r$   rn   r    r   r   r   __len__  rv   zDerSequence.__len__c                 C      | j | | S r   rn   appendr   itemr   r   r   __iadd__     zDerSequence.__iadd__c                 C   r   r   r   r   r   r   r   r     r   zDerSequence.appendc                 C   s   | j || | S r   )rn   insert)r   indexr   r   r   r   r     s   zDerSequence.insertTc                    s    fdd| j D }t|S )zReturn the number of items in this sequence that are
                integers.

                Args:
                  only_non_negative (boolean):
                    If ``True``, negative integers are not counted in.
                c                    s   g | ]	}t | r|qS r   )r   .0r   r   r   r   
<listcomp>*  s    z'DerSequence.hasInts.<locals>.<listcomp>)rn   r$   )r   r   itemsr   r   r   hasInts!  s   	zDerSequence.hasIntsc                 C   s   | j o| |t| j kS )a  Return ``True`` if all items in this sequence are integers
                or non-negative integers.

                This function returns False is the sequence is empty,
                or at least one member is not an integer.

                Args:
                  only_non_negative (boolean):
                    If ``True``, the presence of negative integers
                    causes the method to return ``False``.)rn   r   r$   )r   r   r   r   r   hasOnlyInts-  s   zDerSequence.hasOnlyIntsc                 C   sf   d| _ | jD ]'}t|r|  j |7  _ qt|r$|  j t| 7  _ q|  j | 7  _ qt| S )zReturn this DER SEQUENCE, fully encoded as a
                binary string.

                Raises:
                  ValueError: if some elements in the sequence are neither integers
                              nor byte strings.
                r3   )r9   rn   r   r   r   rG   r   r   r   r   r   rG   :  s   

zDerSequence.encodeFc                 C   s.   || _ tj| ||d}|r|  std|S )a9  Decode a complete DER SEQUENCE, and re-initializes this
                object with it.

                Args:
                  der_encoded (byte string):
                    A complete SEQUENCE DER element.
                  nr_elements (None or integer or list of integers):
                    The number of members the SEQUENCE can have
                  only_ints_expected (boolean):
                    Whether the SEQUENCE is expected to contain only integers.
                  strict (boolean):
                    Whether decoding must check for strict DER compliancy.

                Raises:
                  ValueError: in case of parsing errors.

                DER INTEGERs are decoded into Python integers. Any other DER
                element is not decoded. Its validity is not checked.
                r_   zSome members are not INTEGERs)_nr_elementsr   rO   r   r'   )r   rM   rN   nr_elementsonly_ints_expectedr*   r   r   r   rO   L  s
   zDerSequence.decodec                 C   s   g | _ t| || t| j}| dkrK|  t }||| |jdkr0| j |	  nt
 }|	 }|j||d | j |j | dksd}| jdurnz
t| j | jv }W n tym   t| j | jk}Y nw |sytdt| j  dS )z+Decode a complete DER SEQUENCE from a file.r   rW   r_   TNz1Unexpected number of members (%d) in the sequence)rn   r   rL   r   r9   r%   r!   r7   r   r#   r   rO   rY   r   r$   r   r'   )r   rH   rN   rQ   derderIntdataokr   r   r   rL   i  s4   


zDerSequence._decodeFromStream)NNN)T)FNF)r/   r0   r1   r2   r   rs   ru   rx   r{   r}   r   r   r   r   r   r   r   rG   rO   rL   r   r   r   r   r     s$    
*


r   c                   @   s   e Zd ZdZdddZdS )r
   a  Class to model a DER OCTET STRING.

    An example of encoding is:

    >>> from Crypto.Util.asn1 import DerOctetString
    >>> from binascii import hexlify, unhexlify
    >>> os_der = DerOctetString(b'\xaa')
    >>> os_der.payload += b'\xbb'
    >>> print hexlify(os_der.encode())

    which will show ``0402aabb``, the DER encoding for the byte string
    ``b'\xAA\xBB'``.

    For decoding:

    >>> s = unhexlify(b'0402aabb')
    >>> try:
    >>>   os_der = DerOctetString()
    >>>   os_der.decode(s)
    >>>   print hexlify(os_der.payload)
    >>> except ValueError:
    >>>   print "Not a valid DER OCTET STRING"

    the output will be ``aabb``.

    :ivar payload: The content of the string
    :vartype payload: byte string
    r3   Nc                 C   s   t | d||d dS )ah  Initialize the DER object as an OCTET STRING.

        :Parameters:
          value : byte string
            The initial payload of the object.
            If not specified, the payload is empty.

          implicit : integer
            The IMPLICIT tag to use for the encoded object.
            It overrides the universal tag for OCTET STRING (4).
           FNr   r   )r   rY   r<   r   r   r   r     s   zDerOctetString.__init__)r3   Nr/   r0   r1   r2   r   r   r   r   r   r
     s    r
   c                   @   s   e Zd ZdZdd ZdS )r   z"Class to model a DER NULL element.c                 C   s   t | dddd dS )z$Initialize the DER object as a NULL.   r3   NFr   r    r   r   r   r     s   zDerNull.__init__Nr   r   r   r   r   r     s    r   c                   @   rU   )r   a(  Class to model a DER OBJECT ID.

    An example of encoding is:

    >>> from Crypto.Util.asn1 import DerObjectId
    >>> from binascii import hexlify, unhexlify
    >>> oid_der = DerObjectId("1.2")
    >>> oid_der.value += ".840.113549.1.1.1"
    >>> print hexlify(oid_der.encode())

    which will show ``06092a864886f70d010101``, the DER encoding for the
    RSA Object Identifier ``1.2.840.113549.1.1.1``.

    For decoding:

    >>> s = unhexlify(b'06092a864886f70d010101')
    >>> try:
    >>>   oid_der = DerObjectId()
    >>>   oid_der.decode(s)
    >>>   print oid_der.value
    >>> except ValueError:
    >>>   print "Not a valid DER OBJECT ID"

    the output will be ``1.2.840.113549.1.1.1``.

    :ivar value: The Object ID (OID), a dot separated list of integers
    :vartype value: string
     Nc                 C   rV   )a  Initialize the DER object as an OBJECT ID.

        :Parameters:
          value : string
            The initial Object Identifier (e.g. "1.2.0.0.6.2").
          implicit : integer
            The IMPLICIT tag to use for the encoded object.
            It overrides the universal tag for OBJECT ID (6).
          explicit : integer
            The EXPLICIT tag to use for the encoded object.
           r3   FNrX   rZ   r   r   r   r     s   
zDerObjectId.__init__c                 C   s   dd | j dD }t|dk rtd|d dkrtd|d dk r/|d d	kr/td
d|d  |d  g|dd  }g }t|D ]}||d@  |dL }|rd||d@ dB  |dL }|sUqFddd t|D | _t	| S )zCReturn the DER OBJECT ID, fully encoded as a
        binary string.c                 S      g | ]}t |qS r   )r]   r   r   r   r   r         z&DerObjectId.encode.<locals>.<listcomp>.rW   z$Not a valid Object Identifier stringr   z!First component must be 0, 1 or 2r,   '   z#Second component must be 39 at most(   NrB      r5   r3   c                 S   r   r   )r   r   r   r   r   r     r   )
rY   splitr$   r'   reversedr   joinr9   r   rG   )r   compssubcompsrC   vr   r   r   rG     s&   "
zDerObjectId.encodeFc                 C   rk   )ab  Decode a complete DER OBJECT ID, and re-initializes this
        object with it.

        Args:
            der_encoded (byte string):
                A complete DER OBJECT ID.
            strict (boolean):
                Whether decoding must check for strict DER compliancy.

        Raises:
            ValueError: in case of parsing errors.
        r`   ra   r   r   r   rO     s   zDerObjectId.decodec                 C   s   t | || t| j}g }d}| r/| }|d> |d@  }|d@ s+|| d}| st|dkr9td|d dk rJd|d g|dd< n|d d	k r]d|d d g|dd< nd
|d d	 g|dd< d	dd |D | _
dS )z,Decode a complete DER OBJECT ID from a file.r   r   rB   r5   zEmpty payloadr   Nr,   P   rW   r   c                 S   r   r   )strr   r   r   r   r   7  r   z1DerObjectId._decodeFromStream.<locals>.<listcomp>)r   rL   r   r9   r%   r-   r   r$   r'   r   rY   )r   rH   rN   rQ   r   r   cr   r   r   rL     s&   

zDerObjectId._decodeFromStream)r   NNrS   rg   r   r   r   r   r     s    

r   c                   @   rU   )r   a  Class to model a DER BIT STRING.

    An example of encoding is:

    >>> from Crypto.Util.asn1 import DerBitString
    >>> bs_der = DerBitString(b'\xAA')
    >>> bs_der.value += b'\xBB'
    >>> print(bs_der.encode().hex())

    which will show ``030300aabb``, the DER encoding for the bit string
    ``b'\xAA\xBB'``.

    For decoding:

    >>> s = bytes.fromhex('030300aabb')
    >>> try:
    >>>   bs_der = DerBitString()
    >>>   bs_der.decode(s)
    >>>   print(bs_der.value.hex())
    >>> except ValueError:
    >>>   print "Not a valid DER BIT STRING"

    the output will be ``aabb``.

    :ivar value: The content of the string
    :vartype value: byte string
    r3   Nc                 C   s6   t | dd|d| t|t r| | _dS || _dS )a  Initialize the DER object as a BIT STRING.

        :Parameters:
          value : byte string or DER object
            The initial, packed bit string.
            If not specified, the bit string is empty.
          implicit : integer
            The IMPLICIT tag to use for the encoded object.
            It overrides the universal tag for BIT STRING (3).
          explicit : integer
            The EXPLICIT tag to use for the encoded object.
           r3   FN)r   r   
isinstancerG   rY   rZ   r   r   r   r   W  s   

zDerBitString.__init__c                 C   s   d| j  | _t| S )zBReturn the DER BIT STRING, fully encoded as a
        byte string.ri   rj   r    r   r   r   rG   l  s   
zDerBitString.encodeFc                 C   rk   )aT  Decode a complete DER BIT STRING, and re-initializes this
        object with it.

        Args:
            der_encoded (byte string): a complete DER BIT STRING.
            strict (boolean):
                Whether decoding must check for strict DER compliancy.

        Raises:
            ValueError: in case of parsing errors.
        r`   ra   r   r   r   rO   t  s   zDerBitString.decodec                 C   sR   t | || | jrt| jd dkrtdd| _| jr'| jdd | _dS dS )z1Decode a complete DER BIT STRING DER from a file.r   zNot a valid BIT STRINGr3   r,   N)r   rL   r9   r   r'   rY   rl   r   r   r   rL     s   zDerBitString._decodeFromStream)r3   NNrS   rg   r   r   r   r   r   :  s    

r   c                   @   sT   e Zd ZdZdddZdd Zdd Zd	d
 Zdd ZdddZ	dd Z
dd ZdS )r   a  Class to model a DER SET OF.

    An example of encoding is:

    >>> from Crypto.Util.asn1 import DerBitString
    >>> from binascii import hexlify, unhexlify
    >>> so_der = DerSetOf([4,5])
    >>> so_der.add(6)
    >>> print hexlify(so_der.encode())

    which will show ``3109020104020105020106``, the DER encoding
    of a SET OF with items 4,5, and 6.

    For decoding:

    >>> s = unhexlify(b'3109020104020105020106')
    >>> try:
    >>>   so_der = DerSetOf()
    >>>   so_der.decode(s)
    >>>   print [x for x in so_der]
    >>> except ValueError:
    >>>   print "Not a valid DER SET OF"

    the output will be ``[4, 5, 6]``.
    Nc                 C   s>   t | dd|d g | _d| _|r|D ]	}| | qdS dS )a9  Initialize the DER object as a SET OF.

        :Parameters:
          startSet : container
            The initial set of integers or DER encoded objects.
          implicit : integer
            The IMPLICIT tag to use for the encoded object.
            It overrides the universal tag for SET OF (17).
           r3   TN)r   r   rn   
_elemOctetadd)r   startSetr<   er   r   r   r     s   
zDerSetOf.__init__c                 C   rt   r   rp   rq   r   r   r   ru     rv   zDerSetOf.__getitem__c                 C   r   r   )iterrn   r    r   r   r   __iter__  rv   zDerSetOf.__iter__c                 C   r   r   r   r    r   r   r   r     rv   zDerSetOf.__len__c                 C   sl   t |rd}nt|tr| j}nt|d }| j|kr'| jdur$td|| _|| jvr4| j| dS dS )zAdd an element to the set.

        Args:
            elem (byte string or integer):
              An element of the same type of objects already in the set.
              It can be an integer or a DER encoded object.
        rW   r   Nz&New element does not belong to the set)	r   r   r   r7   r   r   r'   rn   r   )r   elemeor   r   r   r     s   	



zDerSetOf.addFc                 C   rk   )a  Decode a complete SET OF DER element, and re-initializes this
        object with it.

        DER INTEGERs are decoded into Python integers. Any other DER
        element is left undecoded; its validity is not checked.

        Args:
            der_encoded (byte string): a complete DER BIT SET OF.
            strict (boolean):
                Whether decoding must check for strict DER compliancy.

        Raises:
            ValueError: in case of parsing errors.
        r`   ra   r   r   r   rO     s   zDerSetOf.decodec                 C   s   g | _ t| || t| j}d}| dkr\|  t }||| |dk r,|j}n	||jkr5td|dkrB| j 	|
  nt }||
 | | j 	|j | dksdS dS )z)Decode a complete DER SET OF from a file.r   z)Not all elements are of the same DER typerW   N)rn   r   rL   r   r9   r%   r!   r7   r'   r   r#   r   rO   rY   )r   rH   rN   rQ   
setIdOctetr   r   r   r   r   rL     s$   

zDerSetOf._decodeFromStreamc                 C   sf   g }| j D ]}t|rt| }nt|tr| }n|}|| q|  d|| _	t| S )zRReturn this SET OF DER element, fully encoded as a
        binary string.
        r3   )
rn   r   r   rG   r   r   r   sortr   r9   )r   orderedr   bysr   r   r   rG     s   



zDerSetOf.encode)NNrS   )r/   r0   r1   r2   r   ru   r   r   r   rO   rL   rG   r   r   r   r   r     s    

!r   rS   )rc   Crypto.Util.py3compatr   r   r   Crypto.Util.numberr   r   __all__r   objectr   r   r   r	   r   r
   r   r   r   r   r   r   r   r   <module>   s"   
	  7_S V-	vY