def _verifyComponent(self, idx, value): if idx >= self._componentTypeLen: raise error.PyAsn1Error('Component type error out of range') t = self._componentType[idx].getType() if not t.isSuperTypeOf(value): raise error.PyAsn1Error('Component type error %r vs %r' % (t, value))
def prettyIn(self, value): """Dotted -> tuple of numerics OID converter""" if isinstance(value, tuple): pass elif isinstance(value, ObjectIdentifier): return tuple(value) elif isinstance(value, str): r = [] for element in [x for x in value.split('.') if x != '']: try: r.append(int(element, 0)) except ValueError: raise error.PyAsn1Error( 'Malformed Object ID %s at %s: %s' % (str(value), self.__class__.__name__, sys.exc_info()[1])) value = tuple(r) else: try: value = tuple(value) except TypeError: raise error.PyAsn1Error( 'Malformed Object ID %s at %s: %s' % (str(value), self.__class__.__name__, sys.exc_info()[1])) for x in value: if not isinstance(x, intTypes) or x < 0: raise error.PyAsn1Error('Invalid sub-ID in %s at %s' % (value, self.__class__.__name__)) return value
def prettyIn(self, value): if isinstance(value, tuple) and len(value) == 3: for d in value: if not isinstance(d, intTypes): raise error.PyAsn1Error('Lame Real value syntax: %s' % (value, )) if value[1] not in (2, 10): raise error.PyAsn1Error('Prohibited base for Real value: %s' % (value[1], )) if value[1] == 10: value = self.__normalizeBase10(value) return value elif isinstance(value, intTypes): return self.__normalizeBase10((value, 10, 0)) elif isinstance(value, float): if self._inf and value in self._inf: return value else: e = 0 while int(value) != value: value = value * 10 e = e - 1 return self.__normalizeBase10((int(value), 10, e)) elif isinstance(value, Real): return tuple(value) elif isinstance(value, str): # handle infinite literal try: return float(value) except ValueError: pass raise error.PyAsn1Error('Bad real value syntax: %s' % (value, ))
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
def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length, state, decodeFun, substrateFun): head, tail = substrate[:length], substrate[length:] if tagSet[0][1] == tag.tagFormatSimple: # XXX what tag to check? if not head: raise error.PyAsn1Error('Empty substrate') trailingBits = oct2int(head[0]) if trailingBits > 7: raise error.PyAsn1Error('Trailing bits overflow %s' % trailingBits) head = head[1:] lsb = p = 0 l = len(head) - 1 b = () while p <= l: if p == l: lsb = trailingBits j = 7 o = oct2int(head[p]) while j >= lsb: b = b + ((o >> j) & 0x01, ) j = j - 1 p = p + 1 return self._createComponent(asn1Spec, tagSet, b), tail r = self._createComponent(asn1Spec, tagSet, ()) if substrateFun: return substrateFun(r, substrate, length) while head: component, head = decodeFun(head) r = r + component return r, tail
def encodeValue(self, encodeFun, value, defMode, maxChunkSize): oid = value.asTuple() if oid[:5] in self.precomputedValues: octets = self.precomputedValues[oid[:5]] index = 5 else: if len(oid) < 2: raise error.PyAsn1Error('Short OID %s' % (value, )) # Build the first twos if oid[0] > 6 or oid[1] > 39 or oid[0] == 6 and oid[1] > 15: raise error.PyAsn1Error( 'Initial sub-ID overflow %s in OID %s' % (oid[:2], value)) octets = (oid[0] * 40 + oid[1], ) index = 2 # Cycle through subids for subid in oid[index:]: if subid > -1 and subid < 128: # Optimize for the common case octets = octets + (subid & 0x7f, ) elif subid < 0 or subid > 0xFFFFFFFF: raise error.PyAsn1Error('SubId overflow %s in %s' % (subid, value)) else: # Pack large Sub-Object IDs res = (subid & 0x7f, ) subid = subid >> 7 while subid > 0: res = (0x80 | (subid & 0x7f), ) + res subid = subid >> 7 # Add packed Sub-Object ID to resulted Object ID octets += res return ints2octs(octets), 0
def setComponentByPosition(self, idx, value=None, verifyConstraints=True): l = len(self._componentValues) if idx >= l: self._componentValues = self._componentValues + (idx - l + 1) * [None] if value is None: if self._componentValues[idx] is None: if self._componentType is None: raise error.PyAsn1Error('Component type not defined') self._componentValues[idx] = self._componentType.clone() self._componentValuesSet = self._componentValuesSet + 1 return self elif not isinstance(value, base.Asn1Item): if self._componentType is None: raise error.PyAsn1Error('Component type not defined') if isinstance(self._componentType, base.AbstractSimpleAsn1Item): value = self._componentType.clone(value=value) else: raise error.PyAsn1Error('Instance value required') if verifyConstraints: if self._componentType is not None: self._verifyComponent(idx, value) self._verifySubtypeSpec(value, idx) if self._componentValues[idx] is None: self._componentValuesSet = self._componentValuesSet + 1 self._componentValues[idx] = value return self
def getPositionByName(self, name): if not self.__nameToPosIdx: idx = self.__namedTypesLen while idx > 0: idx = idx - 1 n = self.__namedTypes[idx].getName() if n in self.__nameToPosIdx: raise error.PyAsn1Error('Duplicate name %s' % (n, )) self.__nameToPosIdx[n] = idx try: return self.__nameToPosIdx[name] except KeyError: raise error.PyAsn1Error('Name %s not found' % (name, ))
def getPositionByType(self, tagSet): if not self.__tagToPosIdx: idx = self.__namedTypesLen while idx > 0: idx = idx - 1 tagMap = self.__namedTypes[idx].getType().getTagMap() for t in tagMap.getPosMap(): if t in self.__tagToPosIdx: raise error.PyAsn1Error('Duplicate type %s' % (t, )) self.__tagToPosIdx[t] = idx try: return self.__tagToPosIdx[tagSet] except KeyError: raise error.PyAsn1Error('Type %s not found' % (tagSet, ))
def prettyIn(self, value): r = [] if not value: return () elif isinstance(value, str): if value[0] == '\'': if value[-2:] == '\'B': for v in value[1:-2]: if v == '0': r.append(0) elif v == '1': r.append(1) else: raise error.PyAsn1Error( 'Non-binary BIT STRING initializer %s' % (v, )) return tuple(r) elif value[-2:] == '\'H': for v in value[1:-2]: i = 4 v = int(v, 16) while i: i = i - 1 r.append((v >> i) & 0x01) return tuple(r) else: raise error.PyAsn1Error( 'Bad BIT STRING value notation %s' % (value, )) else: for i in value.split(','): j = self.__namedValues.getValue(i) if j is None: raise error.PyAsn1Error( 'Unknown bit identifier \'%s\'' % (i, )) if j >= len(r): r.extend([0] * (j - len(r) + 1)) r[j] = 1 return tuple(r) elif isinstance(value, (tuple, list)): r = tuple(value) for b in r: if b and b != 1: raise error.PyAsn1Error( 'Non-binary BitString initializer \'%s\'' % (r, )) return r elif isinstance(value, BitString): return tuple(value) else: raise error.PyAsn1Error('Bad BitString initializer type \'%s\'' % (value, ))
def prettyIn(self, value): if not isinstance(value, str): try: return int(value) except: raise error.PyAsn1Error('Can\'t coerce %s into integer: %s' % (value, sys.exc_info()[1])) r = self.__namedValues.getValue(value) if r is not None: return r try: return int(value) except: raise error.PyAsn1Error('Can\'t coerce %s into integer: %s' % (value, sys.exc_info()[1]))
def __init__(self, tagClass, tagFormat, tagId): if tagId < 0: raise error.PyAsn1Error('Negative tag ID (%s) not allowed' % (tagId, )) self.__tag = (tagClass, tagFormat, tagId) self.uniq = (tagClass, tagId) self.__hashedUniqTag = hash(self.uniq)
def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length, state, decodeFun, substrateFun): head, tail = substrate[:length], substrate[length:] if not head: raise error.PyAsn1Error('Empty substrate') byte = oct2int(head[0]) # CER/DER specifies encoding of TRUE as 0xFF and FALSE as 0x0, while # BER allows any non-zero value as TRUE; cf. sections 8.2.2. and 11.1 # in http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf if byte == 0xff: value = 1 elif byte == 0x00: value = 0 else: raise error.PyAsn1Error('Boolean CER violation: %s' % byte) return self._createComponent(asn1Spec, tagSet, value), tail
def tagExplicitly(self, superTag): tagClass, tagFormat, tagId = superTag if tagClass == tagClassUniversal: raise error.PyAsn1Error('Can\'t tag with UNIVERSAL-class tag') if tagFormat != tagFormatConstructed: superTag = Tag(tagClass, tagFormatConstructed, tagId) return self + superTag
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)
def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length, state, decodeFun, substrateFun): head, tail = substrate[:length], substrate[length:] r = self._createComponent(asn1Spec, tagSet) if head: raise error.PyAsn1Error('Unexpected %d-octet substrate for Null' % length) return r, tail
def getName(self, innerFlag=0): if self._currentIdx is None: raise error.PyAsn1Error('Component not chosen') else: if innerFlag: c = self._componentValues[self._currentIdx] if isinstance(c, Choice): return c.getName(innerFlag) return self._componentType.getNameByPosition(self._currentIdx)
def prettyIn(self, value): if isinstance(value, bytes): return value elif isinstance(value, OctetString): return value.asOctets() elif isinstance(value, (tuple, list, map)): try: return bytes(value) except ValueError: raise error.PyAsn1Error( 'Bad OctetString initializer \'%s\'' % (value, )) else: try: return str(value).encode(self._encoding) except UnicodeEncodeError: raise error.PyAsn1Error( 'Can\'t encode string \'%s\' with \'%s\' codec' % (value, self._encoding))
def getComponent(self, innerFlag=0): if self._currentIdx is None: raise error.PyAsn1Error('Component not chosen') else: c = self._componentValues[self._currentIdx] if innerFlag and isinstance(c, Choice): return c.getComponent(innerFlag) else: return c
def __init__(self, *flags): self._flags = flagNone self._printer = self.defaultPrinter self('running pyasn1 version %s' % __version__) for f in flags: if f not in flagMap: raise error.PyAsn1Error('bad debug flag %s' % (f,)) self._flags = self._flags | flagMap[f] self('debug category \'%s\' enabled' % f)
def __getitem__(self, tagSet): if tagSet in self.__posMap: return self.__posMap[tagSet] elif tagSet in self.__negMap: raise error.PyAsn1Error('Key in negative map') elif self.__defType is not None: return self.__defType else: raise KeyError()
def __init__(self, *namedValues): self.nameToValIdx = {} self.valToNameIdx = {} self.namedValues = () automaticVal = 1 for namedValue in namedValues: if isinstance(namedValue, tuple): name, val = namedValue else: name = namedValue val = automaticVal if name in self.nameToValIdx: raise error.PyAsn1Error('Duplicate name %s' % (name, )) self.nameToValIdx[name] = val if val in self.valToNameIdx: raise error.PyAsn1Error('Duplicate value %s=%s' % (name, val)) self.valToNameIdx[val] = name self.namedValues = self.namedValues + ((name, val), ) automaticVal = automaticVal + 1
def _createComponent(self, asn1Spec, tagSet, value=None): if tagSet[0][1] not in self.tagFormats: raise error.PyAsn1Error('Invalid tag format %r for %r' % ( tagSet[0], self.protoComponent, )) if asn1Spec is None: return self.protoComponent.clone(tagSet) else: return asn1Spec.clone()
def clone(self, parentType, tagMap, uniq=False): if self.__defType is not None and tagMap.getDef() is not None: raise error.PyAsn1Error('Duplicate default value at %s' % (self,)) if tagMap.getDef() is not None: defType = tagMap.getDef() else: defType = self.__defType posMap = self.__posMap.copy() for k in tagMap.getPosMap(): if uniq and k in posMap: raise error.PyAsn1Error('Duplicate positive key %s' % (k,)) posMap[k] = parentType negMap = self.__negMap.copy() negMap.update(tagMap.getNegMap()) return self.__class__( posMap, negMap, defType, )
def prettyIn(self, value): if isinstance(value, str): return value elif isinstance(value, (tuple, list)): try: return ''.join([chr(x) for x in value]) except ValueError: raise error.PyAsn1Error( 'Bad OctetString initializer \'%s\'' % (value, )) else: return str(value)
def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length, state, decodeFun, substrateFun): if substrateFun: return substrateFun(self._createComponent(asn1Spec, tagSet, ''), substrate, length) value, substrate = decodeFun(substrate, asn1Spec, tagSet, length) terminator, substrate = decodeFun(substrate) if eoo.endOfOctets.isSameTypeWith(terminator) and \ terminator == eoo.endOfOctets: return value, substrate else: raise error.PyAsn1Error('Missing end-of-octets terminator')
def setDefaultComponents(self): if self._componentTypeLen == self._componentValuesSet: return idx = self._componentTypeLen while idx: idx = idx - 1 if self._componentType[idx].isDefaulted: if self.getComponentByPosition(idx) is None: self.setComponentByPosition(idx) elif not self._componentType[idx].isOptional: if self.getComponentByPosition(idx) is None: raise error.PyAsn1Error( 'Uninitialized component #%s at %r' % (idx, self))
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
def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length, state, decodeFun, substrateFun): r = self._createComponent(asn1Spec, tagSet) if substrateFun: return substrateFun(r, substrate, length) if r.getTagSet() == tagSet: # explicitly tagged Choice component, substrate = decodeFun(substrate, r.getComponentTagMap()) eooMarker, substrate = decodeFun(substrate) # eat up EOO marker if not eoo.endOfOctets.isSameTypeWith(eooMarker) or \ eooMarker != eoo.endOfOctets: raise error.PyAsn1Error('No EOO seen before substrate ends') else: component, substrate = decodeFun(substrate, r.getComponentTagMap(), tagSet, length, state) if isinstance(component, univ.Choice): effectiveTagSet = component.getEffectiveTagSet() else: effectiveTagSet = component.getTagSet() r.setComponentByType(effectiveTagSet, component, 0, asn1Spec is None) return r, substrate
def fromBinaryString(self, value): bitNo = 8 byte = 0 r = () for v in value: if bitNo: bitNo = bitNo - 1 else: bitNo = 7 r = r + (byte, ) byte = 0 if v == '0': v = 0 elif v == '1': v = 1 else: raise error.PyAsn1Error( 'Non-binary OCTET STRING initializer %s' % (v, )) byte = byte | (v << bitNo) return octets.ints2octs(r + (byte, ))