def envelope(challenge, cert, signature): user_certificate = decoder.decode(cert) version_section = univ.Integer(1) digest_section = univ.Set() digest_section[0] = univ.Sequence() digest_section[0][0] = univ.ObjectIdentifier('1.3.14.3.2.26') digest_section[0][1] = univ.Null() challenge_section = univ.Sequence() challenge_section[0] = univ.ObjectIdentifier('1.2.840.113549.1.7.1') challenge_section[1] = univ.OctetString(value=base64.b64decode(challenge), tagSet=tag.TagSet( (), tag.Tag(0, 0, 4), tag.Tag(128, 32, 0))) cert_section = univ.Sequence( tagSet=tag.TagSet((), tag.Tag(0, 32, 16), tag.Tag(128, 32, 0))) cert_section[0] = user_certificate[0][0] cert_section[1] = user_certificate[0][1] cert_section[2] = user_certificate[0][2] response_section = univ.Set() response_section[0] = univ.Sequence() response_section[0][0] = univ.Integer(1) response_section[0][1] = univ.Sequence() response_section[0][1][0] = user_certificate[0][0][3] response_section[0][1][1] = user_certificate[0][0][1] response_section[0][2] = univ.Sequence() response_section[0][2][0] = univ.ObjectIdentifier('1.3.14.3.2.26') response_section[0][2][1] = univ.Null() response_section[0][3] = univ.Sequence() response_section[0][3][0] = univ.ObjectIdentifier('1.2.840.113549.1.1.1') response_section[0][3][1] = univ.Null() response_section[0][4] = univ.OctetString(signature) outer = univ.Sequence() outer[0] = univ.ObjectIdentifier('1.2.840.113549.1.7.2') outer[1] = univ.Sequence( tagSet=tag.TagSet((), tag.Tag(0, 32, 16), tag.Tag(128, 32, 0))) outer[1][0] = version_section outer[1][1] = digest_section outer[1][2] = challenge_section outer[1][3] = cert_section outer[1][4] = response_section encoded = encoder.encode(outer) b64 = base64.b64encode(encoded).decode('utf-8') return encoded
def encodeValue(self, value, encodeFun, **options): valueLength = len(value) if valueLength % 8: alignedValue = value << (8 - valueLength % 8) else: alignedValue = value maxChunkSize = options.get('maxChunkSize', 0) if not maxChunkSize or len(alignedValue) <= maxChunkSize * 8: substrate = alignedValue.asOctets() return int2oct(len(substrate) * 8 - valueLength) + substrate, False, True # strip off explicit tags alignedValue = alignedValue.clone( tagSet=tag.TagSet(value.tagSet.baseTag, value.tagSet.baseTag) ) stop = 0 substrate = null while stop < valueLength: start = stop stop = min(start + maxChunkSize * 8, valueLength) substrate += encodeFun(alignedValue[start:stop], **options) return substrate, True, True
def __call__(self, value, defMode=True, maxChunkSize=0): if not defMode and not self.supportIndefLength: raise error.PyAsn1Error( 'Indefinite length encoding not supported by this codec') if debug.logger & debug.flagEncoder: logger = debug.logger else: logger = None if logger: logger( 'encoder called in %sdef mode, chunk size %s for type %s, value:\n%s' % (not defMode and 'in' or '', maxChunkSize, value.prettyPrintType(), value.prettyPrint())) tagSet = value.tagSet if len(tagSet) > 1: concreteEncoder = explicitlyTaggedItemEncoder else: try: concreteEncoder = self.__typeMap[value.typeId] except KeyError: # use base type for codec lookup to recover untagged types baseTagSet = tag.TagSet(value.tagSet.baseTag, value.tagSet.baseTag) try: concreteEncoder = self.__tagMap[baseTagSet] except KeyError: raise error.PyAsn1Error('No encoder for %s' % (value, )) if logger: logger('using value codec %s chosen by %s' % (concreteEncoder.__class__.__name__, tagSet)) substrate = concreteEncoder.encode(self, value, defMode, maxChunkSize) if logger: logger('built %s octets of substrate: %s\nencoder completed' % (len(substrate), debug.hexdump(substrate))) return substrate
def _decodeComponents(self, substrate, decodeFun, tagSet, allowEoo=True): components = [] componentTypes = set() while substrate: component, substrate = decodeFun(substrate, allowEoo=True) if component is eoo.endOfOctets: break components.append(component) componentTypes.add(component.tagSet) # Now we have to guess is it SEQUENCE/SET or SEQUENCE OF/SET OF # The heuristics is: # * 0-1 component -> likely SEQUENCE OF/SET OF # * 1+ components of the same type -> likely SEQUENCE OF/SET OF # * otherwise -> likely SEQUENCE/SET if len(components) > 1 or len(componentTypes) > 1: protoComponent = self.protoRecordComponent else: protoComponent = self.protoSequenceComponent asn1Object = protoComponent.clone( # construct tagSet from base tag from prototype ASN.1 object # and additional tags recovered from the substrate tagSet=tag.TagSet(protoComponent.tagSet.baseTag, * tagSet.superTags)) for idx, component in enumerate(components): asn1Object.setComponentByPosition(idx, component, verifyConstraints=False, matchTags=False, matchConstraints=False) return asn1Object, substrate
def __call__(self, pyObject, asn1Spec, **options): if LOG: debug.scope.push(type(pyObject).__name__) LOG('decoder called at scope %s, working with type %s' % (debug.scope, type(pyObject).__name__)) if asn1Spec is None or not isinstance(asn1Spec, base.Asn1Item): raise error.PyAsn1Error('asn1Spec is not valid (should be an instance of an ASN.1 Item, not %s)' % asn1Spec.__class__.__name__) try: valueDecoder = self.__typeMap[asn1Spec.typeId] except KeyError: # use base type for codec lookup to recover untagged types baseTagSet = tag.TagSet(asn1Spec.tagSet.baseTag, asn1Spec.tagSet.baseTag) try: valueDecoder = self.__tagMap[baseTagSet] except KeyError: raise error.PyAsn1Error('Unknown ASN.1 tag %s' % asn1Spec.tagSet) if LOG: LOG('calling decoder %s on Python type %s <%s>' % (type(valueDecoder).__name__, type(pyObject).__name__, repr(pyObject))) value = valueDecoder(pyObject, asn1Spec, self, **options) if LOG: LOG('decoder %s produced ASN.1 type %s <%s>' % (type(valueDecoder).__name__, type(value).__name__, repr(value))) debug.scope.pop() return value
def testTagsEquivalence(self): integer = univ.Integer( 2, tag.TagSet((), tag.Tag(tag.tagClassContext, 0, 0))) assert decoder.decode(ints2octs((0x9f, 0x80, 0x00, 0x02, 0x01, 0x02)), asn1Spec=integer) == decoder.decode( ints2octs((0x9f, 0x00, 0x02, 0x01, 0x02)), asn1Spec=integer)
def __call__(self, value, defMode=1, maxChunkSize=0): tagSet = value.getTagSet() if len(tagSet) > 1: concreteEncoder = explicitlyTaggedItemEncoder else: concreteEncoder = self.__codecMap.get(tagSet) if not concreteEncoder: # XXX baseTagSet = tagSet.getBaseTag() if baseTagSet: concreteEncoder = self.__codecMap.get( tag.TagSet(baseTagSet, baseTagSet)) else: concreteEncoder = self.__codecMap.get(self.__emptyTagSet) if concreteEncoder: return concreteEncoder.encode(self, value, defMode, maxChunkSize) else: raise Error('No encoder for %s' % value)
def encodeValue(self, value, encodeFun, **options): maxChunkSize = options.get('maxChunkSize', 0) if not maxChunkSize or len(value) <= maxChunkSize: return value.asOctets(), False, True else: # will strip off explicit tags baseTagSet = tag.TagSet(value.tagSet.baseTag, value.tagSet.baseTag) pos = 0 substrate = null while True: chunk = value.clone(value[pos:pos + maxChunkSize], tagSet=baseTagSet) if not chunk: break substrate += encodeFun(chunk, **options) pos += maxChunkSize return substrate, True, True
def __call__(self, value, **options): if debug.logger & debug.flagEncoder: logger = debug.logger else: logger = None if logger: logger('encoder called in %sdef mode, chunk size %s for type %s, value:\n%s' % (not options.get('defMode', True) and 'in' or '', options.get('maxChunkSize', 0), value.prettyPrintType(), value.prettyPrint())) if self.fixedDefLengthMode is not None: options.update(defMode=self.fixedDefLengthMode) if self.fixedChunkSize is not None: options.update(maxChunkSize=self.fixedChunkSize) tagSet = value.tagSet try: concreteEncoder = self.__typeMap[value.typeId] except KeyError: # use base type for codec lookup to recover untagged types baseTagSet = tag.TagSet(value.tagSet.baseTag, value.tagSet.baseTag) try: concreteEncoder = self.__tagMap[baseTagSet] except KeyError: raise error.PyAsn1Error('No encoder for %s' % (value,)) if logger: logger('using value codec %s chosen by %s' % (concreteEncoder.__class__.__name__, tagSet)) substrate = concreteEncoder.encode(value, self, **options) if logger: logger('codec %s built %s octets of substrate: %s\nencoder completed' % (concreteEncoder, len(substrate), debug.hexdump(substrate))) return substrate