diff --git a/DATA TYPES.md b/DATA TYPES.md index 17f26dd..8c9995a 100644 --- a/DATA TYPES.md +++ b/DATA TYPES.md @@ -4,6 +4,88 @@ +#### CryptoAlgoType + +Перечисление всех допустимых к использованию в базовом протоколе алгоритмов вычисления хэшей, контрольных сумм, симметричного и ассиметричного шифрования. + +```C++ +enum CryptoAlgoType: uint8_t { + Reserved = 0, + // Checksums + CRC_16 = 10, + CRC_32 = 11, + CRC_64 = 12, + fletcher_8 = 13, + fletcher_16 = 14, + fletcher_32 = 15, + Adler_32 = 16, + // Non-crypto hashes + Pearson_8 = 30, + Murmur64A = 31, + Murmur3_32 = 32, + Murmur3_128 = 33, + Spooky_128 = 34, + // Cryptographic hashes + BLAKE2b = 60, + BLAKE3 = 61, + GOST = 62, + HAS160 = 63, + HAVAL = 64, + MD2 = 65, + MD5 = 66, + RIPEMD = 67, + SHA1 = 68, + SHA2 = 69, + SHAKE128 = 70, + SHAKE256 = 71, + Skein = 72, + Snefru = 73, + Streebog = 74, + Tiger = 75, + Whirlpool = 76, + // Symmetric key block ciphers + Blowfish = 130, + Twofish = 131, + TripleDES_CBC = 132, + AES_GCM = 133, // AKA Rijndael + AES_CBC = 134, + AES_CTR = 135, + Camellia = 136, + Salsa20 = 137, + CAST5 = 138, + CAST6 = 139, + Kuznyechik = 140, + MESH = 141, + Akelarre = 142, + RC6 = 143, + // TODO +}; +``` + + + +#### CryptoAlgo + +Структура, определяющая криптографический алгоритм и размерность. Для шифров это размер ключа, а для хэшей - размер выходных данных (если применимо). Для хэш-функций и симметричных шифров размер ключа вычисляется по формуле `Size << 4`, а для ассиметричных по формуле `Size << 8`. Размерность опускается для контрольных сумм и не-криптографических функций. + +```C++ +typedef struct { + CryptoAlgoType Type; + uint8_t Size; +} CryptoAlgo; +``` + +#### ServerDescriptor + +Дескриптор сервера, представляющий из себя хэш открытого ключа серверной подписи и использующийся алгоритм. Длинна хэша может варьироваться, но всегда не более 512 бит. + +```C++ +typedef struct { + char[64] Hash; + CryptoAlgo Type; +} ServerDescriptor; +``` + #### LocID Идентификатор локального для конкретного сервера объекта. @@ -20,7 +102,7 @@ typedef uint64_t LocID; ```C++ typedef struct { uint64_t Object; - std::string Server; // Доменное имя сервера-владельца объекта + ServerDescriptor Server; } GlobID; ``` diff --git a/HANDSHAKE.md b/HANDSHAKE.md index 64166b9..faf5b2d 100644 --- a/HANDSHAKE.md +++ b/HANDSHAKE.md @@ -2,7 +2,7 @@ После успешной установки защищённого соединения, происходит обмен характеристиками обоих сторон, AKA "рукопожатие". Запрашивающий соединение отправляет пакет следующего формата: -`[magic number: 8B][protocol version: 4B][sizes: 1B][crypto params: 2B][reconnection flags: 4B]` +`[magic number: 8B][protocol version: 4B][sizes: 1B][crypto params: 6B][reconnection flags: 4B]` - Магическое число - _Тип:_ `uint64_t` @@ -30,10 +30,9 @@ - `0b11`: размер данных это `uint64_t` - Маска `0b00000011`: резерв - Параметры криптографии - - _Тип:_ `uint16_t` - - Описывает используемые криптографические алгоритмы. - - Если равно нулю, то используются опции данной версии протокола по умолчанию - + - _Тип:_ `CryptoAlgo[3]` + - Описывает используемые криптографические алгоритмы на уровне "клиент-сервер". Первый элемент это используемый алгоритм для хэша полезной нагрузки; второй это алгоритм ассиметричного шифрования; третий элемент это алгоритм симметричного шифра. + - Если равно нулю, то используются опции данной версии протокола по умолчанию (SHA256, RSA-2048, AES-192). - Флаги переподключения - _Тип:_ `uint32_t` - Описывает параметры нового подключения: diff --git a/KLDR RESERVED KEYS.md b/KLDR RESERVED KEYS.md index c4a40e2..affa359 100644 --- a/KLDR RESERVED KEYS.md +++ b/KLDR RESERVED KEYS.md @@ -2,6 +2,8 @@ + + ## Базовые примитивы - Data @@ -10,19 +12,19 @@ - Основные передаваемые данные. - ObjectID - _Значение:_ `0x02` - - _Тип:_ `ID` + - _Тип:_ `LocID || GlobID` - ID объекта в локальном контексте. Например, ID канала для отправки сообщения. -- EventAuthor +- SrcEventAuthor - _Значение:_ `0x03` - - _Тип:_ `LocID` или `FedID` - - Источник (автор) события. Например, если клиент отправляет сообщение в канал, то он должен указывать свой айди как значение этой ячейки. + - _Тип:_ `GlobID` + - Источник (автор) оригинального события. - PrevEvent - _Значение:_ `0x04` - - _Тип:_ `LocID` или `FedID` + - _Тип:_ `LocID` - Предыдущее событие, логически связанное с текущим. - NextEvent - _Значение:_ `0x05` - - _Тип:_ `LocID` или `FedID` + - _Тип:_ `LocID` - Следующее событие, логически связанное с текущим. - BatchNumber - _Значение:_ `0x06` @@ -37,17 +39,19 @@ - _Тип:_ `Power` - Права доступа к конкретному объекту. + + ## Криптография -- CryptoAlgo +- CryptoAlgos - _Значение:_ `0x11` - - _Тип:_ `uint32_t` - - Флаги используемых криптографических алгоритм(-ов) для шифрования данных. + - _Тип:_ `CryptoAlgo[3]` + - Используемые криптографические алгоритмы. Первый элемент выделен под хэш-функцию; второй элемент для ассиметричной функции; третий элемет для симметричной функции. - CryptoKeyID - _Значение:_ `0x12` - _Тип:_ `uint32_t` - Идентификатор используемого криптографического ключа для шифрования данных. -- SignedHash +- SignedDataHash - _Значение:_ `0x13` - _Тип:_ не имеет значения - Хэш основных передаваемых данных, зашифрованный закрытым ключом отправителя. \ No newline at end of file diff --git a/OVERVIEW.md b/OVERVIEW.md index d635e42..1d2646f 100644 --- a/OVERVIEW.md +++ b/OVERVIEW.md @@ -2,21 +2,17 @@ Протокол Stadium это протокол для безопасной коммуникации общего назначения, работающий поверх любого поддерживаемого транспорта. Данная спецификация описывает лишь базу, поверх которой может быть реализованы расширения (SPX - Stadium Protocol eXtension) для более конкретных нужд. Помимо прочего, данный протокол служит основой для полнофункционального мессенджера Marafon, спецификация расширения которого находится в папке `SPX/Marafon/`. -_Здесь описана спецификация базового протокола; документация касательно версии протокола используемой в мессенджере размещена в другом репозитории._ - Основной фокус при работе над сим проектом идёт на: - Снижение оверхэдов, по сравнению с классическими решениями (Matrix, Discord, WhatsApp, пр. (Reject HTML+JSON, return to binary.)). - Устойчивость к цензуре. - Федеративность. -- Поддержка сквозного шифрования. +- Поддержка гибкого сквозного шифрования. (возможность как клиенту так и серверу выбирать, какие криптографические алгоритмы использовать) - Совместимость со всеми мажорными оверлейными сетями (Tor, I2P и yggdrasil). - Расширяемость. В сей спецификации вы иногда сможете встретить примеры кода и упоминание типов данных языка C++, так как без них обойтись моментами сложно. - - ## Поведение сервера и клиента @@ -27,9 +23,10 @@ _Здесь описана спецификация базового прото 2. Оповещать сервер в федерации о всех ошибках, возникших во время его запроса, кроме: - Связанных с безопасностью - Связанных с внутренними неполадками -3. По умолчанию отклонять все события, содержащие ложную подпись. -4. Отдавать предпочтение данным других серверов, нежели клиентов. -5. Отдавать предпочтение сетевым настройкам входящих соединений, нежели локальным (не считая лимиты). +3. По умолчанию отклонять все события аутентифицированного клиента, содержащие ложную подпись. +4. По умолчанию отклонять все события сервера, содержащие ложную подпись. +5. Отдавать предпочтение данным других серверов, нежели клиентов. +6. Отдавать предпочтение сетевым настройкам входящих соединений, нежели локальным (не считая лимиты). Клиент **обязан**: @@ -55,7 +52,7 @@ _Здесь описана спецификация базового прото Пакеты с событиями всех категорий, кроме явно оговорённых, содержат хэш полезной нагрузки, зашифрованный с помощью закрытого ключа подписи отправляющего. Этот подписанный хэш гарантирует достоверность полезной нагрузки на уровне прямого подключения ("клиент-сервер" или "сервер-сервер"). -Данные (AKA "полезная нагрузка") могут быть представлены в формате фиксированной схемы или в формате KLDR ("Key-Length-Data-Repeat"), которые являются расположенными последовательно парами "ключ-значение" и могут быть расположены в произвольном порядке относительно друг-друга. Применяемый формат зависит от типа события, но чаще всего это KLDR. Все неизвестные ключи при его парсинге игнорируются. Одна пара (AKA "ячейка") имеет следующий вид: +Данные (AKA "полезная нагрузка") могут быть представлены в формате фиксированной схемы или в формате KLDR ("Key-Length-Data-Repeat"), которые являются расположенными последовательно парами "ключ-значение" и могут быть расположены в произвольном порядке относительно друг-друга. Сервер и клиент могут перемешивать ячейки перед отправкой намеренно. Применяемый формат зависит от типа события, но чаще всего это KLDR. Все неизвестные ключи при его парсинге игнорируются. Одна пара (AKA "ячейка") имеет следующий вид: `[key][data length][data]` @@ -128,19 +125,23 @@ _Здесь описана спецификация базового прото ## Система идентификаторов -Практически каждый объект в Stadium имеет свой уникальный идентификатор, по которому к нему (объекту) следует обращаться. Идентификаторы делятся на три типа: локальные и глобальные. +Практически каждый объект в Stadium имеет свой уникальный идентификатор, по которому к нему (объекту) следует обращаться. Идентификаторы делятся на два типа: локальные и глобальные. Первый тип является восьмибайтным числом без знака (`uint64_t`). Валидный объект не может иметь ID равный нулю. -Второй тип является структурой из одного восьмибайтного числа без знака и строки в кодировке ASCII, кои являют из себя ID объекта и доменное имя сервера соответственно. +Второй тип является структурой из одного восьмибайтного числа без знака для ID объекта, массива размером 64 байт для дескриптора сервера и однобайтового числа (`uint8_t`) для использованного алгоритма хэширования дескриптора. -Сервер должен проверять идентификатор на валидность и отвергать его, если он не валиден в текущем контексте. +Сервер должен проверять идентификатор на валидность и отвергать его, если он ложен в текущем контексте. -### Доменные имена -Доменное имя может быть ассоциированно как сервером, так и клиентом с несколькими другими альтернативными доменными именами, связанными с этим сервером. -Сервер может отправить подписанное событие другому серверу, с целью ассоциировать новое доменное имя со старым, к примеру, если старое более не актуально. Сервер-получатель события обязан не только проверить подпись, но провести проверку доменного имени на его соответствие серверу-отправителю, путём отправки события с запросом подписи сервера. Это событие должно по умолчанию иметь жёсткий рейт-лимит по критерию запрашиваемого домена, т.е. не более 10 проверок одного доменного имени в час. +## Серверный дескриптор + +Серверный дескриптор являет из себя хэш открытого ключа серверной подписи и может быть представлен в виде base64-кодированной строки, если необходимо. Длинна хэша может варьироваться от 128 до 512 бит. Используемый алгоритм хэширования определяется сервером-владельцем дескриптора. + +Дескриптор может быть ассоциирован с несколькими доменами и/или IP/I2P/Tor-адресами, как на стороне сервера, так и на стороне клиента. Клиент может запросить у сервера список ассоциированных с дескриптором адресов, подписанных закрытым ключом сервера-владельца дескриптора и проверить их на достоверность с помощью его-же публичного ключа. + +Сервер может отправить подписанное событие другому серверу, с целью добавить новый домен(-ы)/адрес(-а) в список ассоциированных с его дескриптором или удалить оттуда. Сервер-получатель события обязан не только проверить подпись, но и проверить все домены и адреса на соответствие серверу-отправителю, путём отправки события с запросом подписи сервера. Это событие должно по умолчанию иметь жёсткий рейт-лимит по критерию каждого отдельного ресурса, т.е. не более 10 проверок одного доменного имени или адреса в час. diff --git a/SESSIONS.md b/SESSIONS.md index 42ac2aa..362065d 100644 --- a/SESSIONS.md +++ b/SESSIONS.md @@ -2,19 +2,29 @@ ## Подпись -### Обмен пакетами в неаутентифицированом соединении +### Серверная подпись -До выполнения аутентификации, сервер может, но не обязан, подписывать каждый свой пакет. Клиент может проверять подпись только в случае наличия у него открытого ключа сервера. Также клиент не должен подписывать свои пакеты и должен устанавливать хэш полезной нагрузки в нулевое значение. +Сервер обязан заведомо иметь пару ключей своей подписи, прежде чем коммуницировать с кем-либо в принципе. Генерировать их желательно вручную, на этапе установки/настройки серверного ПО. + +### Обмен пакетами в неаутентифицированом соединении типа клиент-сервер + +До выполнения аутентификации, сервер может, но не обязан, подписывать каждый свой пакет. Клиент не должен подписывать свои пакеты и должен устанавливать хэш полезной нагрузки в нулевое значение. + +Сервер не должен проверять подпись пакетов клиента. Клиент может проверять подпись только в случае наличия у него открытого ключа сервера. ### Регистрация -Перед инициированием процедуры регистрации, клиент запрашивает открытый ключ подписи сервера и тот отвечает событием, с открытым ключом в качестве основных данных и подписанным закрытым ключом хэшем полезной нагрузки. Клиент должен проверить подпись этого события. +Перед инициированием процедуры регистрации, клиент запрашивает открытый ключ подписи сервера и тот отвечает событием, с открытым ключом в качестве основных данных и подписанным закрытым ключом хэшем полезной нагрузки. Клиент должен проверить подпись этого события с помощью публичного ключа из него-же. -В случае успешной регистрации, клиент генерирует публичный и приватный ключи подписи, после чего отправляет событие с публичным ключом в качестве основных данных и подписанной закрытым ключом хэшем полезной нагрузки на сервер. Сервер должен проверить подпись этого события. + + +В случае успешной регистрации, клиент генерирует публичный и приватный ключи подписи, после чего отправляет событие с публичным ключом в качестве основных данных и подписанным закрытым ключом хэшем полезной нагрузки на сервер. Сервер должен проверить подпись этого события с помощью публичного ключа из него-же. + + ### Обмен пакетами в аутентифицированном соединении -Каждый принятый сервером пакет, содержащий хэш полезной нагрузки, должен проверяться на соответствие подписи, путём расшифровки этого хэша открытом ключом подписи и последующего сравнения с реальным хэшем полезной нагрузки. Если сервер обнаруживает, что подпись неверна - сервер отвечает ошибкой, добавляет запись в журнал об инциденте, а обрабатываемый пакет игнорируется. +Каждый принятый сервером пакет, содержащий хэш полезной нагрузки, должен проверяться на соответствие подписи, путём расшифровки этого хэша открытом ключом подписи и последующего сравнения с реальным хэшем полезной нагрузки. Если сервер обнаруживает, что подпись неверна - сервер отвечает ошибкой, добавляет запись об инциденте в журнал, а обрабатываемый пакет игнорируется. Каждый принятый клиентом пакет, содержащий хэш полезной нагрузки, должен быть проверен на соответствие подписи. Если клиент обнаруживает, что подпись неверна - он уведомляет об этом пользователя, а обрабатываемый пакет игнорируется. diff --git a/moveToAnotherRepo/1.md b/moveToAnotherRepo/1.md deleted file mode 100644 index 1c1b5a9..0000000 --- a/moveToAnotherRepo/1.md +++ /dev/null @@ -1,15 +0,0 @@ -### Регистрация - -При успешной регистрации учётной записи, клиент генерирует пару ключей (открытый-закрытый) в качестве подписи, после чего открытый ключ отправляется серверу и тот сохраняет его. - - - -### Вход в учётную запись - -Вход в учётную запись происходит путём отправки логина и хэша пароля на сервер. При этом клиент может указать ID серверной сессии, если произошло непредвиденное отключение и ему необходимо переподключиться. - -Если логин или пароль несовпадают - сервер отвечает ошибкой и разрывает соединение. Если полезная нагрузка подписана ложно - сервер отвечает ошибкой, соединение разрывается, а администратор сервера и владелец учётной записи уведомляются об инциденте. - -Если ID серверной сессии нет в списке недавно-разорванных - сервер отвечает ошибкой и разрывает соединение. - -При успешном входе в учётную запись, сервер генерирует четырёхбайтное целое без знака (`uint32_t`), являющийся идентификатором серверной сессии. Клиент обязан хранить его и прикреплять к каждому пакету (кроме особо-оговорённых случаев) до момента отключения от сервера. \ No newline at end of file diff --git a/moveToAnotherRepo/Error/README.md b/moveToAnotherRepo/Error/README.md deleted file mode 100644 index d4f1783..0000000 --- a/moveToAnotherRepo/Error/README.md +++ /dev/null @@ -1,16 +0,0 @@ -Все ошибки без исключения должны иметь следующий формат: - -- Код ошибки - - _Ключ:_ 0x01 - - _Тип:_ `uint8_t` - - Код, описывающий ошибку конкретнее. -- Подробные данные - - _Ключ:_ 0x02 - - _Тип:_ `char[]` - - Бинарное описание ошибки. -- Текстовое описание - - _Ключ:_ 0x03 - - _Тип:_ `char[]` - - Текстовое описание ошибки. - -Различия допустимы только в интепретации кода ошибки. \ No newline at end of file diff --git a/reserved/Base/EnumerateServices.md b/reserved/Base/EnumerateServices.md new file mode 100644 index 0000000..e69de29 diff --git a/reserved/Base/GetServerPublicSignKey.md b/reserved/Base/GetServerPublicSignKey.md new file mode 100644 index 0000000..e69de29 diff --git a/reserved/Base/PublicSignKey.md b/reserved/Base/PublicSignKey.md new file mode 100644 index 0000000..e69de29 diff --git a/reserved/Base/ServicesList.md b/reserved/Base/ServicesList.md new file mode 100644 index 0000000..e69de29 diff --git a/reserved/BaseErrors/README.md b/reserved/BaseErrors/README.md new file mode 100644 index 0000000..7b7150d --- /dev/null +++ b/reserved/BaseErrors/README.md @@ -0,0 +1 @@ +У всех событий из этой категории, ячейка базового примитива `Data` обязана содержать подробное описание ошибки. \ No newline at end of file diff --git a/reserved/METHOD FORMAT EXAMPLE.md b/reserved/METHOD FORMAT EXAMPLE.md index f19dc25..db81fcd 100644 --- a/reserved/METHOD FORMAT EXAMPLE.md +++ b/reserved/METHOD FORMAT EXAMPLE.md @@ -2,6 +2,8 @@ **Значение типа: 0xBA98** +**Требует аутентификацию: нет** + ## Client2Server Какое-то описание метода. На данный момент, "оффициально" поддерживается два формата, в которых могут быть представлены данные: KLDR (расположенные последовательно "ключ-длина-значение") и фиксированная схема. Тут представлен пример в формате KLDR.