You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							108 lines
						
					
					
						
							3.0 KiB
						
					
					
				
			
		
		
	
	
							108 lines
						
					
					
						
							3.0 KiB
						
					
					
				#
 | 
						|
# This file is part of pyasn1 software.
 | 
						|
#
 | 
						|
# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
 | 
						|
# License: http://snmplabs.com/pyasn1/license.html
 | 
						|
#
 | 
						|
from pyasn1 import error
 | 
						|
from pyasn1.codec.cer import encoder
 | 
						|
from pyasn1.type import univ
 | 
						|
 | 
						|
__all__ = ['encode']
 | 
						|
 | 
						|
 | 
						|
class SetEncoder(encoder.SetEncoder):
 | 
						|
    @staticmethod
 | 
						|
    def _componentSortKey(componentAndType):
 | 
						|
        """Sort SET components by tag
 | 
						|
 | 
						|
        Sort depending on the actual Choice value (dynamic sort)
 | 
						|
        """
 | 
						|
        component, asn1Spec = componentAndType
 | 
						|
 | 
						|
        if asn1Spec is None:
 | 
						|
            compType = component
 | 
						|
        else:
 | 
						|
            compType = asn1Spec
 | 
						|
 | 
						|
        if compType.typeId == univ.Choice.typeId and not compType.tagSet:
 | 
						|
            if asn1Spec is None:
 | 
						|
                return component.getComponent().tagSet
 | 
						|
            else:
 | 
						|
                # TODO: move out of sorting key function
 | 
						|
                names = [namedType.name for namedType in asn1Spec.componentType.namedTypes
 | 
						|
                         if namedType.name in component]
 | 
						|
                if len(names) != 1:
 | 
						|
                    raise error.PyAsn1Error(
 | 
						|
                        '%s components for Choice at %r' % (len(names) and 'Multiple ' or 'None ', component))
 | 
						|
 | 
						|
                # TODO: support nested CHOICE ordering
 | 
						|
                return asn1Spec[names[0]].tagSet
 | 
						|
 | 
						|
        else:
 | 
						|
            return compType.tagSet
 | 
						|
 | 
						|
tagMap = encoder.tagMap.copy()
 | 
						|
tagMap.update({
 | 
						|
    # Set & SetOf have same tags
 | 
						|
    univ.Set.tagSet: SetEncoder()
 | 
						|
})
 | 
						|
 | 
						|
typeMap = encoder.typeMap.copy()
 | 
						|
typeMap.update({
 | 
						|
    # Set & SetOf have same tags
 | 
						|
    univ.Set.typeId: SetEncoder()
 | 
						|
})
 | 
						|
 | 
						|
 | 
						|
class Encoder(encoder.Encoder):
 | 
						|
    fixedDefLengthMode = True
 | 
						|
    fixedChunkSize = 0
 | 
						|
 | 
						|
#: Turns ASN.1 object into DER octet stream.
 | 
						|
#:
 | 
						|
#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
 | 
						|
#: walks all its components recursively and produces a DER octet stream.
 | 
						|
#:
 | 
						|
#: Parameters
 | 
						|
#: ----------
 | 
						|
#: value: either a Python or pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
 | 
						|
#:     A Python or pyasn1 object to encode. If Python object is given, `asnSpec`
 | 
						|
#:     parameter is required to guide the encoding process.
 | 
						|
#:
 | 
						|
#: Keyword Args
 | 
						|
#: ------------
 | 
						|
#: asn1Spec:
 | 
						|
#:     Optional ASN.1 schema or value object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
 | 
						|
#:
 | 
						|
#: Returns
 | 
						|
#: -------
 | 
						|
#: : :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
 | 
						|
#:     Given ASN.1 object encoded into BER octet-stream
 | 
						|
#:
 | 
						|
#: Raises
 | 
						|
#: ------
 | 
						|
#: ~pyasn1.error.PyAsn1Error
 | 
						|
#:     On encoding errors
 | 
						|
#:
 | 
						|
#: Examples
 | 
						|
#: --------
 | 
						|
#: Encode Python value into DER with ASN.1 schema
 | 
						|
#:
 | 
						|
#: .. code-block:: pycon
 | 
						|
#:
 | 
						|
#:    >>> seq = SequenceOf(componentType=Integer())
 | 
						|
#:    >>> encode([1, 2, 3], asn1Spec=seq)
 | 
						|
#:    b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03'
 | 
						|
#:
 | 
						|
#: Encode ASN.1 value object into DER
 | 
						|
#:
 | 
						|
#: .. code-block:: pycon
 | 
						|
#:
 | 
						|
#:    >>> seq = SequenceOf(componentType=Integer())
 | 
						|
#:    >>> seq.extend([1, 2, 3])
 | 
						|
#:    >>> encode(seq)
 | 
						|
#:    b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03'
 | 
						|
#:
 | 
						|
encode = Encoder(tagMap, typeMap)
 |