Exemple #1
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.append((o >> j) & 0x01)
                 j -= 1
             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, self.protoComponent)
         r = r + component
     return r, tail
Exemple #2
0
    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
                     state, decodeFun):
        substrate = substrate[:length]
        if not substrate:
            raise error.PyAsn1Error('Empty substrate')
        oid = (); index = 0
        # Get the first subid
        subId = oct2int(substrate[index])
        oid = oid + divmod(subId, 40)

        index = index + 1
        substrateLen = len(substrate)

        while index < substrateLen:
            subId = oct2int(substrate[index])
            if subId < 128:
                oid = oid + (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 = oct2int(substrate[index])
                if index == substrateLen:
                    raise error.SubstrateUnderrunError(
                        'Short substrate for OID %s' % oid
                        )
                subId = (subId << 7) + nextSubId
                oid = oid + (subId,)
                index = index + 1
        return self._createComponent(asn1Spec, tagSet, oid), substrate[index:]
Exemple #3
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.append((o>>j)&0x01)
                 j -= 1
             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, self.protoComponent)
         r = r + component
     return r, tail
Exemple #4
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 encoding
         if not head:
             raise error.PyAsn1Error("Incomplete floating-point value")
         n = (fo & 0x03) + 1
         if n == 4:
             n = oct2int(head[0])
             head = head[1:]
         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:]
         b = fo >> 4 & 0x03  # base bits
         if b > 2:
             raise error.PyAsn1Error('Illegal Real base')
         if b == 1:  # encbase = 8
             e *= 3
         elif b == 2:  # encbase = 16
             e *= 4
         p = 0
         while head:  # value
             p <<= 8
             p |= oct2int(head[0])
             head = head[1:]
         if fo & 0x40:  # sign bit
             p = -p
         sf = fo >> 2 & 0x03  # scale bits
         p *= 2**sf
         value = (p, 2, e)
     elif fo & 0x40:  # infinite value
         value = fo & 0x01 and '-inf' or 'inf'
     elif fo & 0xc0 == 0:  # character encoding
         if not head:
             raise error.PyAsn1Error("Incomplete floating-point value")
         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
Exemple #5
0
    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
                     state, decodeFun):
        substrate = substrate[:length]        
        if not substrate:
            raise error.PyAsn1Error('Empty substrate')
        oid = (); index = 0        
        # Get the first subid
        subId = oct2int(substrate[index])
        oid = oid + divmod(subId, 40)

        index = index + 1
        substrateLen = len(substrate)
        
        while index < substrateLen:
            subId = oct2int(substrate[index])
            if subId < 128:
                oid = oid + (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 = oct2int(substrate[index])
                if index == substrateLen:
                    raise error.SubstrateUnderrunError(
                        'Short substrate for OID %s' % oid
                        )
                subId = (subId << 7) + nextSubId
                oid = oid + (subId,)
                index = index + 1
        return self._createComponent(asn1Spec, tagSet, oid), substrate[index:]
Exemple #6
0
 def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
                  state, decodeFun):
     substrate = substrate[:length]        
     if tagSet[0][1] == tag.tagFormatSimple:    # XXX what tag to check?
         if not substrate:
             raise error.PyAsn1Error('Missing initial octet')
         trailingBits = oct2int(substrate[0])
         if trailingBits > 7:
             raise error.PyAsn1Error(
                 'Trailing bits overflow %s' % trailingBits
                 )
         substrate = substrate[1:]
         lsb = p = 0; l = len(substrate)-1; b = ()
         while p <= l:
             if p == l:
                 lsb = trailingBits
             j = 7                    
             o = oct2int(substrate[p])
             while j >= lsb:
                 b = b + ((o>>j)&0x01,)
                 j = j - 1
             p = p + 1
         return self._createComponent(asn1Spec, tagSet, b), ''
     r = self._createComponent(asn1Spec, tagSet, ())
     if not decodeFun:
         return r, substrate
     while substrate:
         component, substrate = decodeFun(substrate)
         r = r + component
     return r, substrate
Exemple #7
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
Exemple #8
0
 def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
                  state, decodeFun):
     substrate = substrate[:length]
     if tagSet[0][1] == tag.tagFormatSimple:    # XXX what tag to check?
         if not substrate:
             raise error.PyAsn1Error('Missing initial octet')
         trailingBits = oct2int(substrate[0])
         if trailingBits > 7:
             raise error.PyAsn1Error(
                 'Trailing bits overflow %s' % trailingBits
                 )
         substrate = substrate[1:]
         lsb = p = 0; l = len(substrate)-1; b = ()
         while p <= l:
             if p == l:
                 lsb = trailingBits
             j = 7
             o = oct2int(substrate[p])
             while j >= lsb:
                 b = b + ((o>>j)&0x01,)
                 j = j - 1
             p = p + 1
         return self._createComponent(asn1Spec, tagSet, b), ''
     r = self._createComponent(asn1Spec, tagSet, ())
     if not decodeFun:
         return r, substrate
     while substrate:
         component, substrate = decodeFun(substrate)
         r = r + component
     return r, substrate
Exemple #9
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
Exemple #10
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])
             head = head[1:]
         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:]
         b = fo >> 4 & 0x03 # base bits
         if b > 2:
             raise error.PyAsn1Error('Illegal Real base')
         if b == 1: # encbase = 8
             e *= 3
         elif b == 2: # encbase = 16
             e *= 4
         p = 0
         while head:  # value
             p <<= 8
             p |= oct2int(head[0])
             head = head[1:]
         if fo & 0x40:    # sign bit
             p = -p
         sf = fo >> 2 & 0x03  # scale bits
         p *= 2**sf
         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 = Decimal(head)
             elif fo & 0x3 == 0x3:  # NR3
                 value = Decimal(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
Exemple #11
0
 def __asSocketAddress(self):
     if not hasattr(self, '__tuple_value'):
         v = self.asOctets()
         self.__tuple_value = (
             inet_ntop(socket.AF_INET, v[:4]),
             oct2int(v[4]) << 8 | oct2int(v[5]),
         )
     return self.__tuple_value
Exemple #12
0
 def __asSocketAddress(self):
     if not hasattr(self, '__tuple_value'):
         v = self.asOctets()
         self.__tuple_value = (
             inet_ntop(AF_INET, v[:4]),
             oct2int(v[4]) << 8 | oct2int(v[5])
         )
     return self.__tuple_value
Exemple #13
0
 def __getitem__(self, i):
     if not hasattr(self, '__tuple_value'):
         v = self.asOctets()
         self.__tuple_value = (
             inet_ntop(AF_INET, v[:4]),
             oct2int(v[4]) << 8 | oct2int(v[5])
         )
     return self.__tuple_value[i]
Exemple #14
0
 def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
                  length, state, decodeFun):
     substrate = substrate[:length]
     if not length:
         raise error.SubstrateUnderrunError('Short substrate for Real')
     fo = oct2int(substrate[0]); substrate = substrate[1:]
     if fo & 0x40:  # infinite value
         value = fo & 0x01 and '-inf' or 'inf'
     elif fo & 0x80:  # binary enoding
         if fo & 0x11 == 0:
             n = 1
         elif fo & 0x01:
             n = 2
         elif fo & 0x02:
             n = 3
         else:
             n = oct2int(substrate[0])
         eo, substrate = substrate[:n], substrate[n:]
         if not eo or not substrate:
             raise error.PyAsn1Error('Real exponent screwed')
         e = 0
         while eo:         # exponent
             e <<= 8
             e |= oct2int(eo[0])
             eo = eo[1:]
         p = 0
         while substrate:  # value
             p <<= 8
             p |= oct2int(substrate[0])
             substrate = substrate[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(substrate), 10, 0)
             elif fo & 0x3 == 0x2:  # NR2
                 value = float(substrate)
             elif fo & 0x3 == 0x3:  # NR3
                 value = float(substrate)
             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), substrate
Exemple #15
0
 def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
                  length, state, decodeFun):
     substrate = substrate[:length]
     if not length:
         raise error.SubstrateUnderrunError('Short substrate for Real')
     fo = oct2int(substrate[0]); substrate = substrate[1:]
     if fo & 0x40:  # infinite value
         value = fo & 0x01 and '-inf' or 'inf'
     elif fo & 0x80:  # binary enoding
         if fo & 0x11 == 0:
             n = 1
         elif fo & 0x01:
             n = 2
         elif fo & 0x02:
             n = 3
         else:
             n = oct2int(substrate[0])
         eo, substrate = substrate[:n], substrate[n:]
         if not eo or not substrate:
             raise error.PyAsn1Error('Real exponent screwed')
         e = 0
         while eo:         # exponent
             e <<= 8
             e |= oct2int(eo[0])
             eo = eo[1:]
         p = 0
         while substrate:  # value
             p <<= 8
             p |= oct2int(substrate[0])
             substrate = substrate[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(substrate), 10, 0)
             elif fo & 0x3 == 0x2:  # NR2
                 value = float(substrate)
             elif fo & 0x3 == 0x3:  # NR3
                 value = float(substrate)
             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), substrate
 def __getitem__(self, i):
     if not hasattr(self, '__tuple_value'):
         if not has_ipv6:
             raise error.PySnmpError('IPv6 not supported by platform')
         v = self.asOctets()
         self.__tuple_value = (
             inet_ntop(socket.AF_INET6, v[:16]),
             oct2int(v[16]) << 8 | oct2int(v[17]),
             0,  # flowinfo
             0)  # scopeid
     return self.__tuple_value[i]
Exemple #17
0
 def __getitem__(self, i):
     if not hasattr(self, '__tuple_value'):
         if AF_INET6 is None:
             raise error.PySnmpError('IPv6 not supported by platform')
         v = self.asOctets()
         self.__tuple_value = (
             inet_ntop(AF_INET6, v[:16]),
             oct2int(v[16]) << 8 | oct2int(v[17]),
             0,
             0)
     return self.__tuple_value[i]
Exemple #18
0
 def __asSocketAddress(self):
     if not hasattr(self, '__tuple_value'):
         if not has_ipv6:
             raise error.PySnmpError('IPv6 not supported by platform')
         v = self.asOctets()
         self.__tuple_value = (
             inet_ntop(socket.AF_INET6, v[:16]),
             oct2int(v[16]) << 8 | oct2int(v[17]),
             0,  # flowinfo
             0)  # scopeid
     return self.__tuple_value
Exemple #19
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
Exemple #20
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
Exemple #21
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:]
            value = self.protoComponent.fromOctetString(head, trailingBits)
            return self._createComponent(asn1Spec, tagSet, value), tail

        if not self.supportConstructedForm:
            raise error.PyAsn1Error(
                'Constructed encoding form prohibited at %s' %
                self.__class__.__name__)

        bitString = self._createComponent(asn1Spec, tagSet)

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

        while head:
            component, head = decodeFun(head, self.protoComponent)
            bitString += component

        return bitString, tail
Exemple #22
0
 def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
                  state, decodeFun):
     substrate = substrate[:length]
     if not substrate:
         raise error.PyAsn1Error('Empty substrate')
     if substrate in self.precomputedValues:
         value = self.precomputedValues[substrate]
     else:
         firstOctet = oct2int(substrate[0])
         if firstOctet & 0x80:
             value = -1
         else:
             value = 0
         for octet in substrate:
             value = value << 8 | oct2int(octet)
     return self._createComponent(asn1Spec, tagSet, value), substrate
Exemple #23
0
    def from_bytes(octets, signed=False):
        value = long(b2a_hex(str(octets)), 16)

        if signed and oct2int(octets[0]) & 0x80:
            return value - (1 << len(octets) * 8)

        return value
Exemple #24
0
 def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
                  state, decodeFun):
     substrate = substrate[:length]
     if not substrate:
         raise error.PyAsn1Error('Empty substrate')
     if substrate in self.precomputedValues:
         value = self.precomputedValues[substrate]
     else:
         firstOctet = oct2int(substrate[0])
         if firstOctet & 0x80:
             value = -1
         else:
             value = 0
         for octet in substrate:
             value = value << 8 | oct2int(octet)
     return self._createComponent(asn1Spec, tagSet, value), substrate
Exemple #25
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), tail
     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
Exemple #26
0
    def from_bytes(octets, signed=False):
        value = long(b2a_hex(str(octets)), 16)

        if signed and oct2int(octets[0]) & 0x80:
            return value - (1 << len(octets) * 8)

        return value
Exemple #27
0
    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
                     state, decodeFun, substrateFun):
        head, tail = substrate[:length], substrate[length:]
        if tagSet[0].tagFormat == 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:]
            value = self.protoComponent.fromOctetString(head, trailingBits)
            return self._createComponent(asn1Spec, tagSet, value), tail

        if not self.supportConstructedForm:
            raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__)

        bitString = self._createComponent(asn1Spec, tagSet)

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

        while head:
            component, head = decodeFun(head, self.protoComponent)
            bitString += component

        return bitString, tail
Exemple #28
0
    def valueDecoder(self,
                     substrate,
                     asn1Spec,
                     tagSet=None,
                     length=None,
                     state=None,
                     decodeFun=None,
                     substrateFun=None,
                     **options):

        if length != 1:
            raise error.PyAsn1Error('Not single-octet Boolean payload')

        for chunk in readFromStream(substrate, length, options):
            if isinstance(chunk, SubstrateUnderrunError):
                yield chunk

        byte = oct2int(chunk[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 https://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('Unexpected Boolean payload: %s' % byte)

        yield self._createComponent(asn1Spec, tagSet, value, **options)
Exemple #29
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), tail
     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
Exemple #30
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')

        oid = ()
        index = 0
        substrateLen = len(head)
        while index < substrateLen:
            subId = oct2int(head[index])
            index += 1
            if subId < 128:
                oid = 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 = oct2int(head[index])
                    index += 1
                oid = 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
Exemple #31
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')

        oid = ()
        index = 0
        substrateLen = len(head)
        while index < substrateLen:
            subId = oct2int(head[index])
            index += 1
            if subId < 128:
                oid = 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 = oct2int(head[index])
                    index += 1
                oid = 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
    def from_bytes(octets, signed=False):
        if not octets:
            return 0

        value = long(b2a_hex(ensureString(octets)), 16)

        if signed and oct2int(octets[0]) & 0x80:
            return value - (1 << len(octets) * 8)

        return value
    def from_bytes(octets, signed=False):
        if not octets:
            return 0

        value = long(b2a_hex(ensureString(octets)), 16)

        if signed and oct2int(octets[0]) & 0x80:
            return value - (1 << len(octets) * 8)

        return value
Exemple #34
0
 def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
                  state, decodeFun):
     substrate = substrate[:length]
     if not substrate:
         raise error.PyAsn1Error('Empty substrate')
     byte = oct2int(substrate[0])
     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), substrate[1:]
Exemple #35
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:]
         if BITPATTERN:
             # Use faster method with lookup table
             p = 0; l = len(head)-1; b = []
             while p < l:
                 b.extend(BITPATTERN[oct2int(head[p])])
                 p += 1
             b.extend(BITPATTERN[oct2int(head[p])][0:8-trailingBits])
         else:
             # Use original, slower method
             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
 def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
                  state, decodeFun):
     substrate = substrate[:length]
     if not substrate:
         raise error.PyAsn1Error('Empty substrate')
     byte = oct2int(substrate[0])
     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), substrate[1:]
 def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length, state, decodeFun, substrateFun):
     head, tail = substrate[:length], substrate[length:]
     if not head or length != 1:
         raise error.PyAsn1Error("Not single-octet Boolean payload")
     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("Unexpected Boolean payload: %s" % byte)
     return self._createComponent(asn1Spec, tagSet, value), tail
Exemple #38
0
 def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
                  state, decodeFun, substrateFun):
     head, tail = substrate[:length], substrate[length:]
     if not head or length != 1:
         raise error.PyAsn1Error('Not single-octet Boolean payload')
     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('Unexpected Boolean payload: %s' % byte)
     return self._createComponent(asn1Spec, tagSet, value), tail
Exemple #39
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)
Exemple #40
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)
Exemple #41
0
    def prettyOut(self, value):  # override asn1 type method
        """Implements DISPLAY-HINT evaluation"""
        if self.displayHint and (self.__integer.isSuperTypeOf(self)
                                 or self.__unsigned32.isSuperTypeOf(self)
                                 or self.__timeticks.isSuperTypeOf(self)
                                 or self.__counter32.isSuperTypeOf(self)
                                 or self.__counter64.isSuperTypeOf(self)):
            _ = lambda t, f=0: (t, f)
            t, f = _(*self.displayHint.split('-'))
            if t == 'x':
                return '0x%x' % value
            elif t == 'd':
                try:
                    return '%.*f' % (int(f), float(value) / pow(10, int(f)))
                except Exception:
                    raise SmiError('float num evaluation error: %s' %
                                   sys.exc_info()[1])
            elif t == 'o':
                return '0%o' % value
            elif t == 'b':
                v = value
                r = ['B']
                while v:
                    r.insert(0, '%d' % (v & 0x01))
                    v >>= 1
                return ''.join(r)
            else:
                raise SmiError('Unsupported numeric type spec: %s' % t)
        elif self.displayHint and self.__octetString.isSuperTypeOf(self):
            r = ''
            v = self.__class__(value).asOctets()
            d = self.displayHint
            while v and d:
                # 1
                if d[0] == '*':
                    repeatIndicator = repeatCount = octets.oct2int(v[0])
                    d = d[1:]
                    v = v[1:]
                else:
                    repeatCount = 1
                    repeatIndicator = None

                # 2
                octetLength = ''
                while d and d[0] in '0123456789':
                    octetLength += d[0]
                    d = d[1:]
                try:
                    octetLength = int(octetLength)
                except Exception:
                    raise SmiError('Bad octet length: %s' % octetLength)
                if not d:
                    raise SmiError('Short octet length: %s' % self.displayHint)
                # 3
                displayFormat = d[0]
                d = d[1:]

                # 4
                if d and d[0] not in '0123456789' and d[0] != '*':
                    displaySep = d[0]
                    d = d[1:]
                else:
                    displaySep = ''

                # 5
                if d and displaySep and repeatIndicator is not None:
                    repeatTerminator = d[0]
                    displaySep = ''
                    d = d[1:]
                else:
                    repeatTerminator = None

                while repeatCount:
                    repeatCount -= 1
                    if displayFormat == 'a':
                        r += v[:octetLength].decode('ascii', 'ignore')
                    elif displayFormat == 't':
                        r += v[:octetLength].decode('utf-8', 'ignore')
                    elif displayFormat in ('x', 'd', 'o'):
                        n = 0
                        vv = v[:octetLength]
                        while vv:
                            n <<= 8
                            try:
                                n |= octets.oct2int(vv[0])
                                vv = vv[1:]
                            except Exception:
                                raise SmiError(
                                    'Display format eval failure: %s: %s' %
                                    (vv, sys.exc_info()[1]))
                        if displayFormat == 'x':
                            r += '%02x' % n
                        elif displayFormat == 'o':
                            r += '%03o' % n
                        else:
                            r += '%d' % n
                    else:
                        raise SmiError('Unsupported display format char: %s' %
                                       displayFormat)
                    if v and repeatTerminator:
                        r += repeatTerminator
                    v = v[octetLength:]
                if v and displaySep:
                    r += displaySep
                if not d:
                    d = self.displayHint
                    #             if d:
                    #                 raise SmiError(
                    #                     'Unparsed display hint left: %s' % d
                    #                     )
            return r
        elif self.__objectIdentifier.isSuperTypeOf(self):
            return self.__objectIdentifier.prettyOut(value)
        elif self.__octetString.isSuperTypeOf(self):
            return self.__octetString.prettyOut(value)
        else:
            return str(value)
Exemple #42
0
 def __call__(self, substrate, asn1Spec=None, tagSet=None,
              length=None, state=stDecodeTag, recursiveFlag=1):
     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
         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
             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:
             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 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 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
         if state == stDumpRawValue:
             concreteDecoder = self.defaultRawDecoder
             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
         if state == stErrorCondition:
             raise error.PyAsn1Error(
                 '%s not in asn1Spec: %s' % (tagSet, repr(asn1Spec))
                 )
     return value, substrate
 def test_oct2int(self):
     assert 12 == octets.oct2int(bytes([12]))[0]
Exemple #44
0
    def prettyOut(self, value):  # override asn1 type method
        """Implements DISPLAY-HINT evaluation"""
        if self.displayHint and (self.__integer.isSuperTypeOf(self, matchConstraints=False) and not self.getNamedValues() or
                                 self.__unsigned32.isSuperTypeOf(self, matchConstraints=False) or
                                 self.__timeticks.isSuperTypeOf(self, matchConstraints=False)):
            _ = lambda t, f=0: (t, f)
            displayHintType, decimalPrecision = _(*self.displayHint.split('-'))
            if displayHintType == 'x':
                return '0x%x' % value
            elif displayHintType == 'd':
                try:
                    return '%.*f' % (int(decimalPrecision), float(value) / pow(10, int(decimalPrecision)))
                except Exception as exc:
                    raise SmiError(
                        'float evaluation error: %s' % exc
                    )
            elif displayHintType == 'o':
                return '0%o' % value
            elif displayHintType == 'b':
                runningValue = value
                outputValue = ['B']
                while runningValue:
                    outputValue.insert(0, '%d' % (runningValue & 0x01))
                    runningValue >>= 1
                return ''.join(outputValue)
            else:
                raise SmiError(
                    'Unsupported numeric type spec "%s" at %s' % (displayHintType, self.__class__.__name__)
                )
        elif self.displayHint and self.__octetString.isSuperTypeOf(self, matchConstraints=False):
            outputValue = ''
            runningValue = OctetString(value).asOctets()
            displayHint = self.displayHint
            while runningValue and displayHint:
                # 1
                if displayHint[0] == '*':
                    repeatIndicator = repeatCount = octets.oct2int(runningValue[0])
                    displayHint = displayHint[1:]
                    runningValue = runningValue[1:]
                else:
                    repeatCount = 1
                    repeatIndicator = None

                # 2
                octetLength = ''
                while displayHint and displayHint[0] in string.digits:
                    octetLength += displayHint[0]
                    displayHint = displayHint[1:]

                # length is manatory, but people ignore that
                if not octetLength:
                    octetLength = len(runningValue)

                try:
                    octetLength = int(octetLength)
                except Exception:
                    raise SmiError(
                        'Bad octet length: %s' % octetLength
                    )

                if not displayHint:
                    raise SmiError(
                        'Short octet length: %s' % self.displayHint
                    )

                # 3
                displayFormat = displayHint[0]
                displayHint = displayHint[1:]

                # 4
                if displayHint and displayHint[0] not in string.digits and displayHint[0] != '*':
                    displaySep = displayHint[0]
                    displayHint = displayHint[1:]
                else:
                    displaySep = ''

                # 5
                if displayHint and displaySep and repeatIndicator is not None:
                    repeatTerminator = displayHint[0]
                    displaySep = ''
                    displayHint = displayHint[1:]
                else:
                    repeatTerminator = None

                while repeatCount:
                    repeatCount -= 1
                    if displayFormat == 'a':
                        outputValue += runningValue[:octetLength].decode('ascii', 'ignore')
                    elif displayFormat == 't':
                        outputValue += runningValue[:octetLength].decode('utf-8', 'ignore')
                    elif displayFormat in ('x', 'd', 'o'):
                        number = 0
                        numberString = runningValue[:octetLength]
                        while numberString:
                            number <<= 8
                            try:
                                number |= octets.oct2int(numberString[0])
                                numberString = numberString[1:]
                            except Exception as exc:
                                raise SmiError(
                                    'Display format eval failure: %s: %s'
                                    % (numberString, exc)
                                )
                        if displayFormat == 'x':
                            outputValue += '%02x' % number
                        elif displayFormat == 'o':
                            outputValue += '%03o' % number
                        else:
                            outputValue += '%d' % number
                    else:
                        raise SmiError(
                            'Unsupported display format char: %s' %
                            displayFormat
                        )
                    if runningValue and repeatTerminator:
                        outputValue += repeatTerminator
                    runningValue = runningValue[octetLength:]
                if runningValue and displaySep:
                    outputValue += displaySep
                if not displayHint:
                    displayHint = self.displayHint

            return outputValue

        for base in inspect.getmro(self.__class__):
            if not issubclass(base, TextualConvention) and issubclass(base, Asn1Item):
                return base.prettyOut(self, value)

        raise SmiError('TEXTUAL-CONVENTION has no underlying SNMP base type')
Exemple #45
0
    def __call__(self, substrate, asn1Spec=None, tagSet=None,
                 length=None, state=stDecodeTag, recursiveFlag=True,
                 substrateFun=None, allowEoo=False):
        if debug.logger and 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)))

        substrate = ensureString(substrate)

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

        value = base.noValue

        fullSubstrate = substrate
        while state != stStop:
            if state == 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
                debug.logger and debug.logger & debug.flagDecoder and debug.logger(
                    'tag decoded into %s, 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 = 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
                debug.logger and debug.logger & debug.flagDecoder and debug.logger(
                    'value length decoded into %d, payload substrate is: %s' % (length, debug.hexdump(length == -1 and substrate or 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:
                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 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 asn1Spec.__class__ is dict or asn1Spec.__class__ is tagmap.TagMap:
                    try:
                        chosenSpec = asn1Spec[tagSet]
                    except KeyError:
                        chosenSpec = None
                    if debug.logger and debug.logger & debug.flagDecoder:
                        debug.logger('candidate ASN.1 spec is a map of:')
                        for firstOctet, v in asn1Spec.presentTypes.items():
                            debug.logger('  %s -> %s' % (firstOctet, v.__class__.__name__))
                        if asn1Spec.skipTypes:
                            debug.logger('but neither of: ')
                            for firstOctet, v in asn1Spec.skipTypes.items():
                                debug.logger('  %s -> %s' % (firstOctet, v.__class__.__name__))
                        debug.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
                        debug.logger and debug.logger & debug.flagDecoder and debug.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]
                        debug.logger and debug.logger & debug.flagDecoder and debug.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]
                            debug.logger and debug.logger & debug.flagDecoder and debug.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 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].tagFormat == tag.tagFormatConstructed and tagSet[0].tagClass != 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 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
                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(
                    '%s not in asn1Spec: %s' % (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
Exemple #46
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
Exemple #47
0
    def __call__(self, substrate, asn1Spec=None, tagSet=None,
                 length=None, state=stDecodeTag, recursiveFlag=1,
                 substrateFun=None, allowEoo=False):
        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)))
        if asn1Spec is not None and not isinstance(asn1Spec, (base.Asn1Item, tagmap.TagMap)):
            raise error.PyAsn1Error('asn1Spec is not valid (should be an instance of an ASN.1 Item, not %s)' % asn1Spec.__class__.__name__)

        fullSubstrate = substrate
        while state != stStop:
            if state == stDecodeTag:
                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')
                # Decode tag
                firstOctet = substrate[0]
                substrate = substrate[1:]
                if firstOctet in self.__tagCache:
                    lastTag = self.__tagCache[firstOctet]
                else:
                    t = oct2int(firstOctet)
                    # Look for end-of-octets sentinel
                    if t == 0:
                        if substrate and oct2int(substrate[0]) == 0:
                            if allowEoo and self.supportIndefLength:
                                debug.logger and debug.logger & debug.flagDecoder and debug.logger('end-of-octets sentinel found')
                                value, substrate = eoo.endOfOctets, substrate[1:]
                                state = stStop
                                continue
                            else:
                                raise error.PyAsn1Error('Unexpected end-of-contents sentinel')
                        else:
                            raise error.PyAsn1Error('Zero tag encountered')
                    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 %s, 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 += 1
                substrate = substrate[size:]
                if length != -1 and len(substrate) < length:
                    raise error.SubstrateUnderrunError(
                        '%d-octet short' % (length - len(substrate))
                        )
                if length == -1 and not self.supportIndefLength:
                    error.PyAsn1Error('Indefinite length encoding not supported by this codec')
                state = stGetValueDecoder
                debug.logger and debug.logger & debug.flagDecoder and debug.logger('value length decoded into %d, payload substrate is: %s' % (length, debug.hexdump(length == -1 and substrate or 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('  %s -> %s' % (t, v.__class__.__name__))
                        if asn1Spec.getNegMap():
                            debug.logger('but neither of: ')
                            for t, v in asn1Spec.getNegMap().items():
                                debug.logger('  %s -> %s' % (t, v.__class__.__name__))
                        debug.logger('new candidate ASN.1 spec is %s, chosen by %s' % (__chosenSpec is None and '<none>' or __chosenSpec.prettyPrintType(), 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 %s' % (baseTagSet,))
                    else:
                        concreteDecoder = None
                    if concreteDecoder:
                        asn1Spec = __chosenSpec
                        state = stDecodeValue
                    else:
                        state = stTryAsExplicitTag
                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(
                    '%s not in asn1Spec: %s' % (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
 def test_oct2int(self):
     assert 12 == octets.oct2int('\x0c')
Exemple #49
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 encoding
         ms, m, encbase, e = self._chooseEncBase(value)
         if ms < 0: # mantissa sign
             fo = fo | 0x40 # sign bit
         # exponenta & mantissa normalization
         if encbase == 2:
             while m & 0x1 == 0:
                 m >>= 1
                 e += 1
         elif encbase == 8:
             while m & 0x7 == 0:
                 m >>= 3
                 e += 1
             fo |= 0x10
         else: # encbase = 16
             while m & 0xf == 0:
                 m >>= 4
                 e += 1
             fo |= 0x20
         sf = 0 # scale factor
         while m & 0x1 == 0:
             m >>= 1
             sf += 1
         if sf > 3:
             raise error.PyAsn1Error('Scale factor overflow') # bug if raised
         fo |= sf << 2
         eo = null
         if e == 0 or e == -1:
             eo = int2oct(e&0xff)
         else: 
             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
             if e == -1 and eo and not (oct2int(eo[0]) & 0x80):
                 eo = int2oct(0xff) + 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) + 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)
Exemple #50
0
 def test_oct2int(self):
     assert 12 == octets.oct2int('\x0c')
Exemple #51
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 encoding
         ms, m, encbase, e = self._chooseEncBase(value)
         if ms < 0:  # mantissa sign
             fo = fo | 0x40  # sign bit
         # exponenta & mantissa normalization
         if encbase == 2:
             while m & 0x1 == 0:
                 m >>= 1
                 e += 1
         elif encbase == 8:
             while m & 0x7 == 0:
                 m >>= 3
                 e += 1
             fo |= 0x10
         else:  # encbase = 16
             while m & 0xf == 0:
                 m >>= 4
                 e += 1
             fo |= 0x20
         sf = 0  # scale factor
         while m & 0x1 == 0:
             m >>= 1
             sf += 1
         if sf > 3:
             raise error.PyAsn1Error(
                 'Scale factor overflow')  # bug if raised
         fo |= sf << 2
         eo = null
         if e == 0 or e == -1:
             eo = int2oct(e & 0xff)
         else:
             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
             if e == -1 and eo and not (oct2int(eo[0]) & 0x80):
                 eo = int2oct(0xff) + 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) + 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)
Exemple #52
0
    def encodeValue(self, value, asn1Spec, encodeFun, **options):
        if asn1Spec is not None:
            value = asn1Spec.clone(value)

        if value.isPlusInf:
            return (0x40, ), False, False

        if value.isMinusInf:
            return (0x41, ), False, False

        m, b, e = value

        if not m:
            return null, False, True

        if b == 10:
            if LOG:
                LOG('encoding REAL into character form')

            return str2octs('\x03%dE%s%d' %
                            (m, e == 0 and '+' or '', e)), False, True

        elif b == 2:
            fo = 0x80  # binary encoding
            ms, m, encbase, e = self._chooseEncBase(value)

            if ms < 0:  # mantissa sign
                fo |= 0x40  # sign bit

            # exponent & mantissa normalization
            if encbase == 2:
                while m & 0x1 == 0:
                    m >>= 1
                    e += 1

            elif encbase == 8:
                while m & 0x7 == 0:
                    m >>= 3
                    e += 1
                fo |= 0x10

            else:  # encbase = 16
                while m & 0xf == 0:
                    m >>= 4
                    e += 1
                fo |= 0x20

            sf = 0  # scale factor

            while m & 0x1 == 0:
                m >>= 1
                sf += 1

            if sf > 3:
                raise error.PyAsn1Error(
                    'Scale factor overflow')  # bug if raised

            fo |= sf << 2
            eo = null
            if e == 0 or e == -1:
                eo = int2oct(e & 0xff)

            else:
                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

                if e == -1 and eo and not (oct2int(eo[0]) & 0x80):
                    eo = int2oct(0xff) + 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) + eo

            po = null

            while m:
                po = int2oct(m & 0xff) + po
                m >>= 8

            substrate = int2oct(fo) + eo + po

            return substrate, False, True

        else:
            raise error.PyAsn1Error('Prohibited Real base %s' % b)
Exemple #53
0
    def prettyOut(self, value):  # override asn1 type method
        """Implements DISPLAY-HINT evaluation"""
        if self.displayHint and (self.__integer.isSuperTypeOf(self) or
                                 self.__unsigned32.isSuperTypeOf(self) or
                                 self.__timeticks.isSuperTypeOf(self) or
                                 self.__counter32.isSuperTypeOf(self) or
                                 self.__counter64.isSuperTypeOf(self)):
            _ = lambda t, f=0: (t, f)
            t, f = _(*self.displayHint.split('-'))
            if t == 'x':
                return '0x%x' % value
            elif t == 'd':
                try:
                    return '%.*f' % (int(f), float(value) / pow(10, int(f)))
                except Exception:
                    raise SmiError(
                        'float num evaluation error: %s' % sys.exc_info()[1]
                    )
            elif t == 'o':
                return '0%o' % value
            elif t == 'b':
                v = value
                r = ['B']
                while v:
                    r.insert(0, '%d' % (v & 0x01))
                    v >>= 1
                return ''.join(r)
            else:
                raise SmiError(
                    'Unsupported numeric type spec: %s' % t
                )
        elif self.displayHint and self.__octetString.isSuperTypeOf(self):
            r = ''
            v = self.__class__(value).asOctets()
            d = self.displayHint
            while v and d:
                # 1
                if d[0] == '*':
                    repeatIndicator = repeatCount = octets.oct2int(v[0])
                    d = d[1:]
                    v = v[1:]
                else:
                    repeatCount = 1
                    repeatIndicator = None

                # 2
                octetLength = ''
                while d and d[0] in '0123456789':
                    octetLength += d[0]
                    d = d[1:]
                try:
                    octetLength = int(octetLength)
                except Exception:
                    raise SmiError(
                        'Bad octet length: %s' % octetLength
                    )
                if not d:
                    raise SmiError(
                        'Short octet length: %s' % self.displayHint
                    )
                # 3
                displayFormat = d[0]
                d = d[1:]

                # 4
                if d and d[0] not in '0123456789' and d[0] != '*':
                    displaySep = d[0]
                    d = d[1:]
                else:
                    displaySep = ''

                # 5
                if d and displaySep and repeatIndicator is not None:
                    repeatTerminator = d[0]
                    displaySep = ''
                    d = d[1:]
                else:
                    repeatTerminator = None

                while repeatCount:
                    repeatCount -= 1
                    if displayFormat == 'a':
                        r += v[:octetLength].decode('ascii', 'ignore')
                    elif displayFormat == 't':
                        r += v[:octetLength].decode('utf-8', 'ignore')
                    elif displayFormat in ('x', 'd', 'o'):
                        n = 0
                        vv = v[:octetLength]
                        while vv:
                            n <<= 8
                            try:
                                n |= octets.oct2int(vv[0])
                                vv = vv[1:]
                            except Exception:
                                raise SmiError(
                                    'Display format eval failure: %s: %s'
                                    % (vv, sys.exc_info()[1])
                                )
                        if displayFormat == 'x':
                            r += '%02x' % n
                        elif displayFormat == 'o':
                            r += '%03o' % n
                        else:
                            r += '%d' % n
                    else:
                        raise SmiError(
                            'Unsupported display format char: %s' %
                            displayFormat
                        )
                    if v and repeatTerminator:
                        r += repeatTerminator
                    v = v[octetLength:]
                if v and displaySep:
                    r += displaySep
                if not d:
                    d = self.displayHint
                    #             if d:
                    #                 raise SmiError(
                    #                     'Unparsed display hint left: %s' % d
                    #                     )
            return r
        elif self.__objectIdentifier.isSuperTypeOf(self):
            return self.__objectIdentifier.prettyOut(value)
        elif self.__octetString.isSuperTypeOf(self):
            return self.__octetString.prettyOut(value)
        else:
            return str(value)
Exemple #54
0
    def __call__(self, substrate, asn1Spec=None, tagSet=None,
                 length=None, state=stDecodeTag, recursiveFlag=1):
        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
            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
                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:
                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 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 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
            if state == stDumpRawValue:
                concreteDecoder = self.defaultRawDecoder
                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
            if state == stErrorCondition:
                raise error.PyAsn1Error(
                    '%s not in asn1Spec: %s' % (tagSet, repr(asn1Spec))
                    )
        return value, substrate
Exemple #55
0
    def prettyOut(self, value):  # override asn1 type method
        """Implements DISPLAY-HINT evaluation"""
        if self.displayHint and (self.__integer.isSuperTypeOf(
                self, matchConstraints=False) and not self.getNamedValues()
                                 or self.__unsigned32.isSuperTypeOf(
                                     self, matchConstraints=False)
                                 or self.__timeticks.isSuperTypeOf(
                                     self, matchConstraints=False)):
            _ = lambda t, f=0: (t, f)
            displayHintType, decimalPrecision = _(*self.displayHint.split('-'))
            if displayHintType == 'x':
                return '0x%x' % value
            elif displayHintType == 'd':
                try:
                    return '%.*f' % (int(decimalPrecision), float(value) /
                                     pow(10, int(decimalPrecision)))
                except Exception:
                    raise SmiError('float evaluation error: %s' %
                                   sys.exc_info()[1])
            elif displayHintType == 'o':
                return '0%o' % value
            elif displayHintType == 'b':
                runningValue = value
                outputValue = ['B']
                while runningValue:
                    outputValue.insert(0, '%d' % (runningValue & 0x01))
                    runningValue >>= 1
                return ''.join(outputValue)
            else:
                raise SmiError('Unsupported numeric type spec "%s" at %s' %
                               (displayHintType, self.__class__.__name__))
        elif self.displayHint and self.__octetString.isSuperTypeOf(
                self, matchConstraints=False):
            outputValue = ''
            runningValue = OctetString(value).asOctets()
            displayHint = self.displayHint
            while runningValue and displayHint:
                # 1
                if displayHint[0] == '*':
                    repeatIndicator = repeatCount = octets.oct2int(
                        runningValue[0])
                    displayHint = displayHint[1:]
                    runningValue = runningValue[1:]
                else:
                    repeatCount = 1
                    repeatIndicator = None

                # 2
                octetLength = ''
                while displayHint and displayHint[0] in string.digits:
                    octetLength += displayHint[0]
                    displayHint = displayHint[1:]

                # length is manatory, but people ignore that
                if not octetLength:
                    octetLength = len(runningValue)

                try:
                    octetLength = int(octetLength)
                except Exception:
                    raise SmiError('Bad octet length: %s' % octetLength)

                if not displayHint:
                    raise SmiError('Short octet length: %s' % self.displayHint)

                # 3
                displayFormat = displayHint[0]
                displayHint = displayHint[1:]

                # 4
                if displayHint and displayHint[
                        0] not in string.digits and displayHint[0] != '*':
                    displaySep = displayHint[0]
                    displayHint = displayHint[1:]
                else:
                    displaySep = ''

                # 5
                if displayHint and displaySep and repeatIndicator is not None:
                    repeatTerminator = displayHint[0]
                    displaySep = ''
                    displayHint = displayHint[1:]
                else:
                    repeatTerminator = None

                while repeatCount:
                    repeatCount -= 1
                    if displayFormat == 'a':
                        outputValue += runningValue[:octetLength].decode(
                            'ascii', 'ignore')
                    elif displayFormat == 't':
                        outputValue += runningValue[:octetLength].decode(
                            'utf-8', 'ignore')
                    elif displayFormat in ('x', 'd', 'o'):
                        number = 0
                        numberString = runningValue[:octetLength]
                        while numberString:
                            number <<= 8
                            try:
                                number |= octets.oct2int(numberString[0])
                                numberString = numberString[1:]
                            except Exception:
                                raise SmiError(
                                    'Display format eval failure: %s: %s' %
                                    (numberString, sys.exc_info()[1]))
                        if displayFormat == 'x':
                            outputValue += '%02x' % number
                        elif displayFormat == 'o':
                            outputValue += '%03o' % number
                        else:
                            outputValue += '%d' % number
                    else:
                        raise SmiError('Unsupported display format char: %s' %
                                       displayFormat)
                    if runningValue and repeatTerminator:
                        outputValue += repeatTerminator
                    runningValue = runningValue[octetLength:]
                if runningValue and displaySep:
                    outputValue += displaySep
                if not displayHint:
                    displayHint = self.displayHint

            return outputValue

        for base in inspect.getmro(self.__class__):
            if not issubclass(base, TextualConvention) and issubclass(
                    base, Asn1Item):
                return base.prettyOut(self, value)

        raise SmiError('TEXTUAL-CONVENTION has no underlying SNMP base type')
Exemple #56
0
    def __call__(self,
                 substrate,
                 asn1Spec=None,
                 tagSet=None,
                 length=None,
                 state=stDecodeTag,
                 recursiveFlag=1,
                 substrateFun=None,
                 allowEoo=False):
        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)))
        if asn1Spec is not None and not isinstance(
                asn1Spec, (base.Asn1Item, tagmap.TagMap)):
            raise error.PyAsn1Error(
                'asn1Spec is not valid (should be an instance of an ASN.1 Item, not %s)'
                % asn1Spec.__class__.__name__)

        value = base.noValue

        fullSubstrate = substrate
        while state != stStop:
            if state == stDecodeTag:
                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')
                # Decode tag
                firstOctet = substrate[0]
                substrate = substrate[1:]
                if firstOctet in self.__tagCache:
                    lastTag = self.__tagCache[firstOctet]
                else:
                    t = oct2int(firstOctet)
                    # Look for end-of-octets sentinel
                    if t == 0:
                        if substrate and oct2int(substrate[0]) == 0:
                            if allowEoo and self.supportIndefLength:
                                debug.logger and debug.logger & debug.flagDecoder and debug.logger(
                                    'end-of-octets sentinel found')
                                value, substrate = eoo.endOfOctets, substrate[
                                    1:]
                                state = stStop
                                continue
                            else:
                                raise error.PyAsn1Error(
                                    'Unexpected end-of-contents sentinel')
                        else:
                            raise error.PyAsn1Error('Zero tag encountered')
                    tagClass = t & 0xC0
                    tagFormat = t & 0x20
                    tagId = t & 0x1F
                    short = True
                    if tagId == 0x1F:
                        short = False
                        tagId = 0
                        while True:
                            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 short:
                        # 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 %s, 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 += 1
                substrate = substrate[size:]
                if length != -1 and len(substrate) < length:
                    raise error.SubstrateUnderrunError(
                        '%d-octet short' % (length - len(substrate)))
                if length == -1 and not self.supportIndefLength:
                    error.PyAsn1Error(
                        'Indefinite length encoding not supported by this codec'
                    )
                state = stGetValueDecoder
                debug.logger and debug.logger & debug.flagDecoder and debug.logger(
                    'value length decoded into %d, payload substrate is: %s' %
                    (length,
                     debug.hexdump(length == -1 and substrate
                                   or 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('  %s -> %s' %
                                         (t, v.__class__.__name__))
                        if asn1Spec.getNegMap():
                            debug.logger('but neither of: ')
                            for t, v in asn1Spec.getNegMap().items():
                                debug.logger('  %s -> %s' %
                                             (t, v.__class__.__name__))
                        debug.logger(
                            'new candidate ASN.1 spec is %s, chosen by %s' %
                            (__chosenSpec is None and '<none>'
                             or __chosenSpec.prettyPrintType(), 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 %s' % (baseTagSet, ))
                    else:
                        concreteDecoder = None
                    if concreteDecoder:
                        asn1Spec = __chosenSpec
                        state = stDecodeValue
                    else:
                        state = stTryAsExplicitTag
                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

                    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
                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('%s not in asn1Spec: %s' %
                                        (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
    def encodeValue(self, value, asn1Spec, encodeFun, **options):
        if asn1Spec is not None:
            value = asn1Spec.clone(value)

        if value.isPlusInf:
            return (0x40,), False, False

        if value.isMinusInf:
            return (0x41,), False, False

        m, b, e = value

        if not m:
            return null, False, True

        if b == 10:
            if LOG:
                LOG('encoding REAL into character form')

            return str2octs('\x03%dE%s%d' % (m, e == 0 and '+' or '', e)), False, True

        elif b == 2:
            fo = 0x80  # binary encoding
            ms, m, encbase, e = self._chooseEncBase(value)

            if ms < 0:  # mantissa sign
                fo |= 0x40  # sign bit

            # exponent & mantissa normalization
            if encbase == 2:
                while m & 0x1 == 0:
                    m >>= 1
                    e += 1

            elif encbase == 8:
                while m & 0x7 == 0:
                    m >>= 3
                    e += 1
                fo |= 0x10

            else:  # encbase = 16
                while m & 0xf == 0:
                    m >>= 4
                    e += 1
                fo |= 0x20

            sf = 0  # scale factor

            while m & 0x1 == 0:
                m >>= 1
                sf += 1

            if sf > 3:
                raise error.PyAsn1Error('Scale factor overflow')  # bug if raised

            fo |= sf << 2
            eo = null
            if e == 0 or e == -1:
                eo = int2oct(e & 0xff)

            else:
                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

                if e == -1 and eo and not (oct2int(eo[0]) & 0x80):
                    eo = int2oct(0xff) + 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) + eo

            po = null

            while m:
                po = int2oct(m & 0xff) + po
                m >>= 8

            substrate = int2oct(fo) + eo + po

            return substrate, False, True

        else:
            raise error.PyAsn1Error('Prohibited Real base %s' % b)
Exemple #58
0
 def test_oct2int(self):
     assert 12 == octets.oct2int(bytes([12]))[0]