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 (0x02, SIZE);
- OCTET STRING (0x04, OCT);
- NULL (0x05, NULL);
- OBJECT IDENTIFIER (0x06, OID);
- SEQUENCE (0x30, SEQ).
В скобках указывается тег типа и короткое имя. Короткое имя входит в название функций и макросов работы с типом.
Для типа 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 из исходного текста.