stadium-proto/Handshake.md

148 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Рукопожатие
На рукопожатие возложена задача выяснить способность _узлов_ устанавливать соединение по описываемому протоколу и согласовать подключение с избранными параметрами каждой стороны. На выбор существует два типа хэндшейка: открытый и зашифрованный. Второй дополнительно требует знать публичный ключ целевого _узла_.
## Запрос рукопожатия
После успешного подключения к целевому _узлу_ через избранный транспорт происходит обмен параметрами обоих сторон. Инициирующий соединение _узел_ отправляет пакет с магический числом, флагом шифрования и сериализованными данными в формат _LBM_. В случае с зашифрованным хэндшейком, сериализованные данные дополнительно зашифровываются с помощью публичного ключа целевого _узла_.
Структура пакета с запросом рукопожатия выглядит следующим образом:
`[magic number: 8B][encryption flag: 1B][LBM-formatted data: >0B]`
### Магическое число
Магическим числом является следующая последовательность байт:
```
HEX: 0x53 0x74 0x61 0x64 0x69 0x75 0x6d 0x50
DEC: 83 116 97 100 105 117 109 80
ASCII: S t a d i u m P
```
Если _узел_ получает пакет, который не содержит магического числа на указанной позиции, то он должен молча закрыть соединение.
### Флаг шифрования
Запрос шифрованного хэндшейка предполагает установку этого флага в значение `0x7a`. Все остальные значения должны интерпретироваться как запрос открытого хэндшейка.
### Данные
Данные в формате _LBM_ содержат следующие ячейки:
- Версия протокола
- _Ключ:_ `0x01`
- _Тип:_ `uint8_t`
- _Обязательна:_ да
- Поддерживаемая запрашивающим _узлом_ версия протокола.
- `0b10000000`: зарезервировано
- `0b01111111`: номер версии
- Алгоритмы хэширования полезной нагрузки
- _Ключ:_ `0x02`
- _Тип:_ `Crypto::Algorithm[]`
- _Обязательна:_ только для шифрованного ХШ
- Описывает запрашиваемые к использованию в этом соединении хэш-функции для формирования хэша полезной нагрузки. <!--TODO: упомянуть в структуре события использование нескольких алгоритмов совместно-->
- Алгоритм подписи
- _Ключ:_ `0x03`
- _Тип:_ `Crypto::Algorithm`
- _Обязательна:_ только для шифрованного ХШ
- Описывает используемый запрашивающим _узлом_ алгоритм подписи.
- Публичный ключ подписи
- _Ключ:_ `0x04`
- _Тип:_ `char[]`
- _Обязательна:_ только для шифрованного ХШ
- Публичный ключ подписи запрашивающего _узла_, который будет использован для проверки достоверности событий в соединении.
- Алгоритмы симметричного шифрования
- _Ключ:_ `0x05`
- _Тип:_ `Crypto::Algorithm[]`
- _Обязательна:_ только для шифрованного ХШ
- Описывает запрашиваемые к использованию в этом соединении симметричные алгоритмы шифрования.
- Приватный ключ
- _Ключ:_ `0x06`
- _Тип:_ `char[]`
- _Обязательна:_ только для шифрованного ХШ
- Используемый в этом соединении приватный ключ, размера соответствующего избранному алгоритму симметричного шифрования.
- Параметры шума
- _Ключ:_ `0x07`
- _Тип:_ `uint8_t`
- _Обязательна:_ нет
- Описывает параметры шума в соединении:
- `0b11100000`: выделено под настройку количества умовых пакетов_
- `0b000`: отсутствие умовых пакетов_
- `0b001`: соотношение умовых пакетов_ к реальным - 1:8
- `0b010`: соотношение - 1:4
- `0b011`: 1:2
- `0b100`: 1:1
- `0b101`: 2:1
- `0b110`: 4:1
- `0b111`: зарезервировано
- `0b00011000`: выделено под настройку размера умовых пакетов_
- `0b00`: случайный размер, в пределах от минимального _пакета_ с нулевой полезной нагрузкой, до размера _пакета_ с полезной нагрузкой размерности, которую должен передать целевой _узел_ при одобрении рукопожатия
- `0b01`: случайный размер, на основе среднего размера передаваемого пакета +- 25% (но всегда меньше максимального)
- `0b10`: случайный размер, в пределах от минимального, до максимального / 2
- `0b11`: зарезервировано
- `0b00000110`: выделено под настройку размера умовых данных_ в обычных _пакетах_
- `0b00`: без шумовых данных
- `0b01`: заполнение шумовыми данными до лимита полезной нагрузки
- `0b10`: заполнение шумовыми данными в случайном количестве, от нуля, до лимита полезной нагрузки
- `0b11`: зарезервировано
- `0b00000001`: зарезервировано
<!--
- Запрос транспорта (опционально)
- _Ключ:_ `0x05`
- _Тип:_ `uint8_t`
- Если существует, то интерпретируется как запрос переподключения к другому виду транспорта. TODO: Надо сделать енум.
-->
## Ответ на рукопожатие
На запрос рукопожатия с корректным магическим числом целевой _узел_ должен ответить пакетом либо с согласием, либо с ошибкой. Если это ответ с согласием, то данные в пакете должны быть зашифрованы с помощью переданного в запросе хэндшейка симметричного шифра и переданного приватного ключа. Если это ответ с ошибкой, то он может быть незашифрован, в случае, если ошибка связанна с инициализацией шифрования или версией протокола. Таким образом, запрашивающий _узел_ должен быть готов обработать оба варианта развития событий, исходя из значения флага шифрования. Если цель не поддерживает указанные при рукопожатии параметры, запрашивающий может попробовать установить соединение снова, с иными параметрами.
Пакет ответа имеет следующую структуру:
`[magic number: 8B][encryption flag: 1B][LBM-formatted data: >0B]`
### Данные
Данные в формате _LBM_ содержат следующие ячейки:
- Максимальный размер полезной нагрузки
- _Ключ:_ `0x71`
- _Тип:_ `uint16_t`
- _Обязательна:_ только для соглашения
- Всегда больше нуля. Оба _узла_ должны соблюдать размерность полезной нагрузки в событии, она всегда должна быть равна или меньше этого значения.
- Код ошибки
- _Ключ:_ `0x72`
- _Тип:_ `uint8_t`
- _Обязательна:_ только для ошибки
- Код, описывающий тип ошибки:
- `0x01`: магическое число ложно
- `0x02`: неподдерживаемая версия протокола
- `0x03`: недопустимый алгоритм хэширования
- `0x04`: недопустимый алгоритм подписи
- `0x05`: недопустимый алгоритм симметричного шифрования
- `0x06`: некорректный приватный ключ
- `0x07`: некорректный публичный ключ подписи
- `0x08`: недопустимые параметры шума
- `0x09`: невозможно корректно расшифровать данные (ложный публичный ключ целевого _узла_)
- Описание ошибки
- _Ключ:_ `0x73`
- _Тип:_ `char[]`
- _Обязательна:_ нет
- Строка в кодировке ASCII, описывающая ошибку в человекочитаемом виде.
<!--TODO: стартовый SID-->