1. ASN.1 for space
How spacecraft communicate
A spacecraft and its ground station exchange structured messages. A telecommand can switch a subsystem on, change its operating mode, or request an operation; a telemetry packet can report temperatures, voltages, subsystem status, counters, and scientific measurements. The sender and receiver must agree exactly on the structure and meaning of every message.
For example:
SpacecraftStatus
spacecraftId: integer from 0 to 255
temperature: integer from -100 to +100
mode: one of SAFE, NOMINAL, EMERGENCY
What ASN.1 actually is
ASN.1 (Abstract Syntax Notation One) is a formal language for defining data types, values, and constraints independently of the programming language and of their binary representation on the wire.
So ASN.1 is not itself the serialization format. It defines the structure and allowed values of messages.
An ASN.1 definition could look conceptually like:
SpacecraftStatus ::= SEQUENCE {
spacecraftId INTEGER (0..255),
temperature INTEGER (-100..100),
mode ENUMERATED { safe, nominal, emergency }
}This says what the message contains.
It does not yet completely answer which bits are transmitted on the communication link.
That second problem is handled by an encoding rule.
ITU-T defines ASN.1 as a notation for defining abstract data types; the original ASN1SCC paper likewise describes ASN.1 specifications as platform- and language-independent descriptions of data structures.
From an ASN.1 type to bits
Suppose both the spacecraft and the ground station know this definition:
Speed ::= INTEGER (0..255)The value 37 must eventually become bits.
Different ASN.1 encoding rules define different ways of turning the same ASN.1 value into bytes or bits.
BER: self-describing but relatively verbose
BER — Basic Encoding Rules uses a Tag-Length-Value (TLV) style representation.
Very roughly:
what this element is | how long it is | the actual value
This makes BER flexible, but introduces overhead because metadata such as tags and lengths are carried in the message.
PER: use the ASN.1 constraints instead of transmitting information twice
PER — Packed Encoding Rules takes a different approach.
If both sides already possess the ASN.1 specification, the encoder does not need to transmit information that the specification already fixes.
Consider:
Speed ::= INTEGER (0..255)The receiver already knows that:
- the field is an integer;
- its minimum is 0;
- its maximum is 255.
There are exactly 256 possible values, so PER can represent the value in exactly 8 bits.
There is no need to send a generic integer tag, a separate range description, or other metadata that the receiver already knows from the schema.
Similarly:
Mode ::= ENUMERATED {
safe,
nominal,
emergency
}There are only three possibilities. PER can encode which one was selected using the minimum number of bits needed to distinguish them.
Likewise, in a SEQUENCE, the order and types of fields are already fixed by the ASN.1 specification, so they do not have to be repeatedly identified in every packet.
This is what “PER exploits the ASN.1 specification” means in concrete terms: constraints, ordering, cardinality, and structure known to both endpoints are used to compress the representation instead of being re-described in every message.
uPER: PER without byte-alignment padding
PER has aligned and unaligned variants.
uPER — Unaligned Packed Encoding Rules does not force encoded fields to start on byte boundaries.
If one field needs 3 bits and the next needs 5 bits:
AAA BBBBB
they can be packed directly next to each other rather than adding padding only for octet alignment.
ASN1SCC also supports XER — XML Encoding Rules, which encodes data in XML. XER favors a human-readable, text-based representation rather than the compact binary representation needed on constrained links.
Satellite links naturally favor the most compact communications possible.
There is also ACN — ASN.1 Control Notation, which complements ASN.1 by letting engineers control representation details. This means that it can specify the exact binary wire layout, including exact bit widths, byte order, alignment, and padding.
A major example is the Packet Utilization Standard (PUS) used for spacecraft Telemetry/Telecommand (TM/TC) communication.
The PUS binary format cannot, in general, be reproduced using BER/PER alone, as explained in the original ASN1SCC paper. ACN was introduced to express protocol-specific layouts while retaining ASN.1 as the formal description of the message structures.
2. From specification to code
ASN1SCC and the actual flight software
An ASN.1 file is only a specification. To make things work, we need an implementation. ESA created the ASN.1 Space Certifiable Compiler, ASN1SCC, an open-source ASN.1 compiler for embedded systems.
ASN1SCC is a code generator. It runs on the developer's computer, reads ASN.1/ACN specifications, and generates code in C, Ada, or Scala. For example, it produces Message.c and Message.h, containing data structures corresponding to the ASN.1 types and functions such as Message_Encode() and Message_Decode().
The runtime library
ASN1SCC does not generate every low-level operation independently from scratch for every message type.
The generated code does not implement every operation autonomously. It calls common functions to read bits, decode integers, manage buffers, and handle uPER and ACN.
In C, these are files such as:
asn1crt.c
asn1crt_encoding.c
asn1crt_encoding_uper.c
asn1crt_encoding_acn.c
These files are compiled together with the generated code and the application. The runtime library is therefore included in the operational software; the ASN1SCC compiler normally is not.
This distinction matters for security.
If a bug is in generated code associated only with one specific ASN.1 schema, its propagation may be limited.
If a vulnerability is instead in a shared runtime function, that code may be used by many independently generated applications.
Conceptually:
ASN1SCC
|
+---------------+---------------+
| | |
v v v
Mission A code Mission B code Mission C code
| | |
+------- common runtime --------+
That is what makes vulnerabilities in compiler/runtime ecosystems interesting from a software-supply-chain perspective.
3. The vulnerabilities
Our analysis of ASN1SCC identified multiple memory-safety vulnerabilities in its runtime libraries.
The first published CVE identifiers include:
The vulnerabilities were responsibly disclosed to ESA and fixed upstream.
Detailed technical descriptions, affected functions, vulnerable code, patches, and security impact are maintained in the official ESA GitHub Security Advisories.
Two of these vulnerabilities can lead to remote code execution (RCE). RCE means that a malicious input does not merely crash the decoder: under the right conditions, it can make the program execute instructions chosen by the attacker.
CVE-2026-75614: an invalid length can become a buffer overflow
This is probably the most dangerous of the three vulnerabilities.
ASN.1 can define a variable-size value with a minimum and maximum length. For example:
Payload ::= OCTET STRING (SIZE(0..5))This means that Payload may contain from 0 to 5 bytes. There are six valid lengths: 0, 1, 2, 3, 4, and 5.
uPER needs 3 bits to represent the length:
000 = 0
001 = 1
010 = 2
011 = 3
100 = 4
101 = 5
110 = 6 <- invalid
111 = 7 <- invalid
Three bits can represent eight values, but this ASN.1 type allows only six of them. The decoder should therefore reject 110 and 111.
The vulnerable function did not perform this final check. If a malicious packet contained 111, the decoder accepted 7 as the length even though the destination buffer had space for at most 5 bytes.
Generated decoders then used that value directly as:
- the number of loop iterations;
- the number of bytes to copy;
- the number of bits to read.
In simple terms, the software prepared five boxes but trusted a packet that told it to fill seven. The final two writes could go past the end of the destination buffer and overwrite other memory.
This can lead to remote code execution (RCE), albeit exploitability on a real target still depends on its memory layout and protections, including whether writable memory can be executed and whether control-flow or memory-safety mitigations are enabled.
This pattern is used for common variable-size ASN.1 types, including SEQUENCE OF, OCTET STRING, BIT STRING, and variable-length strings. The problem therefore could propagate to any generated code containing one of these types. uPER uses the vulnerable constrained-integer decoder, and the ACN implementation shares the same runtime function.
The fix adds the missing rule: after decoding the bits, reject the value if it is greater than the maximum permitted by the ASN.1 constraint.
CVE-2026-75615: an invalid character index reads outside the alphabet
ASN.1 can restrict a string to a specific alphabet. For example, a string may allow only the 26 uppercase letters from A to Z.
The encoder does not need to transmit each complete character. It can transmit the position of that character in the permitted alphabet:
0 = A
1 = B
2 = C
...
25 = Z
Representing 26 positions requires 5 bits. However, 5 bits can represent 32 values, from 0 to 31:
00000 = 0 = A
11001 = 25 = Z
11010 = 26 = invalid
...
11111 = 31 = invalid
The ACN runtime and the uPER-generated decoder did not verify that the decoded index was between 0 and 25 before using it as allowedCharSet[charIndex].
For example, the bit pattern 11010 represents index 26. There is no character 26 in a 26-character table: the final valid position is 25. The decoder therefore read one position past the end of the alphabet array.
This is an out-of-bounds read, rather than the direct out-of-bounds write in the previous example. Depending on the target and memory layout, it may return unrelated memory as a character, produce corrupted output, or crash the process.
The fix adds a bounds check before indexing the character table. Invalid bit patterns are now rejected instead of being interpreted as characters.
CVE-2026-76077: a long XML tag overflows a stack buffer
XER represents ASN.1 values using XML. A simplified message may look like this:
<SpacecraftStatus>
...
</SpacecraftStatus>To parse the XML, the XER runtime reads names such as SpacecraftStatus into a fixed-size character array stored on the stack.
The vulnerable parser copied characters into that array without first checking whether the complete tag name would fit. An XML tag name containing 100 or more characters could therefore continue writing beyond the end of the local buffer.
Conceptually:
<AAAAAAAAAA...AAAAAAAAAA>fixed stack buffer: [ space for the expected tag name ]
long XML tag: [ characters continue past the buffer ---> ]
This is a stack buffer overflow that can lead to RCE as well. As with the first vulnerability, practical exploitation depends on the target architecture, compiler options, memory layout, and protections such as stack canaries, non-executable memory, position-independent executables, and address randomization.
This vulnerability concerns the XER/XML decoder. It does not require uPER or ACN.
The fix limits the number of characters copied into the token buffer and also adds checks to prevent the parser from reading beyond the end of the received XML data.
4. Impact
PUS-C, formally ECSS-E-ST-70-41C, defines reusable services and packet structures for communication between spacecraft and ground systems. PUS-C does not require ASN1SCC, but an ESA-funded PUS-C Types Library expresses these packet definitions in ASN.1 and uses ACN to describe their binary layout. ASN1SCC can compile those definitions into the encoders and decoders used by onboard and ground software. A defect in shared generation logic or runtime functions may therefore be reproduced in different programs built with the same tool.
Public sources document ASN1SCC-generated software in at least two ESA missions. For CHEOPS, the official TASTE website states that ASN1SCC generated the message marshallers for the application software. For PROBA-3, the same source reports extensive use of TASTE's data-modelling tools in both the onboard payload and the ground segment. A 2024 ASN1SCC case study identifies both missions as users of code generated from the PUS-C ASN.1/ACN specification.
This does not mean that CHEOPS, PROBA-3, or any other named mission is vulnerable. Using PUS-C does not necessarily imply using ASN1SCC, and using ASN1SCC does not establish that an affected version was deployed. The public ESA fix records the vulnerabilities as reported against ASN1SCC v4.6.0.17; actual impact depends on the version, generated and runtime files included in the build, enabled encoding rules, and whether untrusted input can reach the affected decoder.