Make a more ASN1-friendly CHOICE field (Enhancement)
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 12.6k
- Forks
- 2.2k
- Avg merge
- 1d 4h
- Merged PRs (30d)
- 56
Description
This issue is a proposal to make a different ASN1 choice field type, say ASN1F_NAMEDCHOICE, that looks like a sequence. With this, choices from ASN1 definitions can be more easily translated to scapy, and a choice definition can be reused more easily in several packets/sequences.
Like a sequence, each alternative of the choice will be named. But only one value will be built when the field is expressed, and only one field will be created when the choice is dissected. Also, the value of the choice can be the last alternative that was assigned to any member.
Example borrowed from CMIP:
ObjectClass ::= CHOICE {
ocglobalForm [0] IMPLICIT OBJECT IDENTIFIER,
oclocalForm [1] IMPLICIT INTEGER
}
GetArgument ::= SEQUENCE {
baseManagedObjectClass ObjectClass,
baseManagedObjectInstance ObjectInstance,
...
}
GetResult ::= SEQUENCE {
managedObjectClass ObjectClass OPTIONAL,
managedObjectInstance ObjectInstance OPTIONAL,
currentTime [5] IMPLICIT GeneralizedTime OPTIONAL,
...
}
This is used in several sequences in this standard. The current syntax is clunky because each ASN1F_CHOICE instance must be named when it is defined rather than used, which results in extra names and encapsulations. Also the current ASN1F_CHOICE alternatives are class types which make it an additional burden when implicit or explicit tags are specified: one must create extra classes when the standard ASN1 field constructors have kwargs for them. Additionally, (I think) it's better to specify the name of the alternative which is being used in a standard.
With the syntax in this ticket proposal:
class ObjectClass(ASN1_Packet):
ASN1_codec = ASN1_Codecs.BER
ASN1_root = ASN1F_NAMEDCHOICE(
ASN1F_OID("ocglobalForm", None, implicit_tag=0x80),
ASN1F_INTEGER("oclocalForm", None, implicit_tag=0x81))
class GetArgument(ASN1_Packet):
ASN1_codec = ASN1_Codecs.BER
ASN1_root = ASN1F_SEQUENCE(
ASN1F_PACKET("baseManagedObjectClass", ObjectClass(), ObjectClass),
ASN1F_PACKET("baseManagedObjectInstance", ObjectInstance(), ObjectInstance),
....
class GetResult(ASN1_Packet):
ASN1_codec = ASN1_Codecs.BER
ASN1_root = ASN1F_SEQUENCE(
ASN1F_optional(ASN1F_PACKET("managedObjectClass", None, ObjectClass)),
ASN1F_optional(ASN1F_PACKET("managedObjectInstance", None, ObjectInstance)),
ASN1F_optional(ASN1F_GENERALIZED_TIME("currentTime", None, implicit_tag=0x85)),
....
Some hybrid of the sequence and choice does almost everything this new field type should; adapting them to become a "named choice" requires a bit more work/constraint to make it express only one alternative in encoding/decoding (basically iterate through the list alternatives and stop after one works) and not have a tag of its own.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by comparing the existing ASN1F_CHOICE and ASN1F_SEQUENCE field types described in the issue, including how their alternatives are named and tagged. Define the named-choice behavior for encoding and decoding, including selecting one alternative and retaining the last assigned value. Done means the proposed ASN.1 definitions can be reused across sequences without extra alternative classes or a choice-level tag.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- networking
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100