secdev / secdev/scapy

Make a more ASN1-friendly CHOICE field (Enhancement)

Open
#2,165 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

discussion
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.