Example #1
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 #2
0
 def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
                  state, decodeFun, substrateFun):
     head, tail = substrate[:length], substrate[length:]
     if tagSet[0][1] == tag.tagFormatSimple:    # XXX what tag to check?
         if not head:
             raise error.PyAsn1Error('Empty substrate')
         trailingBits = oct2int(head[0])
         if trailingBits > 7:
             raise error.PyAsn1Error(
                 'Trailing bits overflow %s' % trailingBits
                 )
         head = head[1:]
         lsb = p = 0; l = len(head)-1; b = ()
         while p <= l:
             if p == l:
                 lsb = trailingBits
             j = 7                    
             o = oct2int(head[p])
             while j >= lsb:
                 b = b + ((o>>j)&0x01,)
                 j = j - 1
             p = p + 1
         return self._createComponent(asn1Spec, tagSet, b), tail
     r = self._createComponent(asn1Spec, tagSet, ())
     if substrateFun:
         return substrateFun(r, substrate, length)
     while head:
         component, head = decodeFun(head)
         r = r + component
     return r, tail
Example #3
0
 def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
                  length, state, decodeFun, substrateFun):
     head, tail = substrate[:length], substrate[length:]
     if not head:
         raise error.SubstrateUnderrunError('Short substrate for Real')
     fo = oct2int(head[0]); head = head[1:]
     if fo & 0x40:  # infinite value
         value = fo & 0x01 and '-inf' or 'inf'
     elif 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 & 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'
                 )
     elif fo & 0xc0 == 0x40:  # special real value
         pass
     else:
         raise error.SubstrateUnderrunError(
             'Unknown encoding (tag %s)' % fo
             )
     return self._createComponent(asn1Spec, tagSet, value), tail
Example #4
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')
     if head in self.precomputedValues:
         value = self.precomputedValues[head]
     else:
         firstOctet = oct2int(head[0])
         if firstOctet & 0x80:
             value = -1
         else:
             value = 0
         for octet in head:
             value = value << 8 | oct2int(octet)
     return self._createComponent(asn1Spec, tagSet, value), tail
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')
     byte = oct2int(head[0])
     # CER/DER specifies encoding of TRUE as 0xFF and FALSE as 0x0, while
     # BER allows any non-zero value as TRUE; cf. sections 8.2.2. and 11.1 
     # in http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
     if byte == 0xff:
         value = 1
     elif byte == 0x00:
         value = 0
     else:
         raise error.PyAsn1Error('Boolean CER violation: %s' % byte)
     return self._createComponent(asn1Spec, tagSet, value), tail
Example #6
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')
     byte = oct2int(head[0])
     # CER/DER specifies encoding of TRUE as 0xFF and FALSE as 0x0, while
     # BER allows any non-zero value as TRUE; cf. sections 8.2.2. and 11.1
     # in http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
     if byte == 0xff:
         value = 1
     elif byte == 0x00:
         value = 0
     else:
         raise error.PyAsn1Error('Boolean CER violation: %s' % byte)
     return self._createComponent(asn1Spec, tagSet, value), tail
Example #7
0
 def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
     if value.isPlusInfinity():
         return int2oct(0x40), 0
     if value.isMinusInfinity():
         return int2oct(0x41), 0
     m, b, e = value
     if not m:
         return null, 0
     if b == 10:
         return str2octs('\x03%dE%s%d' % (m, e == 0 and '+' or '', e)), 0
     elif b == 2:
         fo = 0x80                 # binary enoding
         if m < 0:
             fo = fo | 0x40  # sign bit
             m = -m
         while int(m) != m: # drop floating point
             m *= 2
             e -= 1
         while m & 0x1 == 0: # mantissa normalization
             m >>= 1
             e += 1
         eo = null
         while e not in (0, -1):
             eo = int2oct(e&0xff) + eo
             e >>= 8
         if e == 0 and eo and oct2int(eo[0]) & 0x80:
             eo = int2oct(0) + eo
         n = len(eo)
         if n > 0xff:
             raise error.PyAsn1Error('Real exponent overflow')
         if n == 1:
             pass
         elif n == 2:
             fo |= 1
         elif n == 3:
             fo |= 2
         else:
             fo |= 3
             eo = int2oct(n//0xff+1) + eo
         po = null
         while m:
             po = int2oct(m&0xff) + po
             m >>= 8
         substrate = int2oct(fo) + eo + po
         return substrate, 0
     else:
         raise error.PyAsn1Error('Prohibited Real base %s' % b)
Example #8
0
 def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
     if value.isPlusInfinity():
         return int2oct(0x40), 0
     if value.isMinusInfinity():
         return int2oct(0x41), 0
     m, b, e = value
     if not m:
         return null, 0
     if b == 10:
         return str2octs('\x03%dE%s%d' % (m, e == 0 and '+' or '', e)), 0
     elif b == 2:
         fo = 0x80  # binary enoding
         if m < 0:
             fo = fo | 0x40  # sign bit
             m = -m
         while int(m) != m:  # drop floating point
             m *= 2
             e -= 1
         while m & 0x1 == 0:  # mantissa normalization
             m >>= 1
             e += 1
         eo = null
         while e not in (0, -1):
             eo = int2oct(e & 0xff) + eo
             e >>= 8
         if e == 0 and eo and oct2int(eo[0]) & 0x80:
             eo = int2oct(0) + eo
         n = len(eo)
         if n > 0xff:
             raise error.PyAsn1Error('Real exponent overflow')
         if n == 1:
             pass
         elif n == 2:
             fo |= 1
         elif n == 3:
             fo |= 2
         else:
             fo |= 3
             eo = int2oct(n // 0xff + 1) + eo
         po = null
         while m:
             po = int2oct(m & 0xff) + po
             m >>= 8
         substrate = int2oct(fo) + eo + po
         return substrate, 0
     else:
         raise error.PyAsn1Error('Prohibited Real base %s' % b)
Example #9
0
 def __call__(self, substrate, asn1Spec=None, tagSet=None,
              length=None, state=stDecodeTag, recursiveFlag=1,
              substrateFun=None):
     if debug.logger & debug.flagDecoder:
         debug.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)))
     fullSubstrate = substrate
     while state != stStop:
         if state == stDecodeTag:
             # Decode tag
             if not substrate:
                 raise error.SubstrateUnderrunError(
                     'Short octet stream on tag decoding'
                     )
             if not isOctetsType(substrate) and \
                not isinstance(substrate, univ.OctetString):
                 raise error.PyAsn1Error('Bad octet stream type')
             
             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[:length])))
         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
             if debug.logger and debug.logger & debug.flagDecoder:
                 debug.logger('codec %s chosen by a built-in type, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state == stDecodeValue and 'value' or 'as explicit tag'))
                 debug.scope.push(concreteDecoder is None and '?' or concreteDecoder.protoComponent.__class__.__name__)
         if state == stGetValueDecoderByAsn1Spec:
             if isinstance(asn1Spec, (dict, tagmap.TagMap)):
                 if tagSet in asn1Spec:
                     __chosenSpec = asn1Spec[tagSet]
                 else:
                     __chosenSpec = None
                 if debug.logger and debug.logger & debug.flagDecoder:
                     debug.logger('candidate ASN.1 spec is a map of:')
                     for t, v in asn1Spec.getPosMap().items():
                         debug.logger('  %r -> %s' % (t, v.__class__.__name__))
                     if asn1Spec.getNegMap():
                         debug.logger('but neither of: ')
                         for i in asn1Spec.getNegMap().items():
                             debug.logger('  %r -> %s' % (t, v.__class__.__name__))
                     debug.logger('new candidate ASN.1 spec is %s, chosen by %r' % (__chosenSpec is None and '<none>' or __chosenSpec.__class__.__name__, tagSet))
             else:
                 __chosenSpec = asn1Spec
                 debug.logger and debug.logger & debug.flagDecoder and debug.logger('candidate ASN.1 spec is %s' % asn1Spec.__class__.__name__)
             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]
                     debug.logger and debug.logger & debug.flagDecoder and debug.logger('value decoder chosen for an ambiguous type by type ID %s' % (__chosenSpec.typeId,))
                 elif baseTagSet in self.__tagMap:
                     # base type or tagged subtype
                     concreteDecoder = self.__tagMap[baseTagSet]
                     debug.logger and debug.logger & debug.flagDecoder and debug.logger('value decoder chosen by base %r' % (baseTagSet,))
                 else:
                     concreteDecoder = None
                 if concreteDecoder:
                     asn1Spec = __chosenSpec
                     state = stDecodeValue
                 else:
                     state = stTryAsExplicitTag
             elif tagSet == self.__endOfOctetsTagSet:
                 concreteDecoder = self.__tagMap[tagSet]
                 state = stDecodeValue
                 debug.logger and debug.logger & debug.flagDecoder and debug.logger('end-of-octets found')
             else:
                 concreteDecoder = None
                 state = stTryAsExplicitTag
             if debug.logger and debug.logger & debug.flagDecoder:
                 debug.logger('codec %s chosen by ASN.1 spec, decoding %s' % (state == stDecodeValue and concreteDecoder.__class__.__name__ or "<none>", state == stDecodeValue and 'value' or 'as explicit tag'))
                 debug.scope.push(__chosenSpec is None and '?' or __chosenSpec.__class__.__name__)
         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:                    
                 concreteDecoder = None
                 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 == 0 and not substrateFun: # legacy
                 substrateFun = lambda a,b,c: (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
             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)
                 )
     if debug.logger and debug.logger & debug.flagDecoder:
         debug.scope.pop()
         debug.logger('decoder left scope %s, call completed' % debug.scope)
     return value, substrate