Example #1
0
    def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
                             length, state, decodeFun, substrateFun):
        asn1Object = self._createComponent(asn1Spec, tagSet)
        if substrateFun:
            return substrateFun(asn1Object, substrate, length)

        namedTypes = asn1Object.componentType

        if not namedTypes or namedTypes.hasOptionalOrDefault:
            seenIndices = set()
            idx = 0
            while substrate:
                asn1Spec = self._getComponentTagMap(asn1Object, idx)
                component, substrate = decodeFun(substrate,
                                                 asn1Spec,
                                                 allowEoo=True)
                if component is eoo.endOfOctets:
                    break
                idx = self._getComponentPositionByType(
                    asn1Object, component.effectiveTagSet, idx)

                asn1Object.setComponentByPosition(idx,
                                                  component,
                                                  verifyConstraints=False,
                                                  matchTags=False,
                                                  matchConstraints=False)
                seenIndices.add(idx)
                idx += 1

            else:
                raise error.SubstrateUnderrunError(
                    'No EOO seen before substrate ends')

            if namedTypes and not namedTypes.requiredComponents.issubset(
                    seenIndices):
                raise error.PyAsn1Error(
                    'ASN.1 object %s has uninitialized components' %
                    asn1Object.__class__.__name__)
        else:
            for idx, asn1Spec in enumerate(namedTypes.values()):
                component, substrate = decodeFun(substrate, asn1Spec)

                asn1Object.setComponentByPosition(idx,
                                                  component,
                                                  verifyConstraints=False,
                                                  matchTags=False,
                                                  matchConstraints=False)

            component, substrate = decodeFun(substrate,
                                             eoo.endOfOctets,
                                             allowEoo=True)
            if component is not eoo.endOfOctets:
                raise error.SubstrateUnderrunError(
                    'No EOO seen before substrate ends')

        if not namedTypes:
            asn1Object.verifySizeSpec()

        return asn1Object, substrate
Example #2
0
    def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
                             length, state, decodeFun, substrateFun):
        asn1Object = self._createComponent(asn1Spec, tagSet)
        if substrateFun:
            return substrateFun(asn1Object, substrate, length)

        namedTypes = asn1Object.getComponentType()

        if not namedTypes or namedTypes.hasOptionalOrDefault:
            idx = 0
            while substrate:
                asn1Spec = self._getComponentTagMap(asn1Object, idx)
                component, substrate = decodeFun(substrate,
                                                 asn1Spec,
                                                 allowEoo=True)
                if eoo.endOfOctets.isSameTypeWith(
                        component) and component == eoo.endOfOctets:
                    break
                idx = self._getComponentPositionByType(
                    asn1Object, component.getEffectiveTagSet(), idx)

                asn1Object.setComponentByPosition(idx,
                                                  component,
                                                  verifyConstraints=False,
                                                  matchTags=False,
                                                  matchConstraints=False)
                idx += 1

            else:
                raise error.SubstrateUnderrunError(
                    'No EOO seen before substrate ends')

            asn1Object.setDefaultComponents()
        else:
            for idx, asn1Spec in enumerate(namedTypes.values()):
                component, substrate = decodeFun(substrate, asn1Spec)

                asn1Object.setComponentByPosition(idx,
                                                  component,
                                                  verifyConstraints=False,
                                                  matchTags=False,
                                                  matchConstraints=False)

            component, substrate = decodeFun(substrate,
                                             eoo.endOfOctets,
                                             allowEoo=True)
            if not eoo.endOfOctets.isSameTypeWith(
                    component) or component != eoo.endOfOctets:
                raise error.SubstrateUnderrunError(
                    'No EOO seen before substrate ends')

        if not namedTypes:
            asn1Object.verifySizeSpec()

        return asn1Object, substrate
Example #3
0
 def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
                  length, state, decodeFun, substrateFun):
     head, tail = substrate[:length], substrate[length:]
     if not head:
         return self._createComponent(asn1Spec, tagSet, 0.0), tail
     fo = oct2int(head[0]); head = head[1:]
     if fo & 0x80:  # binary enoding
         n = (fo & 0x03) + 1
         if n == 4:
             n = oct2int(head[0])
         eo, head = head[:n], head[n:]
         if not eo or not head:
             raise error.PyAsn1Error('Real exponent screwed')
         e = oct2int(eo[0]) & 0x80 and -1 or 0
         while eo:         # exponent
             e <<= 8
             e |= oct2int(eo[0])
             eo = eo[1:]
         p = 0
         while head:  # value
             p <<= 8
             p |= oct2int(head[0])
             head = head[1:]
         if fo & 0x40:    # sign bit
             p = -p
         value = (p, 2, e)
     elif fo & 0x40:  # infinite value
         value = fo & 0x01 and '-inf' or 'inf'
     elif fo & 0xc0 == 0:  # character encoding
         try:
             if fo & 0x3 == 0x1:  # NR1
                 value = (int(head), 10, 0)
             elif fo & 0x3 == 0x2:  # NR2
                 value = float(head)
             elif fo & 0x3 == 0x3:  # NR3
                 value = float(head)
             else:
                 raise error.SubstrateUnderrunError(
                     'Unknown NR (tag %s)' % fo
                     )
         except ValueError:
             raise error.SubstrateUnderrunError(
                 'Bad character Real syntax'
                 )
     else:
         raise error.SubstrateUnderrunError(
             'Unknown encoding (tag %s)' % fo
             )
     return self._createComponent(asn1Spec, tagSet, value), tail
Example #4
0
def readFromStream(substrate, size=-1, context=None):
    """Read from the stream.

    Parameters
    ----------
    substrate: :py:class:`IOBase`
        Stream to read from.

    Keyword parameters
    ------------------
    size: :py:class:`int`
        How many bytes to read (-1 = all available)

    context: :py:class:`dict`
        Opaque caller context will be attached to exception objects created
        by this function.

    Yields
    ------
    : :py:class:`bytes` or :py:class:`str` or :py:class:`SubstrateUnderrunError`
        Read data or :py:class:`~pyasn1.error.SubstrateUnderrunError`
        object if no `size` bytes is readily available in the stream. The
        data type depends on Python major version

    Raises
    ------
    : :py:class:`~pyasn1.error.EndOfStreamError`
        Input stream is exhausted
    """
    while True:
        # this will block unless stream is non-blocking
        received = substrate.read(size)
        if received is None:  # non-blocking stream can do this
            yield error.SubstrateUnderrunError(context=context)

        elif not received and size != 0:  # end-of-stream
            raise error.EndOfStreamError(context=context)

        elif len(received) < size:
            substrate.seek(-len(received), os.SEEK_CUR)

            # behave like a non-blocking stream
            yield error.SubstrateUnderrunError(context=context)

        else:
            break

    yield received
Example #5
0
    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
                     state, decodeFun, substrateFun):
        head, tail = substrate[:length], substrate[length:]
        if not head:
            raise error.PyAsn1Error('Empty substrate')

        # Get the first subid
        subId = oct2int(head[0])
        oid = divmod(subId, 40)

        index = 1
        substrateLen = len(head)
        while index < substrateLen:
            subId = oct2int(head[index])
            index = index + 1
            if subId == 128:
                # ASN.1 spec forbids leading zeros (0x80) in sub-ID OID
                # encoding, tolerating it opens a vulnerability.
                # See http://www.cosic.esat.kuleuven.be/publications/article-1432.pdf page 7
                raise error.PyAsn1Error('Invalid leading 0x80 in sub-OID')
            elif subId > 128:
                # Construct subid from a number of octets
                nextSubId = subId
                subId = 0
                while nextSubId >= 128:
                    subId = (subId << 7) + (nextSubId & 0x7F)
                    if index >= substrateLen:
                        raise error.SubstrateUnderrunError(
                            'Short substrate for sub-OID past %s' % (oid,)
                            )
                    nextSubId = oct2int(head[index])
                    index = index + 1
                subId = (subId << 7) + nextSubId
            oid = oid + (subId,)
        return self._createComponent(asn1Spec, tagSet, oid), tail
Example #6
0
    def valueDecoder(self, substrate, asn1Spec, tagSet, length, state,
                     decodeFun):
        r = self._createComponent(tagSet, asn1Spec)  # XXX use default tagset
        if not substrate:
            raise error.PyAsn1Error('Empty substrate')
        oid = []
        index = 0
        # Get the first subid
        subId = ord(substrate[index])
        oid.append(int(subId / 40))
        oid.append(int(subId % 40))

        index = index + 1
        substrateLen = len(substrate)

        while index < substrateLen:
            subId = ord(substrate[index])
            if subId < 128:
                oid.append(subId)
                index = index + 1
            else:
                # Construct subid from a number of octets
                nextSubId = subId
                subId = 0
                while nextSubId >= 128 and index < substrateLen:
                    subId = (subId << 7) + (nextSubId & 0x7F)
                    index = index + 1
                    nextSubId = ord(substrate[index])
                if index == substrateLen:
                    raise error.SubstrateUnderrunError(
                        'Short substrate for OID %s' % oid)
                subId = (subId << 7) + nextSubId
                oid.append(subId)
                index = index + 1
        return r.clone(tuple(oid)), substrate[index:]
Example #7
0
 def indefLenValueDecoder(self, substrate, asn1Spec, tagSet,
                          length, state, decodeFun):
     r = self._createComponent(tagSet, asn1Spec)
     idx = 0
     while substrate:
         try:
             asn1Spec = self._getAsn1SpecByPosition(r, idx)
         except error.PyAsn1Error:
             asn1Spec = None # XXX
         if not decodeFun:
             return r, substrate
         component, substrate = decodeFun(substrate, asn1Spec)
         if component == eoo.endOfOctets:
             break
         idx = self._getPositionByType(r, component, idx)
         r.setComponentByPosition(idx, component)
         idx = idx + 1                
     else:
         raise error.SubstrateUnderrunError(
             'No EOO seen before substrate ends'
             )
     if hasattr(r, 'setDefaultComponents'):
         r.setDefaultComponents()
     r.verifySizeSpec()
     return r, substrate
Example #8
0
    def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
                             length, state, decodeFun, substrateFun):
        if asn1Spec is not None and tagSet == asn1Spec.tagSet:
            # tagged Any type -- consume header substrate
            header = null
        else:
            # untagged Any, recover header substrate
            header = fullSubstrate[:-len(substrate)]

        # Any components do not inherit initial tag
        asn1Spec = self.protoComponent

        if substrateFun and substrateFun is not self.substrateCollector:
            asn1Object = self._createComponent(asn1Spec, tagSet)
            return substrateFun(asn1Object, header + substrate,
                                length + len(header))

        # All inner fragments are of the same type, treat them as octet string
        substrateFun = self.substrateCollector

        while substrate:
            component, substrate = decodeFun(substrate,
                                             asn1Spec,
                                             substrateFun=substrateFun,
                                             allowEoo=True)
            if component is eoo.endOfOctets:
                break
            header += component
        else:
            raise error.SubstrateUnderrunError(
                'No EOO seen before substrate ends')
        if substrateFun:
            return header, substrate
        else:
            return self._createComponent(asn1Spec, tagSet, header), substrate
Example #9
0
 def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
                          length, state, decodeFun, substrateFun):
     r = self._createComponent(asn1Spec, tagSet)
     if substrateFun:
         return substrateFun(r, substrate, length)
     idx = 0
     while substrate:
         asn1Spec = self._getComponentTagMap(r, idx)
         component, substrate = decodeFun(substrate,
                                          asn1Spec,
                                          allowEoo=True)
         if eoo.endOfOctets.isSameTypeWith(component) and \
                 component == eoo.endOfOctets:
             break
         idx = self._getComponentPositionByType(
             r, component.getEffectiveTagSet(), idx)
         r.setComponentByPosition(idx,
                                  component,
                                  verifyConstraints=False,
                                  matchTags=False,
                                  matchConstraints=False)
         idx += 1
     else:
         raise error.SubstrateUnderrunError(
             'No EOO seen before substrate ends')
     r.setDefaultComponents()
     r.verifySizeSpec()
     return r, substrate
Example #10
0
    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
                     state, decodeFun, substrateFun):

        if tagSet[0].tagFormat != tag.tagFormatSimple:
            raise error.PyAsn1Error('Simple tag format expected')

        head, tail = substrate[:length], substrate[length:]
        if not head:
            raise error.PyAsn1Error('Empty substrate')

        head = octs2ints(head)

        oid = ()
        index = 0
        substrateLen = len(head)
        while index < substrateLen:
            subId = head[index]
            index += 1
            if subId < 128:
                oid += (subId,)
            elif subId > 128:
                # Construct subid from a number of octets
                nextSubId = subId
                subId = 0
                while nextSubId >= 128:
                    subId = (subId << 7) + (nextSubId & 0x7F)
                    if index >= substrateLen:
                        raise error.SubstrateUnderrunError(
                            'Short substrate for sub-OID past %s' % (oid,)
                        )
                    nextSubId = head[index]
                    index += 1
                oid += ((subId << 7) + nextSubId,)
            elif subId == 128:
                # ASN.1 spec forbids leading zeros (0x80) in OID
                # encoding, tolerating it opens a vulnerability. See
                # http://www.cosic.esat.kuleuven.be/publications/article-1432.pdf
                # page 7
                raise error.PyAsn1Error('Invalid octet 0x80 in OID encoding')

        # Decode two leading arcs
        if 0 <= oid[0] <= 39:
            oid = (0,) + oid
        elif 40 <= oid[0] <= 79:
            oid = (1, oid[0] - 40) + oid[1:]
        elif oid[0] >= 80:
            oid = (2, oid[0] - 80) + oid[1:]
        else:
            raise error.PyAsn1Error('Malformed first OID octet: %s' % head[0])

        return self._createComponent(asn1Spec, tagSet, oid), tail
Example #11
0
 def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
                          length, state, decodeFun):
     r = self._createComponent(asn1Spec, tagSet, '')
     if not decodeFun:
         return r, substrate
     while substrate:
         component, substrate = decodeFun(substrate)
         if component == eoo.endOfOctets:
             break
         r = r + component
     else:
         raise error.SubstrateUnderrunError(
             'No EOO seen before substrate ends')
     return r, substrate
Example #12
0
    def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
                             length, state, decodeFun, substrateFun):
        bitString = self._createComponent(asn1Spec, tagSet)

        if substrateFun:
            return substrateFun(bitString, substrate, length)

        while substrate:
            component, substrate = decodeFun(substrate, self.protoComponent, allowEoo=True)
            if component is eoo.endOfOctets:
                break

            bitString += component

        else:
            raise error.SubstrateUnderrunError('No EOO seen before substrate ends')

        return bitString, substrate
Example #13
0
 def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
                          length, state, decodeFun):
     r = self._createComponent(asn1Spec, tagSet)
     asn1Spec = r.getComponentType()
     idx = 0
     if not decodeFun:
         return r, substrate
     while substrate:
         component, substrate = decodeFun(substrate, asn1Spec)
         if component == eoo.endOfOctets:
             break
         r.setComponentByPosition(idx, component, asn1Spec is None)
         idx = idx + 1
     else:
         raise error.SubstrateUnderrunError(
             'No EOO seen before substrate ends')
     r.verifySizeSpec()
     return r, substrate
Example #14
0
 def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
                          length, state, decodeFun, substrateFun):
     r = self._createComponent(asn1Spec, tagSet)
     if substrateFun:
         return substrateFun(r, substrate, length)
     asn1Spec = r.getComponentType()
     idx = 0
     while substrate:
         component, substrate = decodeFun(substrate, asn1Spec, allowEoo=True)
         if eoo.endOfOctets.isSameTypeWith(component) and \
                 component == eoo.endOfOctets:
             break
         r.setComponentByPosition(idx, component, asn1Spec is None)
         idx += 1
     else:
         raise error.SubstrateUnderrunError(
             'No EOO seen before substrate ends'
         )
     r.verifySizeSpec()
     return r, substrate
Example #15
0
 def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
                          length, state, decodeFun):
     r = self._createComponent(asn1Spec, tagSet)
     idx = 0
     while substrate:
         asn1Spec = self._getComponentTagMap(r, idx)
         if not decodeFun:
             return r, substrate
         component, substrate = decodeFun(substrate, asn1Spec)
         if component == eoo.endOfOctets:
             break
         idx = self._getComponentPositionByType(
             r, component.getEffectiveTagSet(), idx)
         r.setComponentByPosition(idx, component, asn1Spec is None)
         idx = idx + 1
     else:
         raise error.SubstrateUnderrunError(
             'No EOO seen before substrate ends')
     r.setDefaultComponents()
     r.verifySizeSpec()
     return r, substrate
Example #16
0
    def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
                             length, state, decodeFun, substrateFun):
        if substrateFun and substrateFun is not self.substrateCollector:
            asn1Object = self._createComponent(asn1Spec, tagSet)
            return substrateFun(asn1Object, substrate, length)

        # All inner fragments are of the same type, treat them as octet string
        substrateFun = self.substrateCollector

        header = null

        while substrate:
            component, substrate = decodeFun(substrate,
                                             self.protoComponent,
                                             substrateFun=substrateFun,
                                             allowEoo=True)
            if component is eoo.endOfOctets:
                break
            header += component
        else:
            raise error.SubstrateUnderrunError(
                'No EOO seen before substrate ends')
        return self._createComponent(asn1Spec, tagSet, header), substrate
Example #17
0
    def __call__(self,
                 substrate,
                 asn1Spec=None,
                 tagSet=None,
                 length=None,
                 state=stDecodeTag,
                 recursiveFlag=1):
        debug.logger & debug.flagDecoder and debug.logger(
            'decoder called with state %d, working with up to %d octets of substrate: %s'
            % (state, len(substrate), debug.hexdump(substrate)))
        fullSubstrate = substrate
        while state != stStop:
            if state == stDecodeTag:
                # Decode tag
                if not substrate:
                    raise error.SubstrateUnderrunError(
                        'Short octet stream on tag decoding')

                firstOctet = substrate[0]
                substrate = substrate[1:]
                if firstOctet in self.__tagCache:
                    lastTag = self.__tagCache[firstOctet]
                else:
                    t = oct2int(firstOctet)
                    tagClass = t & 0xC0
                    tagFormat = t & 0x20
                    tagId = t & 0x1F
                    if tagId == 0x1F:
                        tagId = 0
                        while 1:
                            if not substrate:
                                raise error.SubstrateUnderrunError(
                                    'Short octet stream on long tag decoding')
                            t = oct2int(substrate[0])
                            tagId = tagId << 7 | (t & 0x7F)
                            substrate = substrate[1:]
                            if not t & 0x80:
                                break
                    lastTag = tag.Tag(tagClass=tagClass,
                                      tagFormat=tagFormat,
                                      tagId=tagId)
                    if tagId < 31:
                        # cache short tags
                        self.__tagCache[firstOctet] = lastTag
                if tagSet is None:
                    if firstOctet in self.__tagSetCache:
                        tagSet = self.__tagSetCache[firstOctet]
                    else:
                        # base tag not recovered
                        tagSet = tag.TagSet((), lastTag)
                        if firstOctet in self.__tagCache:
                            self.__tagSetCache[firstOctet] = tagSet
                else:
                    tagSet = lastTag + tagSet
                state = stDecodeLength
                debug.logger and debug.logger & debug.flagDecoder and debug.logger(
                    'tag decoded into %r, decoding length' % tagSet)
            if state == stDecodeLength:
                # Decode length
                if not substrate:
                    raise error.SubstrateUnderrunError(
                        'Short octet stream on length decoding')
                firstOctet = oct2int(substrate[0])
                if firstOctet == 128:
                    size = 1
                    length = -1
                elif firstOctet < 128:
                    length, size = firstOctet, 1
                else:
                    size = firstOctet & 0x7F
                    # encoded in size bytes
                    length = 0
                    lengthString = substrate[1:size + 1]
                    # missing check on maximum size, which shouldn't be a
                    # problem, we can handle more than is possible
                    if len(lengthString) != size:
                        raise error.SubstrateUnderrunError(
                            '%s<%s at %s' % (size, len(lengthString), tagSet))
                    for char in lengthString:
                        length = (length << 8) | oct2int(char)
                    size = size + 1
                substrate = substrate[size:]
                if length != -1 and len(substrate) < length:
                    raise error.SubstrateUnderrunError(
                        '%d-octet short' % (length - len(substrate)))
                state = stGetValueDecoder
                debug.logger and debug.logger & debug.flagDecoder and debug.logger(
                    'value length decoded into %d, payload substrate is: %s' %
                    (length, debug.hexdump(substrate)))
            if state == stGetValueDecoder:
                if asn1Spec is None:
                    state = stGetValueDecoderByTag
                else:
                    state = stGetValueDecoderByAsn1Spec
            #
            # There're two ways of creating subtypes in ASN.1 what influences
            # decoder operation. These methods are:
            # 1) Either base types used in or no IMPLICIT tagging has been
            #    applied on subtyping.
            # 2) Subtype syntax drops base type information (by means of
            #    IMPLICIT tagging.
            # The first case allows for complete tag recovery from substrate
            # while the second one requires original ASN.1 type spec for
            # decoding.
            #
            # In either case a set of tags (tagSet) is coming from substrate
            # in an incremental, tag-by-tag fashion (this is the case of
            # EXPLICIT tag which is most basic). Outermost tag comes first
            # from the wire.
            #
            if state == stGetValueDecoderByTag:
                if tagSet in self.__tagMap:
                    concreteDecoder = self.__tagMap[tagSet]
                else:
                    concreteDecoder = None
                if concreteDecoder:
                    state = stDecodeValue
                else:
                    _k = tagSet[:1]
                    if _k in self.__tagMap:
                        concreteDecoder = self.__tagMap[_k]
                    else:
                        concreteDecoder = None
                    if concreteDecoder:
                        state = stDecodeValue
                    else:
                        state = stTryAsExplicitTag
                debug.logger and debug.logger & debug.flagDecoder and debug.logger(
                    'codec %s chosen by a built-in type, decoding %s' %
                    (concreteDecoder and concreteDecoder.__class__.__name__
                     or "<none>", state == stDecodeValue and 'value'
                     or 'explicit tag'))
            if state == stGetValueDecoderByAsn1Spec:
                if isinstance(asn1Spec, (dict, tagmap.TagMap)):
                    if tagSet in asn1Spec:
                        __chosenSpec = asn1Spec[tagSet]
                    else:
                        __chosenSpec = None
                else:
                    __chosenSpec = asn1Spec
                if __chosenSpec is not None and (
                       tagSet == __chosenSpec.getTagSet() or \
                       tagSet in __chosenSpec.getTagMap()
                       ):
                    # use base type for codec lookup to recover untagged types
                    baseTagSet = __chosenSpec.baseTagSet
                    if __chosenSpec.typeId is not None and \
                           __chosenSpec.typeId in self.__typeMap:
                        # ambiguous type
                        concreteDecoder = self.__typeMap[__chosenSpec.typeId]
                    elif baseTagSet in self.__tagMap:
                        # base type or tagged subtype
                        concreteDecoder = self.__tagMap[baseTagSet]
                    else:
                        concreteDecoder = None
                    if concreteDecoder:
                        asn1Spec = __chosenSpec
                        state = stDecodeValue
                    else:
                        state = stTryAsExplicitTag
                elif tagSet == self.__endOfOctetsTagSet:
                    concreteDecoder = self.__tagMap[tagSet]
                    state = stDecodeValue
                else:
                    state = stTryAsExplicitTag
                if debug.logger and debug.logger & debug.flagDecoder:
                    if isinstance(asn1Spec, base.Asn1Item):
                        debug.logger(
                            'choosing value codec by ASN.1 spec:\n  %r -> %r' %
                            (asn1Spec.getTagSet(),
                             asn1Spec.__class__.__name__))
                    else:
                        debug.logger(
                            'choosing value codec by ASN.1 spec that offers either of the following: '
                        )
                        for t, v in list(asn1Spec.getPosMap().items()):
                            debug.logger('  %r -> %s' %
                                         (t, v.__class__.__name__))
                        debug.logger('but neither of: ')
                        for i in list(asn1Spec.getNegMap().items()):
                            debug.logger('  %r -> %s' %
                                         (t, v.__class__.__name__))
                    debug.logger(
                        'codec %s chosen by ASN.1 spec, decoding %s' %
                        (state == stDecodeValue
                         and concreteDecoder.__class__.__name__ or "<none>",
                         state == stDecodeValue and 'value' or 'explicit tag'))
            if state == stTryAsExplicitTag:
                if tagSet and \
                       tagSet[0][1] == tag.tagFormatConstructed and \
                       tagSet[0][0] != tag.tagClassUniversal:
                    # Assume explicit tagging
                    concreteDecoder = explicitTagDecoder
                    state = stDecodeValue
                else:
                    state = self.defaultErrorState
                debug.logger and debug.logger & debug.flagDecoder and debug.logger(
                    'codec %s chosen, decoding %s' %
                    (concreteDecoder and concreteDecoder.__class__.__name__
                     or "<none>", state == stDecodeValue and 'value'
                     or 'as failure'))
            if state == stDumpRawValue:
                concreteDecoder = self.defaultRawDecoder
                debug.logger and debug.logger & debug.flagDecoder and debug.logger(
                    'codec %s chosen, decoding value' %
                    concreteDecoder.__class__.__name__)
                state = stDecodeValue
            if state == stDecodeValue:
                if recursiveFlag:
                    decodeFun = self
                else:
                    decodeFun = None
                if length == -1:  # indef length
                    value, substrate = concreteDecoder.indefLenValueDecoder(
                        fullSubstrate, substrate, asn1Spec, tagSet, length,
                        stGetValueDecoder, decodeFun)
                else:
                    value, _substrate = concreteDecoder.valueDecoder(
                        fullSubstrate, substrate, asn1Spec, tagSet, length,
                        stGetValueDecoder, decodeFun)
                    if recursiveFlag:
                        substrate = substrate[length:]
                    else:
                        substrate = _substrate
                state = stStop
                debug.logger and debug.logger & debug.flagDecoder and debug.logger(
                    'codec %s yields type %s, value:\n%s\n...remaining substrate is: %s'
                    % (concreteDecoder.__class__.__name__,
                       value.__class__.__name__, value.prettyPrint(),
                       substrate and debug.hexdump(substrate) or '<none>'))
            if state == stErrorCondition:
                raise error.PyAsn1Error('%r not in asn1Spec: %r' %
                                        (tagSet, asn1Spec))
        debug.logger and debug.logger & debug.flagDecoder and debug.logger(
            'decoder call completed')
        return value, substrate
Example #18
0
    def __call__(self,
                 substrate,
                 asn1Spec=None,
                 tagSet=None,
                 length=None,
                 state=stDecodeTag,
                 recursiveFlag=True,
                 substrateFun=None,
                 allowEoo=False):
        if debug.logger & debug.flagDecoder:
            logger = debug.logger
        else:
            logger = None

        if logger:
            logger(
                'decoder called at scope %s with state %d, working with up to %d octets of substrate: %s'
                %
                (debug.scope, state, len(substrate), debug.hexdump(substrate)))

        substrate = ensureString(substrate)

        # Look for end-of-octets sentinel
        if allowEoo and self.supportIndefLength:
            if substrate.startswith(self.__eooSentinel):
                if logger:
                    logger('end-of-octets sentinel found')
                return eoo.endOfOctets, substrate[2:]

        value = base.noValue

        fullSubstrate = substrate
        while not state is stStop:
            if state is stDecodeTag:
                if not substrate:
                    raise error.SubstrateUnderrunError(
                        'Short octet stream on tag decoding')
                # Decode tag
                isShortTag = True
                firstOctet = substrate[0]
                substrate = substrate[1:]
                try:
                    lastTag = self.__tagCache[firstOctet]
                except KeyError:
                    integerTag = oct2int(firstOctet)
                    tagClass = integerTag & 0xC0
                    tagFormat = integerTag & 0x20
                    tagId = integerTag & 0x1F
                    if tagId == 0x1F:
                        isShortTag = False
                        lengthOctetIdx = 0
                        tagId = 0
                        try:
                            while True:
                                integerTag = oct2int(substrate[lengthOctetIdx])
                                lengthOctetIdx += 1
                                tagId <<= 7
                                tagId |= (integerTag & 0x7F)
                                if not integerTag & 0x80:
                                    break
                            substrate = substrate[lengthOctetIdx:]
                        except IndexError:
                            raise error.SubstrateUnderrunError(
                                'Short octet stream on long tag decoding')
                    lastTag = tag.Tag(tagClass=tagClass,
                                      tagFormat=tagFormat,
                                      tagId=tagId)
                    if isShortTag:
                        # cache short tags
                        self.__tagCache[firstOctet] = lastTag
                if tagSet is None:
                    if isShortTag:
                        try:
                            tagSet = self.__tagSetCache[firstOctet]
                        except KeyError:
                            # base tag not recovered
                            tagSet = tag.TagSet((), lastTag)
                            self.__tagSetCache[firstOctet] = tagSet
                    else:
                        tagSet = tag.TagSet((), lastTag)
                else:
                    tagSet = lastTag + tagSet
                state = stDecodeLength
                if logger:
                    logger('tag decoded into %s, decoding length' % tagSet)
            if state is stDecodeLength:
                # Decode length
                if not substrate:
                    raise error.SubstrateUnderrunError(
                        'Short octet stream on length decoding')
                firstOctet = oct2int(substrate[0])
                if firstOctet < 128:
                    size = 1
                    length = firstOctet
                elif firstOctet == 128:
                    size = 1
                    length = -1
                else:
                    size = firstOctet & 0x7F
                    # encoded in size bytes
                    encodedLength = octs2ints(substrate[1:size + 1])
                    # missing check on maximum size, which shouldn't be a
                    # problem, we can handle more than is possible
                    if len(encodedLength) != size:
                        raise error.SubstrateUnderrunError(
                            '%s<%s at %s' % (size, len(encodedLength), tagSet))
                    length = 0
                    for lengthOctet in encodedLength:
                        length <<= 8
                        length |= lengthOctet
                    size += 1
                substrate = substrate[size:]
                if length == -1:
                    if not self.supportIndefLength:
                        raise error.PyAsn1Error(
                            'Indefinite length encoding not supported by this codec'
                        )
                else:
                    if len(substrate) < length:
                        raise error.SubstrateUnderrunError(
                            '%d-octet short' % (length - len(substrate)))
                state = stGetValueDecoder
                if logger:
                    logger(
                        'value length decoded into %d, payload substrate is: %s'
                        % (length,
                           debug.hexdump(length == -1 and substrate
                                         or substrate[:length])))
            if state is stGetValueDecoder:
                if asn1Spec is None:
                    state = stGetValueDecoderByTag
                else:
                    state = stGetValueDecoderByAsn1Spec
            #
            # There're two ways of creating subtypes in ASN.1 what influences
            # decoder operation. These methods are:
            # 1) Either base types used in or no IMPLICIT tagging has been
            #    applied on subtyping.
            # 2) Subtype syntax drops base type information (by means of
            #    IMPLICIT tagging.
            # The first case allows for complete tag recovery from substrate
            # while the second one requires original ASN.1 type spec for
            # decoding.
            #
            # In either case a set of tags (tagSet) is coming from substrate
            # in an incremental, tag-by-tag fashion (this is the case of
            # EXPLICIT tag which is most basic). Outermost tag comes first
            # from the wire.
            #
            if state is stGetValueDecoderByTag:
                try:
                    concreteDecoder = self.__tagMap[tagSet]
                except KeyError:
                    concreteDecoder = None
                if concreteDecoder:
                    state = stDecodeValue
                else:
                    try:
                        concreteDecoder = self.__tagMap[tagSet[:1]]
                    except KeyError:
                        concreteDecoder = None
                    if concreteDecoder:
                        state = stDecodeValue
                    else:
                        state = stTryAsExplicitTag
                if logger:
                    logger(
                        'codec %s chosen by a built-in type, decoding %s' %
                        (concreteDecoder and concreteDecoder.__class__.__name__
                         or "<none>", state is stDecodeValue and 'value'
                         or 'as explicit tag'))
                    debug.scope.push(
                        concreteDecoder is None and '?'
                        or concreteDecoder.protoComponent.__class__.__name__)
            if state is stGetValueDecoderByAsn1Spec:
                if asn1Spec.__class__ is dict or asn1Spec.__class__ is tagmap.TagMap:
                    try:
                        chosenSpec = asn1Spec[tagSet]
                    except KeyError:
                        chosenSpec = None
                    if logger:
                        logger('candidate ASN.1 spec is a map of:')
                        for firstOctet, v in asn1Spec.presentTypes.items():
                            logger('  %s -> %s' %
                                   (firstOctet, v.__class__.__name__))
                        if asn1Spec.skipTypes:
                            logger('but neither of: ')
                            for firstOctet, v in asn1Spec.skipTypes.items():
                                logger('  %s -> %s' %
                                       (firstOctet, v.__class__.__name__))
                        logger('new candidate ASN.1 spec is %s, chosen by %s' %
                               (chosenSpec is None and '<none>'
                                or chosenSpec.prettyPrintType(), tagSet))
                else:
                    if tagSet == asn1Spec.tagSet or tagSet in asn1Spec.tagMap:
                        chosenSpec = asn1Spec
                        if logger:
                            logger('candidate ASN.1 spec is %s' %
                                   asn1Spec.__class__.__name__)
                    else:
                        chosenSpec = None

                if chosenSpec is not None:
                    try:
                        # ambiguous type or just faster codec lookup
                        concreteDecoder = self.__typeMap[chosenSpec.typeId]
                        if logger:
                            logger(
                                'value decoder chosen for an ambiguous type by type ID %s'
                                % (chosenSpec.typeId, ))
                    except KeyError:
                        # use base type for codec lookup to recover untagged types
                        baseTagSet = tag.TagSet(chosenSpec.tagSet.baseTag,
                                                chosenSpec.tagSet.baseTag)
                        try:
                            # base type or tagged subtype
                            concreteDecoder = self.__tagMap[baseTagSet]
                            if logger:
                                logger('value decoder chosen by base %s' %
                                       (baseTagSet, ))
                        except KeyError:
                            concreteDecoder = None
                    if concreteDecoder:
                        asn1Spec = chosenSpec
                        state = stDecodeValue
                    else:
                        state = stTryAsExplicitTag
                else:
                    concreteDecoder = None
                    state = stTryAsExplicitTag
                if logger:
                    logger('codec %s chosen by ASN.1 spec, decoding %s' %
                           (state is stDecodeValue
                            and concreteDecoder.__class__.__name__
                            or "<none>", state is stDecodeValue and 'value'
                            or 'as explicit tag'))
                    debug.scope.push(chosenSpec is None and '?'
                                     or chosenSpec.__class__.__name__)
            if state is stTryAsExplicitTag:
                if tagSet and tagSet[
                        0].tagFormat == tag.tagFormatConstructed and tagSet[
                            0].tagClass != tag.tagClassUniversal:
                    # Assume explicit tagging
                    concreteDecoder = explicitTagDecoder
                    state = stDecodeValue
                else:
                    concreteDecoder = None
                    state = self.defaultErrorState
                if logger:
                    logger(
                        'codec %s chosen, decoding %s' %
                        (concreteDecoder and concreteDecoder.__class__.__name__
                         or "<none>", state is stDecodeValue and 'value'
                         or 'as failure'))
            if state is stDumpRawValue:
                concreteDecoder = self.defaultRawDecoder
                if logger:
                    logger('codec %s chosen, decoding value' %
                           concreteDecoder.__class__.__name__)
                state = stDecodeValue
            if state is stDecodeValue:
                if not recursiveFlag and not substrateFun:  # legacy

                    def substrateFun(a, b, c):
                        return a, b[:c]

                if length == -1:  # indef length
                    value, substrate = concreteDecoder.indefLenValueDecoder(
                        fullSubstrate, substrate, asn1Spec, tagSet, length,
                        stGetValueDecoder, self, substrateFun)
                else:
                    value, substrate = concreteDecoder.valueDecoder(
                        fullSubstrate, substrate, asn1Spec, tagSet, length,
                        stGetValueDecoder, self, substrateFun)
                state = stStop
                if logger:
                    logger(
                        'codec %s yields type %s, value:\n%s\n...remaining substrate is: %s'
                        % (concreteDecoder.__class__.__name__,
                           value.__class__.__name__, value.prettyPrint(),
                           substrate and debug.hexdump(substrate) or '<none>'))
            if state is stErrorCondition:
                raise error.PyAsn1Error('%s not in asn1Spec: %r' %
                                        (tagSet, asn1Spec))
        if logger:
            debug.scope.pop()
            logger('decoder left scope %s, call completed' % debug.scope)
        return value, substrate
Example #19
0
    def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
                             length, state, decodeFun, substrateFun):
        if tagSet[0].tagFormat != tag.tagFormatConstructed:
            raise error.PyAsn1Error('Constructed tag format expected')

        if substrateFun is not None:
            if asn1Spec is not None:
                asn1Object = asn1Spec.clone()
            elif self.protoComponent is not None:
                asn1Object = self.protoComponent.clone(tagSet=tagSet)
            else:
                asn1Object = self.protoRecordComponent, self.protoSequenceComponent

            return substrateFun(asn1Object, substrate, length)

        if asn1Spec is None:
            return self._decodeComponents(substrate,
                                          decodeFun,
                                          tagSet,
                                          allowEoo=True)

        asn1Object = asn1Spec.clone()

        if asn1Object.typeId in (univ.Sequence.typeId, univ.Set.typeId):

            namedTypes = asn1Object.componentType

            isSetType = asn1Object.typeId == univ.Set.typeId
            isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault

            seenIndices = set()
            idx = 0
            while substrate:
                if len(namedTypes) <= idx:
                    asn1Spec = None
                elif isSetType:
                    asn1Spec = namedTypes.tagMapUnique
                else:
                    try:
                        if isDeterministic:
                            asn1Spec = namedTypes[idx].asn1Object
                        elif namedTypes[idx].isOptional or namedTypes[
                                idx].isDefaulted:
                            asn1Spec = namedTypes.getTagMapNearPosition(idx)
                        else:
                            asn1Spec = namedTypes[idx].asn1Object
                    except IndexError:
                        raise error.PyAsn1Error(
                            'Excessive components decoded at %r' %
                            (asn1Object, ))

                component, substrate = decodeFun(substrate,
                                                 asn1Spec,
                                                 allowEoo=True)
                if component is eoo.endOfOctets:
                    break

                if not isDeterministic and namedTypes:
                    if isSetType:
                        idx = namedTypes.getPositionByType(
                            component.effectiveTagSet)
                    elif namedTypes[idx].isOptional or namedTypes[
                            idx].isDefaulted:
                        idx = namedTypes.getPositionNearType(
                            component.effectiveTagSet, idx)

                asn1Object.setComponentByPosition(idx,
                                                  component,
                                                  verifyConstraints=False,
                                                  matchTags=False,
                                                  matchConstraints=False)

                seenIndices.add(idx)
                idx += 1

            else:
                raise error.SubstrateUnderrunError(
                    'No EOO seen before substrate ends')

            if namedTypes:
                if not namedTypes.requiredComponents.issubset(seenIndices):
                    raise error.PyAsn1Error(
                        'ASN.1 object %s has uninitialized components' %
                        asn1Object.__class__.__name__)
            else:
                asn1Object.verifySizeSpec()

        else:
            asn1Spec = asn1Object.componentType
            idx = 0
            while substrate:
                component, substrate = decodeFun(substrate,
                                                 asn1Spec,
                                                 allowEoo=True)
                if component is eoo.endOfOctets:
                    break
                asn1Object.setComponentByPosition(idx,
                                                  component,
                                                  verifyConstraints=False,
                                                  matchTags=False,
                                                  matchConstraints=False)
                idx += 1
            else:
                raise error.SubstrateUnderrunError(
                    'No EOO seen before substrate ends')
            asn1Object.verifySizeSpec()

        return asn1Object, substrate
Example #20
0
 def __call__(self,
              substrate,
              asn1Spec=None,
              tagSet=None,
              length=None,
              state=stDecodeTag,
              recursiveFlag=1):
     # Decode tag & length
     while state != stStop:
         if state == stDecodeTag:
             # Decode tag
             if not substrate:
                 raise error.SubstrateUnderrunError(
                     'Short octet stream on tag decoding')
             t = ord(substrate[0])
             tagClass = t & 0xC0
             tagFormat = t & 0x20
             tagId = t & 0x1F
             substrate = substrate[1:]
             if tagId == 0x1F:
                 tagId = 0  # 0L
                 while 1:
                     if not substrate:
                         raise error.SubstrateUnderrunError(
                             'Short octet stream on long tag decoding')
                     t = ord(substrate[0])
                     tagId = tagId << 7 | (t & 0x7F)
                     substrate = substrate[1:]
                     if not t & 0x80:
                         break
             lastTag = tag.Tag(tagClass=tagClass,
                               tagFormat=tagFormat,
                               tagId=tagId)
             if tagSet is None:
                 tagSet = tag.TagSet((), lastTag)  # base tag not recovered
             else:
                 tagSet = lastTag + tagSet
             state = stDecodeLength
         if state == stDecodeLength:
             # Decode length
             if not substrate:
                 raise error.SubstrateUnderrunError(
                     'Short octet stream on length decoding')
             firstOctet = ord(substrate[0])
             if firstOctet == 128:
                 size = 1
                 length = -1
             elif firstOctet < 128:
                 length, size = firstOctet, 1
             else:
                 size = firstOctet & 0x7F
                 # encoded in size bytes
                 length = 0
                 lengthString = substrate[1:size + 1]
                 # missing check on maximum size, which shouldn't be a
                 # problem, we can handle more than is possible
                 if len(lengthString) != size:
                     raise error.SubstrateUnderrunError(
                         '%s<%s at %s' % (size, len(lengthString), tagSet))
                 for char in lengthString:
                     length = (length << 8) | ord(char)
                 size = size + 1
             state = stGetValueDecoder
             substrate = substrate[size:]
             if length != -1 and len(substrate) < length:
                 raise error.SubstrateUnderrunError(
                     '%d-octet short' % (length - len(substrate)))
         if state == stGetValueDecoder:
             if asn1Spec is None:
                 state = stGetValueDecoderByTag
             else:
                 state = stGetValueDecoderByAsn1Spec
         #
         # There're two ways of creating subtypes in ASN.1 what influences
         # decoder operation. These methods are:
         # 1) Either base types used in or no IMPLICIT tagging has been
         #    applied on subtyping.
         # 2) Subtype syntax drops base type information (by means of
         #    IMPLICIT tagging.
         # The first case allows for complete tag recovery from substrate
         # while the second one requires original ASN.1 type spec for
         # decoding.
         #
         # In either case a set of tags (tagSet) is coming from substrate
         # in an incremental, tag-by-tag fashion (this is the case of
         # EXPLICIT tag which is most basic). Outermost tag comes first
         # from the wire.
         #
         if state == stGetValueDecoderByTag:
             concreteDecoder = self.__codecMap.get(tagSet)
             if concreteDecoder:
                 state = stDecodeValue
             else:
                 concreteDecoder = self.__codecMap.get(tagSet[:1])
                 if concreteDecoder:
                     state = stDecodeValue
                 else:
                     state = stTryAsExplicitTag
         if state == stGetValueDecoderByAsn1Spec:
             if tagSet == eoo.endOfOctets.getTagSet():
                 concreteDecoder = self.__codecMap[tagSet]
                 state = stDecodeValue
                 continue
             if type(asn1Spec) == types.DictType:
                 __chosenSpec = asn1Spec.get(tagSet)
             elif asn1Spec is not None:
                 __chosenSpec = asn1Spec
             else:
                 __chosenSpec = None
             if __chosenSpec is None or not\
                    __chosenSpec.getTypeMap().has_key(tagSet):
                 state = stTryAsExplicitTag
             else:
                 # use base type for codec lookup to recover untagged types
                 baseTag = __chosenSpec.getTagSet().getBaseTag()
                 if baseTag:  # XXX ugly
                     baseTagSet = tag.TagSet(baseTag, baseTag)
                 else:
                     baseTagSet = tag.TagSet()
                 concreteDecoder = self.__codecMap.get(  # tagged subtype
                     baseTagSet)
                 if concreteDecoder:
                     asn1Spec = __chosenSpec
                     state = stDecodeValue
                 else:
                     state = stTryAsExplicitTag
         if state == stTryAsExplicitTag:
             if tagSet and \
                    tagSet[0][1] == tag.tagFormatConstructed and \
                    tagSet[0][0] != tag.tagClassUniversal:
                 # Assume explicit tagging
                 state = stDecodeTag
             else:
                 raise error.PyAsn1Error('%s not in asn1Spec: %s' %
                                         (tagSet, asn1Spec))
         if state == stDecodeValue:
             if recursiveFlag:
                 decodeFun = self
             else:
                 decodeFun = None
             if length == -1:  # indef length
                 value, substrate = concreteDecoder.indefLenValueDecoder(
                     substrate, asn1Spec, tagSet, length, stGetValueDecoder,
                     decodeFun)
             else:
                 value, _substrate = concreteDecoder.valueDecoder(
                     substrate[:length], asn1Spec, tagSet, length,
                     stGetValueDecoder, decodeFun)
                 if recursiveFlag:
                     substrate = substrate[length:]
                 else:
                     substrate = _substrate
             state = stStop
     return value, substrate
Example #21
0
    def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
                             length, state, decodeFun, substrateFun):
        if tagSet[0].tagFormat != tag.tagFormatConstructed:
            raise error.PyAsn1Error('Constructed tag format expected')

        if substrateFun is not None:
            if asn1Spec is not None:
                asn1Object = asn1Spec.clone()
            elif self.protoComponent is not None:
                asn1Object = self.protoComponent.clone(tagSet=tagSet)
            else:
                asn1Object = self.protoRecordComponent, self.protoSequenceComponent

            return substrateFun(asn1Object, substrate, length)

        if asn1Spec is None:
            return self._decodeComponents(substrate, decodeFun, allowEoo=True)

        asn1Object = asn1Spec.clone()

        if asn1Object.typeId in (univ.Sequence.typeId, univ.Set.typeId):

            namedTypes = asn1Object.componentType

            if not namedTypes or namedTypes.hasOptionalOrDefault:
                seenIndices = set()
                idx = 0
                while substrate:
                    asn1Spec = self._getComponentTagMap(asn1Object, idx)
                    component, substrate = decodeFun(substrate, asn1Spec, allowEoo=True)
                    if component is eoo.endOfOctets:
                        break
                    idx = self._getComponentPositionByType(
                        asn1Object, component.effectiveTagSet, idx
                    )

                    asn1Object.setComponentByPosition(
                        idx, component,
                        verifyConstraints=False,
                        matchTags=False, matchConstraints=False
                    )
                    seenIndices.add(idx)
                    idx += 1

                else:
                    raise error.SubstrateUnderrunError(
                        'No EOO seen before substrate ends'
                    )

                if namedTypes and not namedTypes.requiredComponents.issubset(seenIndices):
                    raise error.PyAsn1Error('ASN.1 object %s has uninitialized components' % asn1Object.__class__.__name__)
            else:
                for idx, asn1Spec in enumerate(namedTypes.values()):
                    component, substrate = decodeFun(substrate, asn1Spec)

                    asn1Object.setComponentByPosition(
                        idx, component,
                        verifyConstraints=False,
                        matchTags=False, matchConstraints=False
                    )

                component, substrate = decodeFun(substrate, eoo.endOfOctets, allowEoo=True)
                if component is not eoo.endOfOctets:
                    raise error.SubstrateUnderrunError(
                        'No EOO seen before substrate ends'
                    )

            if not namedTypes:
                asn1Object.verifySizeSpec()

        else:
            asn1Spec = asn1Object.componentType
            idx = 0
            while substrate:
                component, substrate = decodeFun(substrate, asn1Spec, allowEoo=True)
                if component is eoo.endOfOctets:
                    break
                asn1Object.setComponentByPosition(
                    idx, component,
                    verifyConstraints=False,
                    matchTags=False, matchConstraints=False
                )
                idx += 1
            else:
                raise error.SubstrateUnderrunError(
                    'No EOO seen before substrate ends'
                )
            asn1Object.verifySizeSpec()

        return asn1Object, substrate