Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
decoder.py2226 linesDownload Raw Back to ber
1#2# This file is part of pyasn1 software.3#4# Copyright (c) 2005-2020, Ilya Etingof <etingof@gmail.com>5# License: https://pyasn1.readthedocs.io/en/latest/license.html6#7import io8import os9import sys10import warnings11 12from pyasn1 import debug13from pyasn1 import error14from pyasn1.codec.ber import eoo15from pyasn1.codec.streaming import asSeekableStream16from pyasn1.codec.streaming import isEndOfStream17from pyasn1.codec.streaming import peekIntoStream18from pyasn1.codec.streaming import readFromStream19from pyasn1.compat import _MISSING20from pyasn1.error import PyAsn1Error21from pyasn1.type import base22from pyasn1.type import char23from pyasn1.type import tag24from pyasn1.type import tagmap25from pyasn1.type import univ26from pyasn1.type import useful27 28__all__ = ['StreamingDecoder', 'Decoder', 'decode']29 30LOG = debug.registerLoggee(__name__, flags=debug.DEBUG_DECODER)31 32noValue = base.noValue33 34SubstrateUnderrunError = error.SubstrateUnderrunError35 36# Maximum number of continuation octets (high-bit set) allowed per OID arc.37# 20 octets allows up to 140-bit integers, supporting UUID-based OIDs38MAX_OID_ARC_CONTINUATION_OCTETS = 2039MAX_NESTING_DEPTH = 10040 41# Maximum number of bytes in a BER length field (8 bytes = up to 2^64-1)42MAX_LENGTH_OCTETS = 843 44 45class AbstractPayloadDecoder(object):46    protoComponent = None47 48    def valueDecoder(self, substrate, asn1Spec,49                     tagSet=None, length=None, state=None,50                     decodeFun=None, substrateFun=None,51                     **options):52        """Decode value with fixed byte length.53 54        The decoder is allowed to consume as many bytes as necessary.55        """56        raise error.PyAsn1Error('SingleItemDecoder not implemented for %s' % (tagSet,))  # TODO: Seems more like an NotImplementedError?57 58    def indefLenValueDecoder(self, substrate, asn1Spec,59                             tagSet=None, length=None, state=None,60                             decodeFun=None, substrateFun=None,61                             **options):62        """Decode value with undefined length.63 64        The decoder is allowed to consume as many bytes as necessary.65        """66        raise error.PyAsn1Error('Indefinite length mode decoder not implemented for %s' % (tagSet,)) # TODO: Seems more like an NotImplementedError?67 68    @staticmethod69    def _passAsn1Object(asn1Object, options):70        if 'asn1Object' not in options:71            options['asn1Object'] = asn1Object72 73        return options74 75 76class AbstractSimplePayloadDecoder(AbstractPayloadDecoder):77    @staticmethod78    def substrateCollector(asn1Object, substrate, length, options):79        for chunk in readFromStream(substrate, length, options):80            yield chunk81 82    def _createComponent(self, asn1Spec, tagSet, value, **options):83        if options.get('native'):84            return value85        elif asn1Spec is None:86            return self.protoComponent.clone(value, tagSet=tagSet)87        elif value is noValue:88            return asn1Spec89        else:90            return asn1Spec.clone(value)91 92 93class RawPayloadDecoder(AbstractSimplePayloadDecoder):94    protoComponent = univ.Any('')95 96    def valueDecoder(self, substrate, asn1Spec,97                     tagSet=None, length=None, state=None,98                     decodeFun=None, substrateFun=None,99                     **options):100        if substrateFun:101            asn1Object = self._createComponent(asn1Spec, tagSet, '', **options)102 103            for chunk in substrateFun(asn1Object, substrate, length, options):104                yield chunk105 106            return107 108        for value in decodeFun(substrate, asn1Spec, tagSet, length, **options):109            yield value110 111    def indefLenValueDecoder(self, substrate, asn1Spec,112                             tagSet=None, length=None, state=None,113                             decodeFun=None, substrateFun=None,114                             **options):115        if substrateFun:116            asn1Object = self._createComponent(asn1Spec, tagSet, '', **options)117 118            for chunk in substrateFun(asn1Object, substrate, length, options):119                yield chunk120 121            return122 123        while True:124            for value in decodeFun(125                    substrate, asn1Spec, tagSet, length,126                    allowEoo=True, **options):127 128                if value is eoo.endOfOctets:129                    return130 131                yield value132 133 134rawPayloadDecoder = RawPayloadDecoder()135 136 137class IntegerPayloadDecoder(AbstractSimplePayloadDecoder):138    protoComponent = univ.Integer(0)139 140    def valueDecoder(self, substrate, asn1Spec,141                     tagSet=None, length=None, state=None,142                     decodeFun=None, substrateFun=None,143                     **options):144 145        if tagSet[0].tagFormat != tag.tagFormatSimple:146            raise error.PyAsn1Error('Simple tag format expected')147 148        for chunk in readFromStream(substrate, length, options):149            if isinstance(chunk, SubstrateUnderrunError):150                yield chunk151 152        if chunk:153            value = int.from_bytes(bytes(chunk), 'big', signed=True)154 155        else:156            value = 0157 158        yield self._createComponent(asn1Spec, tagSet, value, **options)159 160 161class BooleanPayloadDecoder(IntegerPayloadDecoder):162    protoComponent = univ.Boolean(0)163 164    def _createComponent(self, asn1Spec, tagSet, value, **options):165        return IntegerPayloadDecoder._createComponent(166            self, asn1Spec, tagSet, value and 1 or 0, **options)167 168 169class BitStringPayloadDecoder(AbstractSimplePayloadDecoder):170    protoComponent = univ.BitString(())171    supportConstructedForm = True172 173    def valueDecoder(self, substrate, asn1Spec,174                     tagSet=None, length=None, state=None,175                     decodeFun=None, substrateFun=None,176                     **options):177 178        if substrateFun:179            asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options)180 181            for chunk in substrateFun(asn1Object, substrate, length, options):182                yield chunk183 184            return185 186        if not length:187            raise error.PyAsn1Error('Empty BIT STRING substrate')188 189        for chunk in isEndOfStream(substrate):190            if isinstance(chunk, SubstrateUnderrunError):191                yield chunk192 193        if chunk:194            raise error.PyAsn1Error('Empty BIT STRING substrate')195 196        if tagSet[0].tagFormat == tag.tagFormatSimple:  # XXX what tag to check?197 198            for trailingBits in readFromStream(substrate, 1, options):199                if isinstance(trailingBits, SubstrateUnderrunError):200                    yield trailingBits201 202            trailingBits = ord(trailingBits)203            if trailingBits > 7:204                raise error.PyAsn1Error(205                    'Trailing bits overflow %s' % trailingBits206                )207 208            for chunk in readFromStream(substrate, length - 1, options):209                if isinstance(chunk, SubstrateUnderrunError):210                    yield chunk211 212            value = self.protoComponent.fromOctetString(213                chunk, internalFormat=True, padding=trailingBits)214 215            yield self._createComponent(asn1Spec, tagSet, value, **options)216 217            return218 219        if not self.supportConstructedForm:220            raise error.PyAsn1Error('Constructed encoding form prohibited '221                                    'at %s' % self.__class__.__name__)222 223        if LOG:224            LOG('assembling constructed serialization')225 226        # All inner fragments are of the same type, treat them as octet string227        substrateFun = self.substrateCollector228 229        bitString = self.protoComponent.fromOctetString(b'', internalFormat=True)230 231        current_position = substrate.tell()232 233        while substrate.tell() - current_position < length:234            for component in decodeFun(235                    substrate, self.protoComponent, substrateFun=substrateFun,236                    **options):237                if isinstance(component, SubstrateUnderrunError):238                    yield component239 240            trailingBits = component[0]241            if trailingBits > 7:242                raise error.PyAsn1Error(243                    'Trailing bits overflow %s' % trailingBits244                )245 246            bitString = self.protoComponent.fromOctetString(247                component[1:], internalFormat=True,248                prepend=bitString, padding=trailingBits249            )250 251        yield self._createComponent(asn1Spec, tagSet, bitString, **options)252 253    def indefLenValueDecoder(self, substrate, asn1Spec,254                             tagSet=None, length=None, state=None,255                             decodeFun=None, substrateFun=None,256                             **options):257 258        if substrateFun:259            asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options)260 261            for chunk in substrateFun(asn1Object, substrate, length, options):262                yield chunk263 264            return265 266        # All inner fragments are of the same type, treat them as octet string267        substrateFun = self.substrateCollector268 269        bitString = self.protoComponent.fromOctetString(b'', internalFormat=True)270 271        while True:  # loop over fragments272 273            for component in decodeFun(274                    substrate, self.protoComponent, substrateFun=substrateFun,275                    allowEoo=True, **options):276 277                if component is eoo.endOfOctets:278                    break279 280                if isinstance(component, SubstrateUnderrunError):281                    yield component282 283            if component is eoo.endOfOctets:284                break285 286            trailingBits = component[0]287            if trailingBits > 7:288                raise error.PyAsn1Error(289                    'Trailing bits overflow %s' % trailingBits290                )291 292            bitString = self.protoComponent.fromOctetString(293                component[1:], internalFormat=True,294                prepend=bitString, padding=trailingBits295            )296 297        yield self._createComponent(asn1Spec, tagSet, bitString, **options)298 299 300class OctetStringPayloadDecoder(AbstractSimplePayloadDecoder):301    protoComponent = univ.OctetString('')302    supportConstructedForm = True303 304    def valueDecoder(self, substrate, asn1Spec,305                     tagSet=None, length=None, state=None,306                     decodeFun=None, substrateFun=None,307                     **options):308        if substrateFun:309            asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options)310 311            for chunk in substrateFun(asn1Object, substrate, length, options):312                yield chunk313 314            return315 316        if tagSet[0].tagFormat == tag.tagFormatSimple:  # XXX what tag to check?317            for chunk in readFromStream(substrate, length, options):318                if isinstance(chunk, SubstrateUnderrunError):319                    yield chunk320 321            yield self._createComponent(asn1Spec, tagSet, chunk, **options)322 323            return324 325        if not self.supportConstructedForm:326            raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__)327 328        if LOG:329            LOG('assembling constructed serialization')330 331        # All inner fragments are of the same type, treat them as octet string332        substrateFun = self.substrateCollector333 334        header = b''335 336        original_position = substrate.tell()337        # head = popSubstream(substrate, length)338        while substrate.tell() - original_position < length:339            for component in decodeFun(340                    substrate, self.protoComponent, substrateFun=substrateFun,341                    **options):342                if isinstance(component, SubstrateUnderrunError):343                    yield component344 345            header += component346 347        yield self._createComponent(asn1Spec, tagSet, header, **options)348 349    def indefLenValueDecoder(self, substrate, asn1Spec,350                             tagSet=None, length=None, state=None,351                             decodeFun=None, substrateFun=None,352                             **options):353        if substrateFun and substrateFun is not self.substrateCollector:354            asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options)355 356            for chunk in substrateFun(asn1Object, substrate, length, options):357                yield chunk358 359            return360 361        # All inner fragments are of the same type, treat them as octet string362        substrateFun = self.substrateCollector363 364        header = b''365 366        while True:  # loop over fragments367 368            for component in decodeFun(369                    substrate, self.protoComponent, substrateFun=substrateFun,370                    allowEoo=True, **options):371 372                if isinstance(component, SubstrateUnderrunError):373                    yield component374 375                if component is eoo.endOfOctets:376                    break377 378            if component is eoo.endOfOctets:379                break380 381            header += component382 383        yield self._createComponent(asn1Spec, tagSet, header, **options)384 385 386class NullPayloadDecoder(AbstractSimplePayloadDecoder):387    protoComponent = univ.Null('')388 389    def valueDecoder(self, substrate, asn1Spec,390                     tagSet=None, length=None, state=None,391                     decodeFun=None, substrateFun=None,392                     **options):393 394        if tagSet[0].tagFormat != tag.tagFormatSimple:395            raise error.PyAsn1Error('Simple tag format expected')396 397        for chunk in readFromStream(substrate, length, options):398            if isinstance(chunk, SubstrateUnderrunError):399                yield chunk400 401        component = self._createComponent(asn1Spec, tagSet, '', **options)402 403        if chunk:404            raise error.PyAsn1Error('Unexpected %d-octet substrate for Null' % length)405 406        yield component407 408 409class ObjectIdentifierPayloadDecoder(AbstractSimplePayloadDecoder):410    protoComponent = univ.ObjectIdentifier(())411 412    def valueDecoder(self, substrate, asn1Spec,413                     tagSet=None, length=None, state=None,414                     decodeFun=None, substrateFun=None,415                     **options):416        if tagSet[0].tagFormat != tag.tagFormatSimple:417            raise error.PyAsn1Error('Simple tag format expected')418 419        for chunk in readFromStream(substrate, length, options):420            if isinstance(chunk, SubstrateUnderrunError):421                yield chunk422 423        if not chunk:424            raise error.PyAsn1Error('Empty substrate')425 426        oid = ()427        index = 0428        substrateLen = len(chunk)429        while index < substrateLen:430            subId = chunk[index]431            index += 1432            if subId < 128:433                oid += (subId,)434            elif subId > 128:435                # Construct subid from a number of octets436                nextSubId = subId437                subId = 0438                continuationOctetCount = 0439                while nextSubId >= 128:440                    continuationOctetCount += 1441                    if continuationOctetCount > MAX_OID_ARC_CONTINUATION_OCTETS:442                        raise error.PyAsn1Error(443                            'OID arc exceeds maximum continuation octets limit (%d) '444                            'at position %d' % (MAX_OID_ARC_CONTINUATION_OCTETS, index)445                        )446                    subId = (subId << 7) + (nextSubId & 0x7F)447                    if index >= substrateLen:448                        raise error.SubstrateUnderrunError(449                            'Short substrate for sub-OID past %s' % (oid,)450                        )451                    nextSubId = chunk[index]452                    index += 1453                oid += ((subId << 7) + nextSubId,)454            elif subId == 128:455                # ASN.1 spec forbids leading zeros (0x80) in OID456                # encoding, tolerating it opens a vulnerability. See457                # https://www.esat.kuleuven.be/cosic/publications/article-1432.pdf458                # page 7459                raise error.PyAsn1Error('Invalid octet 0x80 in OID encoding')460 461        # Decode two leading arcs462        if 0 <= oid[0] <= 39:463            oid = (0,) + oid464        elif 40 <= oid[0] <= 79:465            oid = (1, oid[0] - 40) + oid[1:]466        elif oid[0] >= 80:467            oid = (2, oid[0] - 80) + oid[1:]468        else:469            raise error.PyAsn1Error('Malformed first OID octet: %s' % chunk[0])470 471        yield self._createComponent(asn1Spec, tagSet, oid, **options)472 473 474class RelativeOIDPayloadDecoder(AbstractSimplePayloadDecoder):475    protoComponent = univ.RelativeOID(())476 477    def valueDecoder(self, substrate, asn1Spec,478                     tagSet=None, length=None, state=None,479                     decodeFun=None, substrateFun=None,480                     **options):481        if tagSet[0].tagFormat != tag.tagFormatSimple:482            raise error.PyAsn1Error('Simple tag format expected')483 484        for chunk in readFromStream(substrate, length, options):485            if isinstance(chunk, SubstrateUnderrunError):486                yield chunk487 488        if not chunk:489            raise error.PyAsn1Error('Empty substrate')490 491        reloid = ()492        index = 0493        substrateLen = len(chunk)494        while index < substrateLen:495            subId = chunk[index]496            index += 1497            if subId < 128:498                reloid += (subId,)499            elif subId > 128:500                # Construct subid from a number of octets501                nextSubId = subId502                subId = 0503                continuationOctetCount = 0504                while nextSubId >= 128:505                    continuationOctetCount += 1506                    if continuationOctetCount > MAX_OID_ARC_CONTINUATION_OCTETS:507                        raise error.PyAsn1Error(508                            'RELATIVE-OID arc exceeds maximum continuation octets limit (%d) '509                            'at position %d' % (MAX_OID_ARC_CONTINUATION_OCTETS, index)510                        )511                    subId = (subId << 7) + (nextSubId & 0x7F)512                    if index >= substrateLen:513                        raise error.SubstrateUnderrunError(514                            'Short substrate for sub-OID past %s' % (reloid,)515                        )516                    nextSubId = chunk[index]517                    index += 1518                reloid += ((subId << 7) + nextSubId,)519            elif subId == 128:520                # ASN.1 spec forbids leading zeros (0x80) in OID521                # encoding, tolerating it opens a vulnerability. See522                # https://www.esat.kuleuven.be/cosic/publications/article-1432.pdf523                # page 7524                raise error.PyAsn1Error('Invalid octet 0x80 in RELATIVE-OID encoding')525 526        yield self._createComponent(asn1Spec, tagSet, reloid, **options)527 528 529class RealPayloadDecoder(AbstractSimplePayloadDecoder):530    protoComponent = univ.Real()531 532    def valueDecoder(self, substrate, asn1Spec,533                     tagSet=None, length=None, state=None,534                     decodeFun=None, substrateFun=None,535                     **options):536        if tagSet[0].tagFormat != tag.tagFormatSimple:537            raise error.PyAsn1Error('Simple tag format expected')538 539        for chunk in readFromStream(substrate, length, options):540            if isinstance(chunk, SubstrateUnderrunError):541                yield chunk542 543        if not chunk:544            yield self._createComponent(asn1Spec, tagSet, 0.0, **options)545            return546 547        fo = chunk[0]548        chunk = chunk[1:]549        if fo & 0x80:  # binary encoding550            if not chunk:551                raise error.PyAsn1Error("Incomplete floating-point value")552 553            if LOG:554                LOG('decoding binary encoded REAL')555 556            n = (fo & 0x03) + 1557 558            if n == 4:559                n = chunk[0]560                chunk = chunk[1:]561 562            eo, chunk = chunk[:n], chunk[n:]563 564            if not eo or not chunk:565                raise error.PyAsn1Error('Real exponent screwed')566 567            e = eo[0] & 0x80 and -1 or 0568 569            while eo:  # exponent570                e <<= 8571                e |= eo[0]572                eo = eo[1:]573 574            b = fo >> 4 & 0x03  # base bits575 576            if b > 2:577                raise error.PyAsn1Error('Illegal Real base')578 579            if b == 1:  # encbase = 8580                e *= 3581 582            elif b == 2:  # encbase = 16583                e *= 4584            p = 0585 586            while chunk:  # value587                p <<= 8588                p |= chunk[0]589                chunk = chunk[1:]590 591            if fo & 0x40:  # sign bit592                p = -p593 594            sf = fo >> 2 & 0x03  # scale bits595            p *= 2 ** sf596            value = (p, 2, e)597 598        elif fo & 0x40:  # infinite value599            if LOG:600                LOG('decoding infinite REAL')601 602            value = fo & 0x01 and '-inf' or 'inf'603 604        elif fo & 0xc0 == 0:  # character encoding605            if not chunk:606                raise error.PyAsn1Error("Incomplete floating-point value")607 608            if LOG:609                LOG('decoding character encoded REAL')610 611            try:612                if fo & 0x3 == 0x1:  # NR1613                    value = (int(chunk), 10, 0)614 615                elif fo & 0x3 == 0x2:  # NR2616                    value = float(chunk)617 618                elif fo & 0x3 == 0x3:  # NR3619                    value = float(chunk)620 621                else:622                    raise error.SubstrateUnderrunError(623                        'Unknown NR (tag %s)' % fo624                    )625 626            except ValueError:627                raise error.SubstrateUnderrunError(628                    'Bad character Real syntax'629                )630 631        else:632            raise error.SubstrateUnderrunError(633                'Unknown encoding (tag %s)' % fo634            )635 636        yield self._createComponent(asn1Spec, tagSet, value, **options)637 638 639class AbstractConstructedPayloadDecoder(AbstractPayloadDecoder):640    protoComponent = None641 642 643class ConstructedPayloadDecoderBase(AbstractConstructedPayloadDecoder):644    protoRecordComponent = None645    protoSequenceComponent = None646 647    def _getComponentTagMap(self, asn1Object, idx):648        raise NotImplementedError649 650    def _getComponentPositionByType(self, asn1Object, tagSet, idx):651        raise NotImplementedError652 653    def _decodeComponentsSchemaless(654            self, substrate, tagSet=None, decodeFun=None,655            length=None, **options):656 657        asn1Object = None658 659        components = []660        componentTypes = set()661 662        original_position = substrate.tell()663 664        while length == -1 or substrate.tell() < original_position + length:665            for component in decodeFun(substrate, **options):666                if isinstance(component, SubstrateUnderrunError):667                    yield component668 669            if length == -1 and component is eoo.endOfOctets:670                break671 672            components.append(component)673            componentTypes.add(component.tagSet)674 675            # Now we have to guess is it SEQUENCE/SET or SEQUENCE OF/SET OF676            # The heuristics is:677            # * 1+ components of different types -> likely SEQUENCE/SET678            # * otherwise -> likely SEQUENCE OF/SET OF679            if len(componentTypes) > 1:680                protoComponent = self.protoRecordComponent681 682            else:683                protoComponent = self.protoSequenceComponent684 685            asn1Object = protoComponent.clone(686                # construct tagSet from base tag from prototype ASN.1 object687                # and additional tags recovered from the substrate688                tagSet=tag.TagSet(protoComponent.tagSet.baseTag, *tagSet.superTags)689            )690 691        if LOG:692            LOG('guessed %r container type (pass `asn1Spec` to guide the '693                'decoder)' % asn1Object)694 695        for idx, component in enumerate(components):696            asn1Object.setComponentByPosition(697                idx, component,698                verifyConstraints=False,699                matchTags=False, matchConstraints=False700            )701 702        yield asn1Object703 704    def valueDecoder(self, substrate, asn1Spec,705                     tagSet=None, length=None, state=None,706                     decodeFun=None, substrateFun=None,707                     **options):708        if tagSet[0].tagFormat != tag.tagFormatConstructed:709            raise error.PyAsn1Error('Constructed tag format expected')710 711        original_position = substrate.tell()712 713        if substrateFun:714            if asn1Spec is not None:715                asn1Object = asn1Spec.clone()716 717            elif self.protoComponent is not None:718                asn1Object = self.protoComponent.clone(tagSet=tagSet)719 720            else:721                asn1Object = self.protoRecordComponent, self.protoSequenceComponent722 723            for chunk in substrateFun(asn1Object, substrate, length, options):724                yield chunk725 726            return727 728        if asn1Spec is None:729            for asn1Object in self._decodeComponentsSchemaless(730                    substrate, tagSet=tagSet, decodeFun=decodeFun,731                    length=length, **options):732                if isinstance(asn1Object, SubstrateUnderrunError):733                    yield asn1Object734 735            if substrate.tell() < original_position + length:736                if LOG:737                    for trailing in readFromStream(substrate, context=options):738                        if isinstance(trailing, SubstrateUnderrunError):739                            yield trailing740 741                    LOG('Unused trailing %d octets encountered: %s' % (742                        len(trailing), debug.hexdump(trailing)))743 744            yield asn1Object745 746            return747 748        asn1Object = asn1Spec.clone()749        asn1Object.clear()750 751        options = self._passAsn1Object(asn1Object, options)752 753        if asn1Spec.typeId in (univ.Sequence.typeId, univ.Set.typeId):754 755            namedTypes = asn1Spec.componentType756 757            isSetType = asn1Spec.typeId == univ.Set.typeId758            isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault759 760            if LOG:761                LOG('decoding %sdeterministic %s type %r chosen by type ID' % (762                    not isDeterministic and 'non-' or '', isSetType and 'SET' or '',763                    asn1Spec))764 765            seenIndices = set()766            idx = 0767            while substrate.tell() - original_position < length:768                if not namedTypes:769                    componentType = None770 771                elif isSetType:772                    componentType = namedTypes.tagMapUnique773 774                else:775                    try:776                        if isDeterministic:777                            componentType = namedTypes[idx].asn1Object778 779                        elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:780                            componentType = namedTypes.getTagMapNearPosition(idx)781 782                        else:783                            componentType = namedTypes[idx].asn1Object784 785                    except IndexError:786                        raise error.PyAsn1Error(787                            'Excessive components decoded at %r' % (asn1Spec,)788                        )789 790                for component in decodeFun(substrate, componentType, **options):791                    if isinstance(component, SubstrateUnderrunError):792                        yield component793 794                if not isDeterministic and namedTypes:795                    if isSetType:796                        idx = namedTypes.getPositionByType(component.effectiveTagSet)797 798                    elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:799                        idx = namedTypes.getPositionNearType(component.effectiveTagSet, idx)800 801                asn1Object.setComponentByPosition(802                    idx, component,803                    verifyConstraints=False,804                    matchTags=False, matchConstraints=False805                )806 807                seenIndices.add(idx)808                idx += 1809 810            if LOG:811                LOG('seen component indices %s' % seenIndices)812 813            if namedTypes:814                if not namedTypes.requiredComponents.issubset(seenIndices):815                    raise error.PyAsn1Error(816                        'ASN.1 object %s has uninitialized '817                        'components' % asn1Object.__class__.__name__)818 819                if  namedTypes.hasOpenTypes:820 821                    openTypes = options.get('openTypes', {})822 823                    if LOG:824                        LOG('user-specified open types map:')825 826                        for k, v in openTypes.items():827                            LOG('%s -> %r' % (k, v))828 829                    if openTypes or options.get('decodeOpenTypes', False):830 831                        for idx, namedType in enumerate(namedTypes.namedTypes):832                            if not namedType.openType:833                                continue834 835                            if namedType.isOptional and not asn1Object.getComponentByPosition(idx).isValue:836                                continue837 838                            governingValue = asn1Object.getComponentByName(839                                namedType.openType.name840                            )841 842                            try:843                                openType = openTypes[governingValue]844 845                            except KeyError:846 847                                if LOG:848                                    LOG('default open types map of component '849                                        '"%s.%s" governed by component "%s.%s"'850                                        ':' % (asn1Object.__class__.__name__,851                                               namedType.name,852                                               asn1Object.__class__.__name__,853                                               namedType.openType.name))854 855                                    for k, v in namedType.openType.items():856                                        LOG('%s -> %r' % (k, v))857 858                                try:859                                    openType = namedType.openType[governingValue]860 861                                except KeyError:862                                    if LOG:863                                        LOG('failed to resolve open type by governing '864                                            'value %r' % (governingValue,))865                                    continue866 867                            if LOG:868                                LOG('resolved open type %r by governing '869                                    'value %r' % (openType, governingValue))870 871                            containerValue = asn1Object.getComponentByPosition(idx)872 873                            if containerValue.typeId in (874                                    univ.SetOf.typeId, univ.SequenceOf.typeId):875 876                                for pos, containerElement in enumerate(877                                        containerValue):878 879                                    stream = asSeekableStream(containerValue[pos].asOctets())880 881                                    for component in decodeFun(stream, asn1Spec=openType, **options):882                                        if isinstance(component, SubstrateUnderrunError):883                                            yield component884 885                                    containerValue[pos] = component886 887                            else:888                                stream = asSeekableStream(asn1Object.getComponentByPosition(idx).asOctets())889 890                                for component in decodeFun(stream, asn1Spec=openType, **options):891                                    if isinstance(component, SubstrateUnderrunError):892                                        yield component893 894                                asn1Object.setComponentByPosition(idx, component)895 896            else:897                inconsistency = asn1Object.isInconsistent898                if inconsistency:899                    raise error.PyAsn1Error(900                        f"ASN.1 object {asn1Object.__class__.__name__} is inconsistent")901 902        else:903            componentType = asn1Spec.componentType904 905            if LOG:906                LOG('decoding type %r chosen by given `asn1Spec`' % componentType)907 908            idx = 0909 910            while substrate.tell() - original_position < length:911                for component in decodeFun(substrate, componentType, **options):912                    if isinstance(component, SubstrateUnderrunError):913                        yield component914 915                asn1Object.setComponentByPosition(916                    idx, component,917                    verifyConstraints=False,918                    matchTags=False, matchConstraints=False919                )920 921                idx += 1922 923        yield asn1Object924 925    def indefLenValueDecoder(self, substrate, asn1Spec,926                             tagSet=None, length=None, state=None,927                             decodeFun=None, substrateFun=None,928                             **options):929        if tagSet[0].tagFormat != tag.tagFormatConstructed:930            raise error.PyAsn1Error('Constructed tag format expected')931 932        if substrateFun is not None:933            if asn1Spec is not None:934                asn1Object = asn1Spec.clone()935 936            elif self.protoComponent is not None:937                asn1Object = self.protoComponent.clone(tagSet=tagSet)938 939            else:940                asn1Object = self.protoRecordComponent, self.protoSequenceComponent941 942            for chunk in substrateFun(asn1Object, substrate, length, options):943                yield chunk944 945            return946 947        if asn1Spec is None:948            for asn1Object in self._decodeComponentsSchemaless(949                    substrate, tagSet=tagSet, decodeFun=decodeFun,950                    length=length, **dict(options, allowEoo=True)):951                if isinstance(asn1Object, SubstrateUnderrunError):952                    yield asn1Object953 954            yield asn1Object955 956            return957 958        asn1Object = asn1Spec.clone()959        asn1Object.clear()960 961        options = self._passAsn1Object(asn1Object, options)962 963        if asn1Spec.typeId in (univ.Sequence.typeId, univ.Set.typeId):964 965            namedTypes = asn1Object.componentType966 967            isSetType = asn1Object.typeId == univ.Set.typeId968            isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault969 970            if LOG:971                LOG('decoding %sdeterministic %s type %r chosen by type ID' % (972                    not isDeterministic and 'non-' or '', isSetType and 'SET' or '',973                    asn1Spec))974 975            seenIndices = set()976 977            idx = 0978 979            while True:  # loop over components980                if len(namedTypes) <= idx:981                    asn1Spec = None982 983                elif isSetType:984                    asn1Spec = namedTypes.tagMapUnique985 986                else:987                    try:988                        if isDeterministic:989                            asn1Spec = namedTypes[idx].asn1Object990 991                        elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:992                            asn1Spec = namedTypes.getTagMapNearPosition(idx)993 994                        else:995                            asn1Spec = namedTypes[idx].asn1Object996 997                    except IndexError:998                        raise error.PyAsn1Error(999                            'Excessive components decoded at %r' % (asn1Object,)1000                        )1001 1002                for component in decodeFun(substrate, asn1Spec, allowEoo=True, **options):1003 1004                    if isinstance(component, SubstrateUnderrunError):1005                        yield component1006 1007                    if component is eoo.endOfOctets:1008                        break1009 1010                if component is eoo.endOfOctets:1011                    break1012 1013                if not isDeterministic and namedTypes:1014                    if isSetType:1015                        idx = namedTypes.getPositionByType(component.effectiveTagSet)1016 1017                    elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:1018                        idx = namedTypes.getPositionNearType(component.effectiveTagSet, idx)1019 1020                asn1Object.setComponentByPosition(1021                    idx, component,1022                    verifyConstraints=False,1023                    matchTags=False, matchConstraints=False1024                )1025 1026                seenIndices.add(idx)1027                idx += 11028 1029            if LOG:1030                LOG('seen component indices %s' % seenIndices)1031 1032            if namedTypes:1033                if not namedTypes.requiredComponents.issubset(seenIndices):1034                    raise error.PyAsn1Error(1035                        'ASN.1 object %s has uninitialized '1036                        'components' % asn1Object.__class__.__name__)1037 1038                if namedTypes.hasOpenTypes:1039 1040                    openTypes = options.get('openTypes', {})1041 1042                    if LOG:1043                        LOG('user-specified open types map:')1044 1045                        for k, v in openTypes.items():1046                            LOG('%s -> %r' % (k, v))1047 1048                    if openTypes or options.get('decodeOpenTypes', False):1049 1050                        for idx, namedType in enumerate(namedTypes.namedTypes):1051                            if not namedType.openType:1052                                continue1053 1054                            if namedType.isOptional and not asn1Object.getComponentByPosition(idx).isValue:1055                                continue1056 1057                            governingValue = asn1Object.getComponentByName(1058                                namedType.openType.name1059                            )1060 1061                            try:1062                                openType = openTypes[governingValue]1063 1064                            except KeyError:1065 1066                                if LOG:1067                                    LOG('default open types map of component '1068                                        '"%s.%s" governed by component "%s.%s"'1069                                        ':' % (asn1Object.__class__.__name__,1070                                               namedType.name,1071                                               asn1Object.__class__.__name__,1072                                               namedType.openType.name))1073 1074                                    for k, v in namedType.openType.items():1075                                        LOG('%s -> %r' % (k, v))1076 1077                                try:1078                                    openType = namedType.openType[governingValue]1079 1080                                except KeyError:1081                                    if LOG:1082                                        LOG('failed to resolve open type by governing '1083                                            'value %r' % (governingValue,))1084                                    continue1085 1086                            if LOG:1087                                LOG('resolved open type %r by governing '1088                                    'value %r' % (openType, governingValue))1089 1090                            containerValue = asn1Object.getComponentByPosition(idx)1091 1092                            if containerValue.typeId in (1093                                    univ.SetOf.typeId, univ.SequenceOf.typeId):1094 1095                                for pos, containerElement in enumerate(1096                                        containerValue):1097 1098                                    stream = asSeekableStream(containerValue[pos].asOctets())1099 1100                                    for component in decodeFun(stream, asn1Spec=openType,1101                                                               **dict(options, allowEoo=True)):1102                                        if isinstance(component, SubstrateUnderrunError):1103                                            yield component1104 1105                                        if component is eoo.endOfOctets:1106                                            break1107 1108                                    containerValue[pos] = component1109 1110                            else:1111                                stream = asSeekableStream(asn1Object.getComponentByPosition(idx).asOctets())1112                                for component in decodeFun(stream, asn1Spec=openType,1113                                                           **dict(options, allowEoo=True)):1114                                    if isinstance(component, SubstrateUnderrunError):1115                                        yield component1116 1117                                    if component is eoo.endOfOctets:1118                                        break1119 1120                                    asn1Object.setComponentByPosition(idx, component)1121 1122                else:1123                    inconsistency = asn1Object.isInconsistent1124                    if inconsistency:1125                        raise error.PyAsn1Error(1126                            f"ASN.1 object {asn1Object.__class__.__name__} is inconsistent")1127 1128        else:1129            componentType = asn1Spec.componentType1130 1131            if LOG:1132                LOG('decoding type %r chosen by given `asn1Spec`' % componentType)1133 1134            idx = 01135 1136            while True:1137 1138                for component in decodeFun(1139                        substrate, componentType, allowEoo=True, **options):1140 1141                    if isinstance(component, SubstrateUnderrunError):1142                        yield component1143 1144                    if component is eoo.endOfOctets:1145                        break1146 1147                if component is eoo.endOfOctets:1148                    break1149 1150                asn1Object.setComponentByPosition(1151                    idx, component,1152                    verifyConstraints=False,1153                    matchTags=False, matchConstraints=False1154                )1155 1156                idx += 11157 1158        yield asn1Object1159 1160 1161class SequenceOrSequenceOfPayloadDecoder(ConstructedPayloadDecoderBase):1162    protoRecordComponent = univ.Sequence()1163    protoSequenceComponent = univ.SequenceOf()1164 1165 1166class SequencePayloadDecoder(SequenceOrSequenceOfPayloadDecoder):1167    protoComponent = univ.Sequence()1168 1169 1170class SequenceOfPayloadDecoder(SequenceOrSequenceOfPayloadDecoder):1171    protoComponent = univ.SequenceOf()1172 1173 1174class SetOrSetOfPayloadDecoder(ConstructedPayloadDecoderBase):1175    protoRecordComponent = univ.Set()1176    protoSequenceComponent = univ.SetOf()1177 1178 1179class SetPayloadDecoder(SetOrSetOfPayloadDecoder):1180    protoComponent = univ.Set()1181 1182 1183class SetOfPayloadDecoder(SetOrSetOfPayloadDecoder):1184    protoComponent = univ.SetOf()1185 1186 1187class ChoicePayloadDecoder(ConstructedPayloadDecoderBase):1188    protoComponent = univ.Choice()1189 1190    def valueDecoder(self, substrate, asn1Spec,1191                     tagSet=None, length=None, state=None,1192                     decodeFun=None, substrateFun=None,1193                     **options):1194        if asn1Spec is None:1195            asn1Object = self.protoComponent.clone(tagSet=tagSet)1196 1197        else:1198            asn1Object = asn1Spec.clone()1199 1200        if substrateFun:

Showing the first 1,200 of 2226 lines. Download the file for the rest.

codekingpro/portable-devtools · Team Ai