der.h - Man Page

Отличительные правила кодирования

Synopsis

#include 'bee2/defs.h'

Классы

struct der_anchor
Якорь для кодирования контейнеров

Макросы

#define derEncOCT(der,  val,  len)   derEnc(der, 0x04, val, len)
Кодирование OCTET STRING.
#define derDecOCT3(der,  count,  val,  len)   derDec4(der, count, 0x04, val, len)
Проверка кода OCTET STRING.
#define derEncNULL(der)   derEnc(der, 0x05, 0, 0)
Кодирование NULL.
#define derDecNULL(der,  count)   derDec4(der, count, 0x05, 0, 0)
Проверка кода NULL.

Функции

size_t derEnc (octet der[], u32 tag, const void *val, size_t len)
Кодирование
bool_t derIsValid (const octet der[], size_t count)
Корректный код?
bool_t derIsValid2 (const octet der[], size_t count, u32 tag)
Корректный код с ожидаемым тегом?
size_t derDec (u32 *tag, const octet **val, size_t *len, const octet der[], size_t count)
Декодирование
size_t derDec2 (const octet **val, size_t *len, const octet der[], size_t count, u32 tag)
Декодирование с проверкой тега
size_t derDec3 (const octet **val, const octet der[], size_t count, u32 tag, size_t len)
Декодирование с проверкой тега и длины
size_t derDec4 (const octet der[], size_t count, u32 tag, const void *val, size_t len)
Проверка кода
size_t derEncSIZE (octet der[], size_t val)
Кодирование SIZE.
size_t derDecSIZE (size_t *val, const octet der[], size_t count)
Декодирование SIZE.
size_t derDecSIZE2 (const octet der[], size_t count, size_t val)
Проверка кода SIZE.
size_t derDecOCT (octet *val, size_t *len, const octet der[], size_t count)
Декодирование OCTET STRING.
size_t derDecOCT2 (octet *val, const octet der[], size_t count, size_t len)
Декодирование OCTET STRING с проверкой длины
size_t derEncOID (octet der[], const char *oid)
Кодирование OBJECT IDENTIFIER.
size_t derDecOID (char *oid, size_t *len, const octet der[], size_t count)
Декодирование OBJECT IDENTIFIER.
size_t derDecOID2 (const octet der[], size_t count, const char *oid)
Проверка кода OBJECT IDENTIFIER.
size_t derEncSEQStart (der_anchor *anchor, octet der[], size_t pos)
Начать кодирование SEQUENCE.
size_t derEncSEQStop (octet der[], size_t pos, const der_anchor *anchor)
Завершить кодирование SEQUENCE.
size_t derDecSEQStart (der_anchor *anchor, const octet der[], size_t count)
Начать декодирование SEQUENCE.
size_t derDecSEQStop (const octet der[], const der_anchor *anchor)
Завершить декодирование SEQUENCE.

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

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

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

Поддержано кодирование по правилам АСН.1. Согласно этим правилам, структуры данных представляются в формате TLV: сначала идет октеты тега (T), затем октеты длины (L), а после этого L октетов значения (V).

Тег задается, как минимум, одним октетом, в котором младшие 5 битов представляют номер, 6-й бит является признаком примитивности / конструктивности (если бит установлен, то V не содержит / содержит вложенные структуры TLV), а старшие два бита определяют класс тега.

Если не все 5 младших битов первого октета тега равняются 1, то первый октет является единственным (короткий тег). Короткие теги могут иметь номера от 0 до 30.

Если все 5 младших битов типа первого октета тега равняются 1 (длинный тег), то номер тега представляется в виде \sum {i = 0}^{r - 1}t_i 128^i, 0 <= t_i < 128, t_{r - 1} != 0, и кодируется октетами (t_{r - 1} | 128), ..., (t_1 | 128), t_0, следующими сразу за первым октетом тега.

Длинные теги должен применяться только для номеров >= 31. В частности, если r == 1, то t_0 >= 31.

Ограничение реализации: тег задается словом u32. Номер тега задается младшими 5 битами слова, если не все эти биты единичные (короткий тег), либо старшими 24 битами, в противном случае (длинный тег). Если в коротком теге некоторый из старших 24 битов ненулевой, то это считается ошибкой формата. Если в длинном теге старшие 24 бита соответствуют числу < 31, то это также считается ошибкой формата.

Если L < 128, то длина может кодироваться одним октетом, содержащим L (короткая явная форма). Если L >= 128, то длина представляется в виде L = \sum {i = 0}^{r - 1}l_i 256^i, 0 <= l_i < 256, и кодируется r + 1 октетами (r | 128), l_{r - 1},..., l_0 (длинная явная форма). Заранее неизвестная длина кодируется октетом 128 (неявная форма). Значение 255 первого октета длины зарезервировано и не должно использоваться.

При кодировании примитивных типов (см. 6-й бит тега) должна использоваться явная форма длины. Других ограничений в базовых правилах кодирования АСН.1, которые называются BER (Basic Encoding Rules), нет. Например, допускается выбор длинной формы для L < 128, допускается использование в длинной форме нулевых старших октетов (l_{r - 1} может равняться 0).

Реализованные в настоящем модуле правила DER (Distinguished Encoding Rules) снимают неоднозначности. По правилам DER длина должна кодироваться всегда в явной форме и всегда с помощью минимального числа октетов. Последнее означает, что при L < 128 должна применяться короткая форма, а при L >= 128 -- длинная форма с l_{r - 1} != 0.

Ограничение реализации: длина укладывается в size_t.

Декодируемый DER-код записывается в виде [<=count]der. Подразумевается, что код записан в префиксе буфера [count]der. Точная длина DER-кода (сумма длин полей T, L и V, причем длина V указана в L) определяется в процессе декодирования.

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

Базовые типы

Реализовано кодирование следующих типов АСН.1:

В скобках указывается тег типа и короткое имя. Короткое имя входит в название функций и макросов работы с типом.

Для типа INTEGER реализована работа только с неотрицательными значениями, которые укладываются в size_t.

Идентификатор объекта задается строкой по правилам модуля oid.h.

При кодировании контейнера (структуры SEQUENCE) длина вложенных данных становится окончательно известна только в конце кодирования. Для уточнения длины в начале кодирования сохраняется ссылка на закодированный префикс структуры. Эта ссылка называется якорем, описывается типом der_anchor и используется при завершении кодирования.

Якорь используется также при декодировании контейнера: сохраняется в начале, учитывается в конце для проверки кода.

Прим.

Значение, которое определяется при декодировании SIZE, OCT и OID, возвращается по указанному извне адресу, а не в виде указателя на участок декодируемого кода (ср. с поведением базовых функций derDecXXX()).

Макросы

#define derDecNULL(der, count)   derDec4(der, count, 0x05, 0, 0)

#define derEncNULL(der)   derEnc(der, 0x05, 0, 0)

Функции

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

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

Прим.

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

Предусловие

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

Возвращает

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

Аргументы

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

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

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

Прим.

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

Предусловие

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

Возвращает

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

Аргументы

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

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

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

Прим.

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

Предусловие

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

Возвращает

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

Аргументы

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

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 derDecOCT (octet * val, size_t * len, const octet der[], size_t count)

Определяется строка октетов [len?]buf, представленная DER-кодом [<=count]der.

Возвращает

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

Аргументы

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

size_t derDecOCT2 (octet * val, const octet der[], size_t count, size_t len)

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

Прим.

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

Предусловие

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

Возвращает

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

Аргументы

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

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

Определяется идентификатор объекта [len?]oid, представленный DER-кодом [<=count]der. Длина len учитывает завершающий нулевой символ строки oid.

Возвращает

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

Аргументы

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

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

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

Возвращает

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

Аргументы

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

size_t derDecSEQStart (der_anchor * anchor, const octet der[], size_t count)

Определяется число октетов в префиксе DER-кода [<=count]der структуры SEQUENCE. Одновременно в якоре anchor сохраняются данные, необходимые для проверки префикса при завершении декодирования структуры.

Возвращает

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

Аргументы

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

size_t derDecSEQStop (const octet der[], const der_anchor * anchor)

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

Предусловие

derDecSEQStop < derDecSEQStart.

Возвращает

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

Аргументы

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

size_t derDecSIZE (size_t * val, const octet der[], size_t count)

Определяется неотрицательное целое (INTEGER) val, представленное DER-кодом [<=count]der.

Прим.

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

Возвращает

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

Аргументы

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

size_t derDecSIZE2 (const octet der[], size_t count, size_t val)

Проверяется, что DER-код [<=count]der представляет неотрицательное целое (INTEGER) типа size_t.

Возвращает

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

Аргументы

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

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 в случае ошибки.

Прим.

Ошибкой является неверный формат tag.

Разрешаются вызовы derEnc(0, tag, val, len), derEnc(0, tag, 0, len).

Аргументы

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

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

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

Предусловие

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

Возвращает

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

Аргументы

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

size_t derEncSEQStart (der_anchor * anchor, octet der[], size_t pos)

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

Предусловие

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

Возвращает

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

Прим.

Позиция pos -- это

Аргументы

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

size_t derEncSEQStop (octet der[], size_t pos, const der_anchor * anchor)

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

Предусловие

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

Ожидается:\n derEncSEQStop < derEncSEQStart.

Предусловие

Если в derEncSEQStart() передан ненулевой адрес der, то в derEncSEQStop() также передан ненулевой адрес и разность адресов совпадает с разностью позиций.

Возвращает

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

Аргументы

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

size_t derEncSIZE (octet der[], size_t val)

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

Предусловие

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

Возвращает

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

Аргументы

der DER-код
val значение

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 (const octet der[], size_t count, u32 tag)

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

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

Возвращает

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

Прим.

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

Аргументы

der DER-код
count длина der в октетах
tag ожидаемый тег

Автор

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

Info

Пн 13 Фев 2023 Библиотека Bee2