BER in ASN.1: Recognizing a Values Structure
In ASN.1, a values structure is recognized by the presence of a named type followed by an assignment operator (::=) and a value notation that matches the type’s definition, such as MyStruct ::= SEQUENCE { a INTEGER, b BOOLEAN } followed by myValue MyStruct ::= { a 5, b TRUE }. You identify it by seeing a value assignment (a name, a type, and ::=) where the right-hand side uses braces { } with field names and values, rather than a type assignment that defines a new structure.
Background: What ASN.1 Values Are
ASN.1 (Abstract Syntax Notation One) is a formal language for describing data structures that need to be exchanged between systems, often in telecommunications, cryptography, and network protocols. The standard (ITU-T X.680 series) distinguishes between type assignments and value assignments. A type assignment creates a reusable blueprint, like Person ::= SEQUENCE { name UTF8String, age INTEGER }. A value assignment instantiates that blueprint with actual data, like john Person ::= { name "John", age 30 }. Recognizing a values structure means spotting the difference between these two in a specification or an encoded message.
In practice, you encounter values structures in two places: in the ASN.1 source text (where they appear as named constants or default values) and in the encoded bytes after applying a transfer syntax like BER (Basic Encoding Rules), DER, or PER. This article focuses on the source text, since that is where the word “structure” most often applies.
How to Spot a Values Structure in ASN.1 Source
The quickest way to recognize a values structure is to look for the ::= operator and then examine what follows it. There are two main patterns:
- Type assignment:
Name ::= TypeNotation— the right side defines a type (e.g.,SEQUENCE,INTEGER,CHOICE). Example:Color ::= ENUMERATED { red, green, blue }. - Value assignment:
name Name ::= ValueNotation— the right side provides an actual value. Example:myColor Color ::= green.
For a values structure specifically, the value notation uses braces with named fields. A constructed value like { name "Alice", age 25 } is a values structure. The field names must match the type’s component identifiers. If the type is a SEQUENCE, the value is written in the same order as the type definition (unless using component notation with names, which is allowed). For a SET, order does not matter, but names are required if the type has named components.
Here is a concrete example:
Person ::= SEQUENCE {
name UTF8String,
age INTEGER
}
alice Person ::= { name "Alice", age 30 }
The second line is a values structure. The clue is that alice is lowercase (by convention, value names start lowercase) and the right side is a brace-enclosed list with component names.
Distinguishing Values from Types in Complex Definitions
Ambiguity arises when a type itself uses braces. For example, Seq ::= SEQUENCE { a INTEGER, b BOOLEAN } uses braces, but it is a type assignment, not a values structure. The difference is the presence of a value name before the type. In mySeq Seq ::= { a 1, b TRUE }, there are two names: mySeq (the value name) and Seq (the type). In a type assignment, there is only one name before ::=.
Another clue is the content inside braces. In a type definition, you see keywords like SEQUENCE, SET, CHOICE, and component types. In a values structure, you see literal values: numbers, strings, TRUE/FALSE, or nested braces. For instance, { 1, 2, 3 } could be a value for a SEQUENCE OF INTEGER, while { a 1, b 2 } is a value for a named-component structure.
Also watch for the OPTIONAL and DEFAULT keywords in the type. If a component has a default value, that default is itself a values structure embedded in the type definition. Example: Status ::= SEQUENCE { code INTEGER DEFAULT 0 } — here 0 is a value, but the whole line is still a type assignment.
Recognizing Values Structures in BER-Encoded Bytes
When you look at raw BER data, you are not seeing ASN.1 text but a binary encoding. A values structure appears as a constructed tag (bit 6 of the identifier octet set to 1) followed by a length and then child elements. For a SEQUENCE, the tag is 0x30 (universal tag 16, constructed). For a SET, it is 0x31. Inside, each component is encoded as its own TLV (Tag-Length-Value) triple.
To recognize a values structure in BER, look for a constructed tag whose children are themselves TLVs. For example, bytes 30 06 02 01 05 01 01 FF decode as a SEQUENCE containing an INTEGER (value 5) and a BOOLEAN (TRUE). The outer 0x30 tells you it is a structured value, not a primitive like an INTEGER (tag 0x02) or a BOOLEAN (tag 0x01).
One common mistake is confusing a constructed tag with a primitive that has a long length. The constructed bit is in the tag octet, not the length. If the tag’s low 5 bits are 16 or 17 (SEQUENCE or SET), it is a structure. Other constructed tags (like 0x20 for a constructed string) can also hold values structures, but those are less common in typical protocol data.
Common Misconceptions and Pitfalls
A frequent error is thinking that any brace-enclosed text is a values structure. In ASN.1, braces also appear in type definitions for SEQUENCE, SET, and CHOICE. The rule is simple: if the name before ::= is followed by another name, it is a value assignment; if not, it is a type assignment. Another pitfall is confusing SEQUENCE OF with SEQUENCE. A values structure for SEQUENCE OF INTEGER is written as { 1, 2, 3 } (no field names), while a SEQUENCE with named components uses { a 1, b 2 }. If you see names inside braces, check the type definition to confirm they match.
Also note that ASN.1 allows parameterized types and values. A value assignment can include parameters, like myVal MyType{INTEGER} ::= { 42 }. The recognition rule still holds: the right side is a value because it has a value name before the type. Finally, beware of object identifier values, which are written as { 1 2 840 113549 } — these are values but not structures in the SEQUENCE sense; they are just lists of integers.
Practical Examples for Quick Recognition
Here are three examples to test your recognition skill:
Point ::= SEQUENCE { x INTEGER, y INTEGER }— Type assignment (no value).origin Point ::= { x 0, y 0 }— Values structure (value nameorigin, typePoint, brace value).numbers SEQUENCE OF INTEGER ::= { 1, 2, 3 }— Values structure (note the type is inline, but the value name is present).
In example 3, the type is written directly after the value name, which is legal. The right side is a value because the left side has two identifiers: numbers (value) and SEQUENCE OF INTEGER (type). If the line were Numbers ::= SEQUENCE OF INTEGER, it would be a type assignment.
When reading a specification, look for lines where the first token is lowercase (value names conventionally start with a lowercase letter, while type names start with uppercase). This convention is not enforced by the standard, but it is nearly universal in real-world ASN.1 modules. If you see lowercaseName UppercaseType ::= { ... }, you are almost certainly looking at a values structure.
Why It Matters in Real Protocols
Recognizing values structures is not just an academic exercise. In protocols like X.509 certificates, LDAP, SNMP, and PKCS standards, ASN.1 modules define both types and default values. For example, a certificate extension might have a default value defined as a values structure. When implementing an encoder or decoder, you must know whether a given definition is a type (to parse incoming data) or a value (to know what to send when no explicit value is provided). Misreading a value assignment as a type leads to compile errors in ASN.1 compilers and runtime failures in parsers.
Also, when debugging a BER dump, recognizing the outer structure tag helps you navigate the tree. A SEQUENCE tag (0x30) means you should expect child TLVs; a primitive tag like 0x02 means you should read a single integer. Tools like openssl asn1parse display this hierarchy, but understanding the underlying pattern lets you verify the tool’s output.
Frequently Asked Questions
What is the difference between a type and a value in ASN.1?
A type defines the shape of data (e.g., SEQUENCE { a INTEGER }), while a value is a concrete instance of that type (e.g., { a 5 }). In the source text, a type assignment has one name before ::=, while a value assignment has two: the value name and the type name.
Can a values structure contain nested values structures?
Yes. If a component of a SEQUENCE is itself a SEQUENCE, then the outer value’s braces will contain an inner brace-enclosed value. For example, outer ::= SEQUENCE { inner SEQUENCE { x INTEGER } } with a value outerVal ::= { inner { x 1 } }.
How do I recognize a values structure in a BER hex dump?
Look for a tag byte with the constructed bit set (0x30 for SEQUENCE, 0x31 for SET). Then check that the following length is consistent with the number of child TLVs inside. If the children are themselves valid TLVs, it is a structured value.
Are SET and SEQUENCE values written the same way?
No. In a SEQUENCE value, components must appear in the order defined by the type. In a SET value, order is not significant, but if the type has named components, you must include the names. Both use braces, but the order rule differs.
What does ::= { } with nothing inside mean?
It is an empty value for a structure that has no required components, or a value for a SEQUENCE {} type. It is valid and simply means no fields are present.
Can a value name be uppercase?
Technically yes, but the ASN.1 convention is that type names start with an uppercase letter and value names start with a lowercase letter. Following this convention makes recognition much easier, but you should not rely on it alone.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.