der.h(3)

📦
version 2.2.0 · 2 versions
, in fedora 44

🦋 der.h — Library Functions Manual 🦋

okay so hi bestie 💖 this is der.h(3) — section 3 of the manual, the Library Functions Manual — and it is genuinely a whole vibe. It's the header where the Distinguished Encoding Rules live, and it is stacked with macros and functions. Not me about to walk you through every single one 🫶


🌸 NAME 🌸

der.h — Отличительные правила кодирования (Distinguished Encoding Rules) 💅


🎀 SYNOPSIS 🎀

#include 'bee2/defs.h'

🧚 Классы 🧚

  • struct der_anchor_t — the anchor you hold onto while you're encoding containers ✨

💫 Макросы 💫

  • #define derSIZEEnc(der, val) — SIZE encoding 🍓
  • #define derSIZEDec(val, der, count) — SIZE encoding (and yes, the page literally says "encoding" here, bestie, I'm just the messenger 🙈)
  • #define derSIZEDec2(der, count, val) — check a SIZE code ✅
  • #define derUINTEnc(der, val, len) — UINT encoding ✨
  • #define derUINTDec(val, len, der, count) — UINT decoding
  • #define derUINTDec2(val, der, count, len) — UINT decoding, but with a length check 👀
  • #define derBITEnc(der, val, len) — BIT encoding 🌈
  • #define derBITDec(val, len, der, count) — BIT decoding
  • #define derBITDec2(val, der, count, len) — BIT decoding, with a length check 👀
  • #define derNULLEnc(der) — NULL encoding 🕳️
  • #define derNULLDec(der, count) — check a NULL code ✅
  • #define derTOCTEnc(der, tag, val, len) — TOCT encoding
  • #define derOCTEnc(der, val, len) — OCT encoding
  • #define derOCTDec(val, len, der, count) — OCT decoding
  • #define derOCTDec2(val, der, count, len) — OCT decoding, with a length check 👀
  • #define derTOCTDec3 derDec4 — check a TOCT code ✅
  • #define derOCTDec3(der, count, val, len) — check an OCT code ✅
  • #define derPSTREnc(der, val) — PSTR encoding 💌
  • #define derPSTRDec(val, len, der, count) — PSTR decoding
  • #define derSEQEncStart(anchor, der, pos) — start encoding a SEQ 🎬
  • #define derSEQEncStop derTSEQEncStop — finish encoding a SEQ 🏁
  • #define derSEQDecStart(anchor, der, count) — start decoding a SEQ 🎬
  • #define derSEQDecStop derTSEQDecStop — finish decoding a SEQ 🏁

👑 Функции 👑

  • size_t derTLEnc (octet der[], u32 tag, size_t len) — encode the tag and the length 🔖
  • size_t derEnc (octet der[], u32 tag, const void *val, size_t len) — encoding, periodt ✨
  • bool_t derIsValid (const octet der[], size_t count) — is this code actually valid? 🤔
  • bool_t derIsValid2 (const octet der[], size_t count, u32 tag) — is this code valid and does it have the tag you expected? 🔍
  • bool_t derIsValid3 (const octet der[], size_t count) — is this code valid, taking nesting into account? 🪆
  • bool_t derStartsWith (const octet der[], size_t count, u32 tag) — does it start with the tag? 👀
  • size_t derTLDec (u32 *tag, size_t *len, const octet der[], size_t count) — decode the tag and the length 🔖
  • size_t derDec (u32 *tag, const octet **val, size_t *len, const octet der[], size_t count) — decoding ✨
  • size_t derDec2 (const octet **val, size_t *len, const octet der[], size_t count, u32 tag) — decoding, with a tag check 🔍
  • size_t derDec3 (const octet **val, const octet der[], size_t count, u32 tag, size_t len) — decoding, with a tag check and a length check 👑
  • size_t derDec4 (const octet der[], size_t count, u32 tag, const void *val, size_t len) — check a code ✅
  • size_t derTSIZEEnc (octet der[], u32 tag, size_t val) — TSIZE encoding 🍓
  • size_t derTSIZEDec (size_t *val, const octet der[], size_t count, u32 tag) — TSIZE decoding
  • size_t derTSIZEDec2 (const octet der[], size_t count, u32 tag, size_t val) — check a TSIZE code ✅
  • size_t derTUINTEnc (octet der[], u32 tag, const octet *val, size_t len) — TUINT encoding ✨
  • size_t derTUINTDec (octet *val, size_t *len, const octet der[], size_t count, u32 tag) — TUINT decoding
  • size_t derTUINTDec2 (octet *val, const octet der[], size_t count, u32 tag, size_t len) — TUINT decoding, with a length check 👀
  • size_t derTBITEnc (octet der[], u32 tag, const octet *val, size_t len) — TBIT encoding 🌈
  • size_t derTBITDec (octet *val, size_t *len, const octet der[], size_t count, u32 tag) — TBIT decoding
  • size_t derTBITDec2 (octet *val, const octet der[], size_t count, u32 tag, size_t len) — TBIT decoding, with a length check 👀
  • size_t derOIDEnc (octet der[], const char *oid) — OID encoding 🌳
  • size_t derOIDDec (char *oid, size_t *len, const octet der[], size_t count) — OID decoding
  • size_t derOIDDec2 (const octet der[], size_t count, const char *oid) — check an OID code ✅
  • size_t derTOCTDec (octet *val, size_t *len, const octet der[], size_t count, u32 tag) — TOCT decoding
  • size_t derTOCTDec2 (octet *val, const octet der[], size_t count, u32 tag, size_t len) — TOCT decoding, with a length check 👀
  • size_t derTPSTREnc (octet der[], u32 tag, const char *val) — TPSTR encoding 💌
  • size_t derTPSTRDec (char *val, size_t *len, const octet der[], size_t count, u32 tag) — TPSTR decoding
  • size_t derTSEQEncStart (der_anchor_t *anchor, octet der[], size_t pos, u32 tag) — start encoding a TSEQ 🎬
  • size_t derTSEQEncStop (octet der[], size_t pos, const der_anchor_t *anchor) — finish encoding a TSEQ 🏁
  • size_t derTSEQDecStart (der_anchor_t *anchor, const octet der[], size_t count, u32 tag) — start decoding a TSEQ 🎬
  • size_t derTSEQDecStop (const octet der[], const der_anchor_t *anchor) — finish decoding a TSEQ 🏁

🌈 Подробное описание 🌈

okay so this is the part where the page really starts cooking 🍳 — hold that thought, bestie, there's more coming 💖

✨ Правила кодирования ✨

okay so bestie, ASN.1 encoding rules are a whole thing and we're supporting them 💅 According to these rules, data structures are represented in TLV format: first come the tag octets (T), then the length octets (L), and after that L octets of value (V). No cap.

The tag is defined by at least one octet, where the lower 5 bits represent the number, the 6th bit is the primitive/constructed flag (if the bit is clear/set, then V does not contain / contains nested TLV structures), and the two most significant bits determine the tag class:

  • 00 => UNIVERSAL;
  • 01 => APPLICATION;
  • 10 => CONTEXT-SPECIFIC;
  • 11 => PRIVATE.

If not all 5 lower bits of the first tag octet are equal to 1, then the first octet is the only one (short tag). Short tags can have numbers from 0 to 30.

If all 5 lower bits of the first tag octet are equal to 1 (long tag), then the tag number is represented as \sum {i = 0}^{r - 1}t_i 128^i, 0 <= t_i < 128, t_{r - 1} != 0, and is encoded by octets (t_{r - 1} | 128), ..., (t_1 | 128), t_0, following immediately after the first tag octet.

Long tags must be used only for numbers >= 31. In particular, if r == 1, then t_0 >= 31.

Implementation limitation: the tag is defined by a u32 word, which is a ready-made code. The tag-as-number, the tag class, and the primitive flag are encoded.

Examples:

  • tag = 0x30 = 00110000 => class = UNIVERSAL, is_primitive = FALSE, tag_num = 8;
  • tag = 0x7F21 = 01111111 00100001 => class = APPLICATION, is_primitive = FALSE, tag_num = 33;
  • tag = 0x5F29 = 01011111 00101001 => class = APPLICATION, is_primitive = TRUE, tag_num = 41.
  • tag = 0x42 = 01000010 => class = APPLICATION, is_primitive = TRUE, tag_num = 2.
Note. The configuration (class = UNIVERSAL, is_primitive = TRUE, tag_num = 0), which corresponds to the zero code word, is allowed.

🌸 Длина (L) 🌸

If L < 128, the length can be encoded in one octet containing L (short definite form). If L >= 128, the length is represented as L = \sum {i = 0}^{r - 1}l_i 256^i, 0 <= l_i < 256, and is encoded with r + 1 octets (r | 128), l_{r - 1},..., l_0 (long definite form). A length unknown in advance is encoded with octet 128 (indefinite form). The value 255 of the first length octet is reserved and must not be used.

When encoding primitive types (see the 6th bit of the tag), the definite form of length must be used. There are no other restrictions in the basic ASN.1 encoding rules, which are called BER (Basic Encoding Rules). For example, choosing the long form for L < 128 is allowed; using zero leading octets in the long form is allowed (l_{r - 1} may equal 0).

The DER (Distinguished Encoding Rules) implemented in this module remove ambiguities. According to DER, the length must always be encoded in the definite form and always with the minimum number of octets. The latter means that for L < 128 the short form must be used, and for L >= 128 the long form with l_{r - 1} != 0.

Implementation limitation: the length fits in size_t.

The DER code being decoded is written as [<=count]der. It is assumed that the code is written in the prefix of the buffer [count]der. The exact length of the DER code (the sum of the lengths of fields T, L, and V, where the length of V is given in L) is determined during decoding.

Note. Passing null input pointers to functions is allowed.
Precondition. The buffer corresponding to a non-null pointer is valid. Input buffers do not overlap unless otherwise stated.

✨ DER-кодирование ✨

🦋 Базовые типы 🦋

Encoding of the following ASN.1 types is implemented:

  • INTEGER (0x02, SIZE, UINT);
  • BIT STRING (0x03, BIT);
  • OCTET STRING (0x04, OCT);
  • NULL (0x05, NULL);
  • OBJECT IDENTIFIER (0x06, OID);
  • PrintableString (0x13, PSTR);
  • SEQUENCE (0x30, SEQ).

In parentheses, the standard tag code of the type and the short name are given. The short name is part of the names of functions and macros for working with the type.

For some types, support for non-standard tags is implemented. In the corresponding functions and macros, the prefix T is added to the short name: TSIZE, TBIT, etc.

The INTEGER type describes integers. When encoding a number, the V field has the form o1 o2 ... on, where o1 is the most significant octet of the number, and on is the least significant. Setting the most significant bit in o1 is a sign of a negative number. The minimum number of octets must be used for an unambiguous representation of the number.

Examples:

  • der(0) = 02 01 00
  • der(127) = 02 01 7F
  • der(128) = 02 02 00 80
  • der(256) = 02 02 01 00
  • der(-128) = 02 01 80
  • der(-129) = 02 02 FF 7F

Implementation features:

  • negative integers are not supported;
  • the numbers being encoded are either values of type size_t (SIZE) or octet strings (UINT);
  • in the latter case (UINT), little-endian rules apply.

A bit string (BIT STRING) is represented in memory as an octet string. The bits of the string are numbered from zero. The zero bit is the most significant bit of the first octet of the representation, the seventh bit is the least significant bit of the first octet, the eighth bit is the most significant bit of the second octet, and so on. If the length of the string is not a multiple of 8, it is first padded with zeros. They will be located in the least significant bits of the last octet of the representation. The number of appended zero bits (from 0 to 7) is recorded in an additional octet that precedes the representation octets.

An object identifier (OBJECT IDENTIFIER) is specified by a string according to the rules of the oid.h module.

When encoding a container (SEQUENCE structure), the length of the nested data becomes finally known only at the end of encoding. To refine the length, at the beginning of encoding a reference to the encoded prefix of the structure is saved. This reference is called an anchor, is described by the type der_anchor_t, and is used when finishing encoding.

The anchor is also used when decoding a container: it is saved at the beginning and taken into account at the end to check the code.

Note. The value determined when decoding SIZE, UINT, BIT, OCT, and OID is returned via an externally specified address, not as a pointer to a section of the code being decoded (compare with the behavior of the basic functions derDecXXX()).

✨ Функции ✨

size_t derDec (u32 * tag, const octet ** val, size_t * len, const octet der[], size_t count)

The tag tag and the value [len?]val of the DER code [<=count]der are determined. Here val points to a memory buffer inside the der buffer.

Returns. The exact length of the DER code or SIZE_MAX in case of a format error.

Note. Any of the pointers tag, val, and len may be null.

Arguments:

  • tag — tag
  • val — pointer to value
  • len — length of value
  • der — DER code
  • count — length of der in octets

size_t derDec2 (const octet ** val, size_t * len, const octet der[], size_t count, u32 tag)

It is checked that the tag of the DER code [<=count]der equals tag and, if so, the encoded value [len?]val is determined. Here val points to a memory buffer inside the der buffer.

Note. Any of the pointers val, len may be null, and then no data is returned via the pointer.

Предусловие

  • Буферы, на которые ссылаются ненулевые указатели val и len, не пересекаются между собой и с буфером der.

Возвращает

  • Точная длина DER-кода или SIZE_MAX в случае ошибки.

Аргументы

  • val — значение
  • len — длина значения
  • der — DER-код
  • count — длина der в октетах
  • tag — тег

size_t derDec3

size_t derDec3 (const octet ** val, const octet der[], size_t count, u32 tag, size_t len)

okay bestie, слушай сюда! Эта штука проверяет, что тег и длина значения у DER-кода [<=count]der равны tag и len соответственно. И если всё сходится — вытаскиваем закодированное значение [len]val. При этом val указывает на буфер памяти внутри буфера der. 💅

Прим.

  • Указатель val может быть нулевым, и тогда возврат данных по указателю не производится. no cap

Предусловие

  • Если val != 0, то соответствующий буфер не пересекается с буфером der.

Возвращает

  • Точная длина DER-кода или SIZE_MAX в случае ошибки.

Аргументы

  • val — значение
  • der — DER-код
  • count — длина der в октетах
  • tag — тег
  • len — длина значения

size_t derDec4

size_t derDec4 (const octet der[], size_t count, u32 tag, const void * val, size_t len)

Проверяем, что тег и значение DER-кода [<=count]der равны tag и [len]val. просто, но эффективно ✨

Прим.

  • Величина count — это оценка сверху актуальной длины DER-кода. не путай, это важно

Возвращает

  • Точная длина DER-кода или SIZE_MAX в случае ошибки.

Аргументы

  • der — DER-код
  • count — длина der в октетах
  • tag — тег
  • val — значение
  • len — длина значения

size_t derEnc

size_t derEnc (octet der[], u32 tag, const void * val, size_t len)

Определяем число октетов в DER-коде значения [len]val с тегом tag. Если der != 0, то DER-код размещается по этому адресу. магия кодирования 🦋

Предусловие

  • Если der != 0, то val != 0 и по адресу der зарезервировано derEnc(0, tag, val, len) октетов.

Возвращает

  • Число октетов в DER-коде или SIZE_MAX в случае ошибки.

Прим.

  • Буферы der и val могут пересекаться. они могут пересекаться, да-да
  • Ошибкой является неверный формат tag.
  • Разрешаются вызовы derEnc(0, tag, val, len), derEnc(0, tag, 0, len).

Аргументы

  • der — DER-код
  • tag — тег
  • val — значение
  • len — длина val в октетах

bool_t derIsValid

bool_t derIsValid (const octet der[], size_t count)

Проверяем корректность DER-кода [count]der. Вот какие условия проверяются:

  • тег T и длина L закодированы по правилам ACH.1;
  • тег укладывается в u32 (ограничение реализации);
  • длина укладывается в size_t (ограничение реализации);
  • count действительно является длиной кода.

Возвращает

  • Признак корректности.

Прим.

  • Содержимое V не проверяется. ой, это важно

Аргументы

  • der — DER-код
  • count — длина der в октетах

bool_t derIsValid2

bool_t derIsValid2 (const octet der[], size_t count, u32 tag)

Проверяем корректность DER-кода [count]der с ожидаемым тегом tag. Условия:

  • derIsValid(der, count) == TRUE;
  • der имеет тег tag.

Ожидается [FALSE]

  • Тег tag корректен.

Возвращает

  • Признак корректности.

Прим.

  • Содержимое V не проверяется.

Аргументы

  • der — DER-код
  • count — длина der в октетах
  • tag — тег

bool_t derIsValid3

bool_t derIsValid3 (const octet der[], size_t count)

Проверяем корректность DER-кода [count]der. Вот полный чек-лист:

  • derIsValid(der, count) == TRUE;
  • если der примитивен, т.е. не содержит вложенных der-полей, и имеет распознаваемый реализацией тег (см. далее), то он корректно декодируется;
  • если der конструктивен, т.е. содержит вложенные der-поля, то derIsValid(d, count) == TRUE для каждого такого поля d;
  • глубина вложенности не превышает 32.

Возвращает

  • Признак корректности.

Аргументы

  • der — DER-код
  • count — длина der в октетах

size_t derOIDDec

size_t derOIDDec (char * oid, size_t * len, const octet der[], size_t count)

Определяем идентификатор объекта [len? + 1]oid, представленный DER-кодом [<=count]der. OID, детка 💅

Возвращает

  • Точная длина DER-кода или SIZE_MAX в случае ошибки.

Прим.

  • Длина len? не учитывает завершающий нулевой символ. не забудь про нулевой символ

Аргументы

  • oid — идентификатор
  • len — длина идентификатора
  • der — DER-код
  • count — длина der в октетах

size_t derOIDDec2

size_t derOIDDec2 (const octet der[], size_t count, const char * oid)

Проверяем, что DER-код [<=count]der построен по идентификатору oid. Идентификатор задаётся строкой, составленной по правилам модуля oid.h. читай документацию к oid.h, bestie 📚

Возвращает

  • Точная длина DER-кода или SIZE_MAX в случае ошибки.

Аргументы

  • der — DER-код
  • count — длина der в октетах
  • oid — идентификатор

size_t derOIDEnc

size_t derOIDEnc (octet der[], const char * oid)

Определяем число октетов в DER-коде идентификатора объекта oid. Если der != 0, то DER-код размещается по этому адресу. кодируем OID 🦋

Предусловие

  • Если der != 0, то по адресу der зарезервировано derOIDEnc(0, oid) октетов.

Возвращает

  • Число октетов в DER-коде или SIZE_MAX в случае ошибки.

Аргументы

  • der — DER-код
  • oid — идентификатор объекта

bool_t derStartsWith

bool_t derStartsWith (const octet der[], size_t count, u32 tag)

Проверяем, что DER-код [count]der начинается с тега tag. startswith, но для DER ✨

Ожидается [FALSE]

  • Тег tag корректен.

Возвращает

  • Признак корректности.

Аргументы

  • der — DER-код
  • count — длина der в октетах
  • tag — тег

size_t derTBITDec

size_t derTBITDec (octet * val, size_t * len, const octet der[], size_t count, u32 tag)

Проверяем, что тег DER-кода [<=count]der равен tag, и если это так — определяем закодированную строку битов [(len? + 7)/8]val. битовые строки, моя любовь 💖

Прим.

  • Любой из указателей val и len может быть нулевым. гибкость!

Предусловие

  • Буферы, на которые ссылаются ненулевые указатели val и len, не пересекаются между собой, но могут пересекаться с буфером der.

Возвращает

  • Точная длина DER-кода или SIZE_MAX в случае ошибки.

Аргументы

  • val — строка битов
  • len — длина val в битах
  • der — DER-код
  • count — длина der в октетах
  • tag — тег

size_t derTBITDec2

size_t derTBITDec2 (octet * val, const octet der[], size_t count, u32 tag, size_t len)

Проверяем, что DER-код [<=count]der имеет тег tag и представляет строку битов длины len, и если это так — определяем закодированное значение [(len + 7)/8]val. точность — наше всё 💅

Прим.

  • Указатель val может быть нулевым.
  • Если val != 0, то соответствующий буфер может пересекаться с der. пересечения разрешены

Возвращает

  • Точная длина DER-кода или SIZE_MAX в случае ошибки.

Аргументы

  • val — строка битов
  • der — DER-код
  • count — длина der в октетах
  • tag — тег
  • len — длина val в битах

size_t derTBITEnc

size_t derTBITEnc (octet der[], u32 tag, const octet * val, size_t len)

Определяем число октетов в DER-коде с тегом tag строки битов [(len + 7)/8]val. Если der != 0, то DER-код размещается по этому адресу. кодируем биты 🦋

Предусловие

  • Если der != 0, то по адресу der зарезервировано derTBITEnc(0, tag, val, len) октетов.

Возвращает

  • Число октетов в DER-коде или SIZE_MAX в случае ошибки.

Прим.

  • Поддерживается логика derEnc(), в частности, буферы der и val могут пересекаться. как в derEnc, только биты

Аргументы

  • der — DER-код
  • tag — тег
  • val — строка битов
  • len — длина val в битах

size_t derTLDec

size_t derTLDec (u32 * tag, size_t * len, const octet der[], size_t count)

Определяем тег tag и длину значения len DER-кода с TL-префиксом [<=count]der. TL-префикс, детка ✨

Возвращает

  • Точная длина TL-префикса или SIZE_MAX в случае ошибки формата.

Прим.

  • Любой из указателей tag и len может быть нулевым. оба могут быть нулевыми

Аргументы

  • tag — тег
  • len — длина значения
  • der — DER-код
  • count — длина der в октетах

size_t derTLEnc (octet der[], u32 tag, size_t len)

Окей бэсти, погнали. Эта крошка считает, сколько октетов живёт в TL-префиксе DER-кода с тегом tag и значением длины val. А если der != 0 — то префикс буквально переезжает по этому адресу, как ты в новую квартиру. 🏠✨

Предусловие

Если der != 0, то по адресу der зарезервировано derEnc(0, tag, len) октетов. Не зарезервировала — не жалуйся потом, это на тебе. 💅

Возвращает

Число октетов в TL-префиксе или SIZE_MAX в случае ошибки.

Прим.

Ошибкой является неверный формат tag. Вот и всё, никаких сюрпризов.

Аргументы

  • der — DER-код
  • tag — тег
  • len — длина значения в октетах

size_t derTOCTDec (octet * val, size_t * len, const octet der[], size_t count, u32 tag)

Проверяет, что тег DER-кода [<=count]der реально равняется tag — вайб-чек, грубо говоря — и если да, то достаёт закодированную строку октетов [len?]val. 🔍

Прим.

Любой из указателей val и len может быть нулевым. Да-да, прям любой.

Предусловие

Буферы, на которые ссылаются ненулевые указатели val и len, не пересекаются между собой, но могут пересекаться с буфером der. Дружба с der разрешена, между собой — нет. 🚫

Возвращает

Точная длина DER-кода или SIZE_MAX в случае ошибки.

Аргументы

  • val — строка октетов
  • len — длина val
  • der — DER-код
  • count — длина der в октетах
  • tag — тег

size_t derTOCTDec2 (octet * val, const octet der[], size_t count, u32 tag, size_t len)

Проверяет, что DER-код [<=count]der имеет тег tag и представляет строку октетов длины len — двойная проверка, двойная уверенность, ате. 💅 И если всё сходится, определяется закодированное значение [len]val.

Прим.

Указатель val может быть нулевым.

Если val != 0, то соответствующий буфер может пересекаться с der. Всё чилл, пересекаться можно. 🌸

Возвращает

Точная длина DER-кода или SIZE_MAX в случае ошибки.

Аргументы

  • val — строка октетов
  • der — DER-код
  • count — длина der в октетах
  • tag — тег
  • len — длина val

size_t derTPSTRDec (char * val, size_t * len, const octet der[], size_t count, u32 tag)

Проверяет, что тег DER-кода [<=count]der равняется tag, и если это так — определяется печатаемая строка [len? + 1]val. ✨

Прим.

Любой из указателей val и len может быть нулевым.

Предусловие

Буферы, на которые ссылаются ненулевые указатели val и len, не пересекаются между собой, но могут пересекаться с буфером der.

Возвращает

Точная длина DER-кода или SIZE_MAX в случае ошибки.

Прим.

Длина len? не учитывает завершающий нулевой символ. Важный момент, не забудь про него! 🫶

Аргументы

  • val — строка
  • len — длина val
  • der — DER-код
  • count — длина der в октетах
  • tag — тег

size_t derTPSTREnc (octet der[], u32 tag, const char * val)

Считает, сколько октетов в DER-коде с тегом tag для печатаемой строки str. А если der != 0 — DER-код размещается по этому адресу. 🎀

Предусловие

Если der != 0, то по адресу der зарезервировано derTPSTREnc(0, tag, str) октетов.

Ожидается [SIZE_MAX]

  • strIsPrintable(val)

Возвращает

Число октетов в DER-коде или SIZE_MAX в случае ошибки.

Прим.

Поддерживается логика derEnc(), в частности, буферы der и val могут пересекаться. 🔥

Аргументы

  • der — DER-код
  • tag — тег
  • val — строка

size_t derTSEQDecStart (der_anchor_t * anchor, const octet der[], size_t count, u32 tag)

Определяет число октетов в префиксе DER-кода [<=count]der структуры TSEQ с тегом tag. И одновременно в якоре anchor сохраняются данные, которые потом пригодятся, чтобы проверить префикс при завершении декодирования структуры. ⚓️ Это как сохранить черновик, чтобы потом не переписывать всё заново.

Ожидается [SIZE_MAX]

  • В tag установлен бит конструктивности.

Возвращает

Число октетов в префиксе DER-коде или SIZE_MAX в случае ошибки.

Аргументы

  • anchor — якорь
  • der — DER-код
  • count — длина der в октетах
  • tag — тег

size_t derTSEQDecStop (const octet der[], const der_anchor_t * anchor)

Завершает декодирование структуры TSEQ: по якорю anchor, сохранённому в начале кодирования, и адресу der, который указывает на окончание DER-кода, проверяется корректность кода. Финальный вайб-чек, и всё готово. 🦋

Предусловие

derTSEQDecStop() < derTSEQDecStart().

Возвращает

0 в случае успешного завершения или SIZE_MAX в случае ошибки.

Аргументы

  • der — DER-код
  • anchor — якорь

size_t derTSEQEncStart (der_anchor_t * anchor, octet der[], size_t pos, u32 tag)

Определяет число октетов в префиксе DER-кода структуры TSEQ с тегом tag. Если der != 0, то префикс размещается по этому адресу. И одновременно в якоре anchor сохраняются данные, нужные чтобы уточнить префикс при завершении кодирования структуры. Чтобы корректно уточнить префикс при нулевом der, в функцию передаётся параметр pos — это текущая позиция в коде в абстрактной (со свободной точкой отсчёта) системе координат. 📍

Предусловие

Если der != 0, то по адресу der зарезервировано derTSEQEncStart(anchor, 0, pos, tag) октетов.

Ожидается [SIZE_MAX]

  • В tag установлен бит конструктивности.

Возвращает

Число октетов в префиксе DER-коде или SIZE_MAX в случае ошибки.

Аргументы

  • anchor — якорь
  • der — DER-код
  • pos — позиция
  • tag — тег

size_t derTSEQEncStop (octet der[], size_t pos, const der_anchor_t * anchor)

По якорю anchor и текущей позиции pos в коде определяется дополнительное число октетов, чтобы завершить кодирование структуры TSEQ. Если der != 0, то кодирование завершается. Закрываем гештальт, periodt. 💅

Предусловие

Если der != 0, то по адресу der зарезервировано derTSEQEncStop(0, pos, anchor) октетов.

Ожидается

  • derTSEQEncStop() < derTSEQEncStart().

Предусловие

Если в derTSEQEncStart() передан ненулевой адрес der, то в derTSEQEncStop() также передан ненулевой адрес и разность адресов совпадает с разностью позиций. Симметрия, красота, эстетика. ✨

Возвращает

Число октетов завершающих кодирование или SIZE_MAX в случае ошибки.

Аргументы

  • der — DER-код
  • pos — позиция
  • anchor — якорь

size_t derTSIZEDec (size_t * val, const octet der[], size_t count, u32 tag)

Проверяет, что тег DER-кода [<=count]der равняется tag, и если это так — определяется закодированное неотрицательное целое val. 🔢

Возвращает

Точная длина DER-кода или SIZE_MAX в случае ошибки.

Аргументы

  • val — значение
  • der — DER-код
  • count — длина der в октетах
  • tag — тег

size_t derTSIZEDec2 (const octet der[], size_t count, u32 tag, size_t val)

Проверяет, что DER-код [<=count]der имеет тег tag и представляет неотрицательное целое val. Совпадение должно быть идеальным, как твой мейкап на фото. 💄

Возвращает

Точная длина DER-кода или SIZE_MAX в случае ошибки.

Аргументы

  • der — DER-код
  • count — длина der в октетах
  • tag — тег
  • val — значение

size_t derTSIZEEnc (octet der[], u32 tag, size_t val)

Определяет число октетов в DER-коде с тегом tag для неотрицательного целого val. Если der != 0, то DER-код размещается по этому адресу. 🧚

Предусловие

Если der != 0, то по адресу der зарезервировано derTSIZEEnc(0, tag, val) октетов.

Возвращает

Число октетов в DER-коде или SIZE_MAX в случае ошибки.

Аргументы

  • der — DER-код
  • tag — тег
  • val — значение

size_t derTUINTDec (octet * val, size_t * len, const octet der[], size_t count, u32 tag)

Проверяет, что тег DER-кода [<=count]der равняется tag, и если это так — определяется закодированное неотрицательное целое число [len?]val. 🌈

Прим.

Любой из указателей val и len может быть нулевым.

Предусловие

Буферы, на которые ссылаются ненулевые указатели val и len, не пересекаются между собой, но могут пересекаться с буфером der.

Возвращает

Точная длина DER-кода или SIZE_MAX в случае ошибки.

Аргументы

  • val — число 🔢
  • len — длина val в октетах
  • der — DER-код
  • count — длина der в октетах
  • tag — тег

size_t derTUINTDec2 (octet * val, const octet der[], size_t count, u32 tag, size_t len)

okay so this one does a lil vibe check on the DER-code: it looks at [<=count]der and is like "bestie, do you have tag tag and are you a non-negative number made of exactly len octets?" and if the answer is yes (slay), it hands you back the decoded value as [len]val ✨

Прим.

  • The pointer val is allowed to be null. yes really, zero thoughts head empty, it's fine 🙈
  • If val != 0, then the buffer it points at can totally overlap with der. no cap, they can share space.

Возвращает

The exact length of the DER-code, or SIZE_MAX if something went wrong 💀

Прим.

  • The number val gets written using exactly len octets, as long as you skip the insignificant zero octets in the record. Specifically: val[len - 1] == 0 <=> len == 1. that's the whole rule, periodt.

Аргументы

  • val — строка битов
  • der — DER-код
  • count — длина der в октетах
  • tag — тег
  • len — длина val в битах

size_t derTUINTEnc (octet der[], u32 tag, const octet * val, size_t len)

this icon works out how many octets the DER-code is gonna have — the one with tag tag for the non-negative integer [len]val. And if der != 0, it actually puts the DER-code right at that address. two jobs, one function, main character energy 👑

Предусловие

  • len > 0. do not come in here with a zero, it's giving nothing 🌸
  • If der != 0, then the space reserved at address der is derTUINTEnc(0, tag, val, len) octets. like, do the math first, bestie.

Возвращает

The number of octets in the DER-code, or SIZE_MAX if it went sideways 😭

Прим.

  • It supports the logic of derEnc() — in particular, the buffers der and val are allowed to overlap. they're basically holding hands 🫶

Аргументы

  • der — DER-код
  • tag — тег
  • val — число
  • len — длина val в октетах

Автор ✨

Автоматически создано Doxygen для Библиотека Bee2 из исходного текста.

yeah the docs basically generated themselves, we just gave them a glow-up 💅

and that's a wrap on der.h(3), bestie!! this page came from Библиотека Bee2, dated Вс 25 Янв 2026 00:00:00 — go forth and DER-encode responsibly 🦋🎀

📦 where this page comes from