Пакеты
Данные в файлах OpenPGP делятся на пакеты. Каждый пакет состоит из соответствующих ему данных, предварённых заголовком (обозначающим тип пакета) и длиной пакета. Вот типы пакетов и их идентификаторы:
ID | Тип пакета |
---|---|
1 | Пакет сеансового ключа, зашифрованного открытым ключом (Public-Key Encrypted Session Key Packet) |
2 | Пакет подписи (Signature Packet) |
3 | Пакет сеансового ключа, зашифрованного симметричным ключом (Symmetric-Key Encrypted Session Key Packet) |
4 | Пакет однопроходовой подписи (One-Pass Signature Packet) |
5 | Пакет закрытого ключа (Secret Key Packet) |
6 | Пакет открытого ключа (Public Key Packet) |
7 | Пакет закрытого подключа (Secret Subkey Packet) |
8 | Пакет сжатых данных (Compressed Data Packet) |
9 | Пакет симметрично зашифрованных данных (Symmetrically Encrypted Data Packet) |
10 | Пакет метки (Marker Packet) |
11 | Пакет исходных данных (Literal Data Packet) |
12 | Пакет сведений о доверии (Trust Packet) |
13 | Пакет имени пользователя / записи сертификата (User ID Packet) |
14 | Пакет открытого подключа (Public Subkey Packet) |
60-64 | Диапазон частных/экспериментальных пакетов |
Заголовок пакета
Заголовок (хидер) пакета сообщает о типе пакета и его длине. Каждый пакет начинается с заголовка.
Заголовок старых пакетов может быть длиной 1, 2, 3 или 5 байт. Первый бит всегда равен 1. Второй бит в старых пакетах — 0. В старом формате следующие четыре бита содержат тип пакета (таким образом, идентификатор типа может быть от 0 до 16), а заключительные два бита сообщают о том, как закодирована длина. Вот возможные значения для этого последнего поля:
Значение | Описание |
---|---|
0 | Длина заголовка равна 2 байтам, а следующий за ним байт содержит длину пакета. Этот тип длины может применяться для пакетов, содержащих менее 256 байт данных. |
1 | Длина заголовка равна 3 байтам, а последующие два байта кодируют длину. Такой тип длины возможен при объёме данных менее 65536 байт. |
2 | Заголовок имеет длину 5 байт, а длину пакета кодируют ещё четыре байта. Возможный объём данных для такого пакета лежит в пределах 4 Гб. |
3 | Длина пакета не может быть восстановлена из заголовка. Заголовок составляет ровно один байт, а длина пакета должна определяться "по контексту". |
Для новых пакетов второй бит равен 1, а оставшиеся 6 бит первого байта заголовка обозначают тип пакета. Длина заголовка может составлять 2, 3 или 5 байт. Какая длина будет выбрана для заголовка, зависит от значения его второго байта:
Значение | Описание |
---|---|
0-192 | Длина данных обозначается непосредственно значением байта. |
192-224 | Длина данных рассчитывается как (byte1-192)∗28+byte2. (Не забывайте, что byte1 — это второй байт хидера.) Такой вариант применим, если размер данных лежит в диапазоне от 192 до 8384 байт. |
224-255 | Это означает, что полная длина данных в текущий момент не известна. Длина первого сегмента данных рассчитывается как 2byte1-224. После этого сегмента с данными следует новый индикатор длины (хидер без первого байта), а далее — оставшаяся часть или части файла (аналогичным образом кодируя длину каждого сегмента). 1 Заключительный сегмент должен иметь любой другой индикатор длины, кроме этого. Такое обозначение длины называется раздельной длиной тела данных (partial body length). |
255 | Такое значение говорит о том, что длина закодирована в следующих четырёх байтах. Объём данных в этом случае может быть в пределах 4 Гб. |
Важной чертой подобного дизайна является возможность определения типа пакетов. Иными словами, PGP не нужно [заранее] знать, что он читает ключ или подпись. Я пытался сбить программу с толку, скармливая ей файлы ключей с расширением .sig, однако выяснилось, что PGP целиком полагается на идентификаторы пакетов. Все прочие признаки игнорируются. Другое полезное свойство такой кодировки в том, что PGP заранее знает длину предстоящих данных (в большинстве случаев). Это позволяет PGP резервировать буферы необходимого объёма. В случаях, когда программам приходится читать данные до конца строки, хакеры зачастую пытаются передать программе огромную строку, так что нужные им данные оказываются скопированы в сегмент памяти за пределами выделенного буфера.
Назад[link1] | Дальше[link2]
1 Таким образом, длина каждого сегмента может быть до 2 Гб, — прим. пер.
[link2] https://www.pgpru.com/biblioteka/statji/analiznadezhnostipgp/formatfajjlovpgp/paketykljuchejj