14 KiB
Спецификация протокола Stadium v1.0
Протокол Stadium это протокол для безопасной коммуникации общего назначения, работающий поверх любого поддерживаемого транспорта. Также является основой для полнофункционального мессенджера Marafon.
Здесь описана спецификация базового протокола; документация касательно версии протокола используемой в мессенджере размещена в другом репозитории.
Основной фокус при работе над сим проектом идёт на:
- Снижение оверхэдов, по сравнению с классическими решениями (Matrix, Discord, WhatsApp, пр. (Reject HTML+JSON, return to binary.)).
- Устойчивость к цензуре.
- Федеративность.
- Поддержка сквозного шифрования.
- Совместимость со всеми мажорными оверлейными сетями (Tor, I2P и yggdrasil).
- Расширяемость.
Поведение сервера и клиента
Сервер обязан:
- Оповещать клиент о всех ошибках, возникших во время его запроса, кроме связанных с безопасностью.
- Оповещать сервер в федерации о всех ошибках, возникших во время его запроса, кроме:
- Связанных с безопасностью
- Связанных с внутренними неполадками
- По умолчанию отклонять все события, содержащие ложную подпись.
- Отдавать предпочтение данным других серверов, нежели клиентов.
- Отдавать предпочтение сетевым настройкам входящих соединений, нежели локальным (не считая лимиты).
Клиент обязан:
- Не сообщать серверу ни о каких ошибках на своей (клиентской) стороне.
- По умолчанию блокировать до решения юзера все события, содержащие ложную подпись.
- Явно уведомлять юзера при возникновении проблем с безопасностью, как минимум по умолчанию.
События, пакеты и их структура
Существует три уровня категорий событий:
- Надкатегория: Client2Server, Server2Client, Server2Server.
- Категория: например "Authentication", "User", "Message", т.д.
- Подкатегория: например "Login", "Create", "Delete", т.д.
Надкатегория никак не указывается в пакете, зависит от контекста и при упоминании - чаще всего опускается. Она также определяет структуру некоторых событий, которая может меняться в конкретных случаях. Остальные две являются шестнадцатеричными числами размерности указанной при хэндшейке.
Все категории вместе являются типом события. Значение типа - это шестнадцатеричное число, которое указывается в начале пакета.
Пакеты с событиями всех категорий, кроме явно оговорённых или принадлежащих к надкатегории Server2Client, содержат идентификатор серверной сессии, являющийся четырёхбайтным числом без знака (uint32_t
).
Пакеты с событиями всех категорий из надкатегории Client2Server, кроме явно оговорённых, содержат хэш полезной нагрузки, зашифрованный с помощью закрытого ключа подписи клиента. Этот подписанный хэш гарантирует достоверность полезной нагрузки на уровне прямого подключения ("клиент-сервер" или "сервер-сервер").
Данные (AKA "полезная нагрузка") могут быть представлены в формате фиксированной схемы или в формате KLDR ("Key-Length-Data-Repeat"), которые являются расположенными последовательно парами "ключ-значение" и могут быть расположены в произвольном порядке относительно друг-друга. Формат целиком зависит от типа события. Все неизвестные ключи при парсинге игнорируются. Одна пара (AKA "ячейка") имеет следующий вид:
[key][data length][data]
Следовательно, полезная нагрузка в данном формате имеет вид:
[cell_1][cell_2][cell_3]...[cell_n]
Ключ и длинна данных являются шестнадцатеричными числами, размерность которых задаётся на этапе хэндшейка. Полезная нагрузка не может отсутствовать полностью (кроме особо-оговорённых случаев), а ключ не может являться нулём. Если значение конкретной пары пусто, то длинна данных должна быть нулём.
Исходя из всего вышеописанного, итоговая примерная структура пакета выглядит следующим образом:
[category][subcategory][server session: 4B][payload hash: ~B][payload: >0B]
Размер пакета не нормирован и ответственность за его менеджмент остаётся на транспортном уровне. (Эталонная реализация Stadium будет использовать общий универсальный интерфейс, который, в свою очередь, заворачивать все данные в релевантный протокол транспортного уровня)
Зарезервированные события
Некоторые категории событий зарезервированы под нужды базового протокола или просто для событий определённого рода. Второе носит рекомендательный характер; вы также можете использовать другие диапазоны для тех-же целей.
Все из зарезервированных типов помещаются в минимальную размерность типа события (т.е. по одному байту на категорию и подкатегорию). Ниже приведены диапазоны зарезервированных значений.
Зарезервировано для нужд протокола и запрещено к использованию в частных реализациях (см. также файлы в директории reserved/
для конкретных примеров):
- Категория
0x01
- Все субкатегории: выделены для событий общей направленности.
- Категория
0x11
- Все субкатегории: выделены для событий ошибок и предупреждений протокольного уровня.
Рекомендуется к использованию в конкретных ситуациях:
- Категории
0x12-0x1F
(включительно)- Все субкатегории: для событий ошибок и предупреждений.
Зарезервированные ключи ячеек
У данных в формате KLDR также существуют зарезервированные ключи, которые аналогичным образом помещаются в минимальную размерность ключа:
0x00
- Запрещено к использованию.
0x01-0x20
(включительно)- Базовые примитивы.
0x21-0x2F
(включительно)- Для нужд криптографии.
Подробное описание зарезервированных ключей есть в файле KLDR RESERVED KEYS.md
.
Соединение, аутентификация и сессии
Первичное подключение к серверу может выполнятся разными способами, в том числе подразумевающими маскировку траффика под существующие протоколы, но при использовании вне локальных сетей - должно сводиться к установке защищённого соединения.
Рукопожатие
См. файл HANDSHAKE.md
.
Аутентификация
Описываемый протокол предполагает наличие базовых механизмов аутентификации. Все они сводятся к проверке как цели, так и запрашивающего на предмет релевантного доступа.
Сессии и подпись
Пример работы подписи; при отправке сообщения клиентом другому клиенту, оно проходит следующую цепочку:
- Клиент-отправитель посылает пакет с подписанной полезной нагрузкой (далее - ППН) и подписанными основными данными (как часть содержания ППН), на свой хоумсервер (далее - ХС; место, где клиент аутентифицирован).
- ХС проверяет подпись ППН на валидность. Допустим, что подпись верна.
- ХС совершает релевантные действия, исходя из содержания и типа события.
- ХС переподписывает пакет с использованием свой подписи.
- ХС отправляет переподписанный пакет целевому серверу (далее - ЦС).
- ЦС проверяет подпись ППН на валидность. Допустим, что подпись верна.
- ЦС совершает релевантные действия, исходя из содержания и типа пакета.
- ЦС переподписывает пакет с использованием своей подписи.
- ЦС отправляет переподписанный пакет целевому клиенту (далее - ЦК).
- ЦК проверяет подпись ППН на валидность. Допустим, что подпись верна.
- ЦК проверяет подпись основных данных, на предмет соответствия подписи клиента-отправителя и совершает релевантные действия.
Каждый принятый сервером пакет, содержащий хэш полезной нагрузки, должен проверяться на соответствие подписи. Если сервер обнаруживает, что подпись неверна - сервер отвечает ошибкой, соединение разрывается, а администратор сервера и владелец учётной записи уведомляются об инциденте.
Каждый принятый клиентом пакет, содержащий хэш полезной нагрузки, может быть проверен на соответствие подписи. Если клиент обнаруживает, что подпись неверна - он должен оповестить пользователя.
Полезная нагрузка пакета может быть проверена на целостность сервером или клиентом с использованием хэша, но данная проверка может быть отключена, по усмотрению владельца сервера или пользователя клиента.
Если при проверке ID серверной сессии обнаруживается несоответствие - сервер отвечает ошибкой, соединение разрывается.
Список ToDo (To Document)
- Механизм пользовательский сессий, клиентские подписи и базовая аутентификация
- Механизм синхронизации ключей для сквозного шифрования между юзерами
- Манипуляции с файлами (скачивание/загрузка)
- Стриминг аудио и видео