def __init__(self, name, default, *args, **kwargs): if "implicit_tag" in kwargs: err_msg = "ASN1F_CHOICE has been called with an implicit_tag" raise ASN1_Error(err_msg) self.implicit_tag = None for kwarg in ["context", "explicit_tag"]: setattr(self, kwarg, kwargs.get(kwarg)) ASN1F_field.__init__(self, name, None, context=self.context, explicit_tag=self.explicit_tag) self.default = default self.current_choice = None self.choices = {} self.pktchoices = {} for p in args: if hasattr(p, "ASN1_root"): # should be ASN1_Packet if hasattr(p.ASN1_root, "choices"): for k, v in six.iteritems(p.ASN1_root.choices): self.choices[k] = v # ASN1F_CHOICE recursion else: self.choices[p.ASN1_root.network_tag] = p elif hasattr(p, "ASN1_tag"): if isinstance(p, type): # should be ASN1F_field class self.choices[p.ASN1_tag] = p else: # should be ASN1F_PACKET instance self.choices[p.network_tag] = p self.pktchoices[hash(p.cls)] = (p.implicit_tag, p.explicit_tag ) # noqa: E501 else: raise ASN1_Error("ASN1F_CHOICE: no tag found for one field")
def m2i(self, pkt, s): """ First we have to retrieve the appropriate choice. Then we extract the field/packet, according to this choice. """ if len(s) == 0: raise ASN1_Error("ASN1F_CHOICE: got empty string") _, s = BER_tagging_dec(s, hidden_tag=self.ASN1_tag, explicit_tag=self.explicit_tag) tag, _ = BER_id_dec(s) if tag not in self.choices: if self.flexible_tag: choice = ASN1F_field else: raise ASN1_Error("ASN1F_CHOICE: unexpected field") else: choice = self.choices[tag] if hasattr(choice, "ASN1_root"): # we don't want to import ASN1_Packet in this module... return self.extract_packet(choice, s) elif isinstance(choice, type): # XXX find a way not to instantiate the ASN1F_field return choice(self.name, b"").m2i(pkt, s) else: # XXX check properly if this is an ASN1F_PACKET return choice.m2i(pkt, s)
def m2i(self, pkt, s): # type: (ASN1_Packet, bytes) -> Tuple[ASN1_Object[Any], bytes] """ First we have to retrieve the appropriate choice. Then we extract the field/packet, according to this choice. """ if len(s) == 0: raise ASN1_Error("ASN1F_CHOICE: got empty string") _, s = BER_tagging_dec(s, hidden_tag=self.ASN1_tag, explicit_tag=self.explicit_tag) tag, _ = BER_id_dec(s) if tag in self.choices: choice = self.choices[tag] else: if tag & 0x1f in self.choices: # Try resolve only the tag number choice = self.choices[tag & 0x1f] elif self.flexible_tag: choice = ASN1F_field else: raise ASN1_Error("ASN1F_CHOICE: unexpected field in '%s' " "(tag %s not in possible tags %s)" % (self.name, tag, list(self.choices.keys()))) if hasattr(choice, "ASN1_root"): choice = cast('ASN1_Packet', choice) # we don't want to import ASN1_Packet in this module... return self.extract_packet(choice, s, _underlayer=pkt) elif isinstance(choice, type): return choice(self.name, b"").m2i(pkt, s) else: # XXX check properly if this is an ASN1F_PACKET return choice.m2i(pkt, s)
def __init__( self, name, # type: str default, # type: Optional[_A] context=None, # type: Optional[Type[ASN1_Class]] implicit_tag=None, # type: Optional[int] explicit_tag=None, # type: Optional[int] flexible_tag=False, # type: Optional[bool] ): # type: (...) -> None if context is not None: self.context = context self.name = name if default is None: self.default = default # type: Optional[_A] elif isinstance(default, ASN1_NULL): self.default = default # type: ignore else: self.default = self.ASN1_tag.asn1_object(default) # type: ignore self.flexible_tag = flexible_tag if (implicit_tag is not None) and (explicit_tag is not None): err_msg = "field cannot be both implicitly and explicitly tagged" raise ASN1_Error(err_msg) self.implicit_tag = implicit_tag self.explicit_tag = explicit_tag # network_tag gets useful for ASN1F_CHOICE self.network_tag = int(implicit_tag or explicit_tag or self.ASN1_tag)
def __init__(self, name, default, *args, **kwargs): # type: (str, Any, *_CHOICE_T, **Any) -> None if "implicit_tag" in kwargs: err_msg = "ASN1F_CHOICE has been called with an implicit_tag" raise ASN1_Error(err_msg) self.implicit_tag = None for kwarg in ["context", "explicit_tag"]: setattr(self, kwarg, kwargs.get(kwarg)) super(ASN1F_CHOICE, self).__init__(name, None, context=self.context, explicit_tag=self.explicit_tag) self.default = default self.current_choice = None self.choices = {} # type: Dict[int, _CHOICE_T] self.pktchoices = {} for p in args: if hasattr(p, "ASN1_root"): p = cast('ASN1_Packet', p) # should be ASN1_Packet if hasattr(p.ASN1_root, "choices"): root = cast(ASN1F_CHOICE, p.ASN1_root) for k, v in six.iteritems(root.choices): # ASN1F_CHOICE recursion self.choices[k] = v else: self.choices[p.ASN1_root.network_tag] = p elif hasattr(p, "ASN1_tag"): p = cast(Union[ASN1F_PACKET, Type[ASN1F_field[Any, Any]]], p) if isinstance(p, type): # should be ASN1F_field class self.choices[int(p.ASN1_tag)] = p else: # should be ASN1F_field instance self.choices[p.network_tag] = p if p.implicit_tag is not None: self.choices[p.implicit_tag & 0x1f] = p self.pktchoices[hash(p.cls)] = (p.implicit_tag, p.explicit_tag ) # noqa: E501 else: raise ASN1_Error("ASN1F_CHOICE: no tag found for one field")
def i2m(self, pkt, x): # type: (ASN1_Packet, Union[bytes, _I, _A]) -> bytes if x is None: return b"" if isinstance(x, ASN1_Object): if (self.ASN1_tag == ASN1_Class_UNIVERSAL.ANY or x.tag == ASN1_Class_UNIVERSAL.RAW or x.tag == ASN1_Class_UNIVERSAL.ERROR or self.ASN1_tag == x.tag): s = x.enc(pkt.ASN1_codec) else: raise ASN1_Error("Encoding Error: got %r instead of an %r for field [%s]" % (x, self.ASN1_tag, self.name)) # noqa: E501 else: s = self.ASN1_tag.get_codec(pkt.ASN1_codec).enc(x) return BER_tagging_enc(s, implicit_tag=self.implicit_tag, explicit_tag=self.explicit_tag)
def __init__(self, name, default, context=None, implicit_tag=None, explicit_tag=None, flexible_tag=False): self.context = context self.name = name if default is None: self.default = None elif isinstance(default, ASN1_NULL): self.default = default else: self.default = self.ASN1_tag.asn1_object(default) self.flexible_tag = flexible_tag if (implicit_tag is not None) and (explicit_tag is not None): err_msg = "field cannot be both implicitly and explicitly tagged" raise ASN1_Error(err_msg) self.implicit_tag = implicit_tag self.explicit_tag = explicit_tag # network_tag gets useful for ASN1F_CHOICE self.network_tag = implicit_tag or explicit_tag or self.ASN1_tag