Add common DM parser and signed subgroup recipient context

This commit is contained in:
evgeny committed 2026-11-03 12:18:25 +01:00
1 parent d81b3139fa
commit 2d8d57be47
2 files changed
+204

No files matched your search

+57
View File
@@ -0,0 +1,57 @@
/* dm_protocol — единый разбор тела DEVICE/GROUPS и сертификатов адресатов.
* DEVICE сохраняет существующий формат. GROUPS занимает зарезервированный
* ct_len=0 и помещает типизированные стороны/адресатов перед настоящим ct.
* Тело подписывается целиком, включая снимок; parser не проверяет подпись автора.
* Указатели view заимствуют входной буфер. SQL-функция encode вызывается в uasync. */
#ifndef UTUN_DM_PROTOCOL_H
#define UTUN_DM_PROTOCOL_H
#include "dm_identity.h"
#ifdef __cplusplus
extern "C" {
#endif
#define DM_TARGET_PROOF_SIZE 137 /* node:LE64,side:u8,x:32,ed:32,member_sig:64. */
#define DM_CONTEXT_MAX (1 + 2 * DM_PARTY_WIRE_SIZE + 2 + DM_TARGET_MAX * DM_TARGET_PROOF_SIZE)
#define DM_BODY_MAX (33 + DM_CONTEXT_MAX + 1 + 255 + 2 + 1024 + 16 + 56 + 64)
struct dm_message_view {
uint64_t conv, seq, timestamp, author; /* Общий префикс, native-endian. */
enum dm_mode mode;
struct dm_party parties[2]; /* Только GROUPS: сторона автора, другая сторона. */
uint16_t target_count; /* GROUPS: снимок включает автора. DEVICE: 0. */
const uint8_t* targets; /* target_count сертификатов по DM_TARGET_PROOF_SIZE. */
const uint8_t* content_type; /* Не NUL-строка, ровно content_type_size байт. */
uint8_t content_type_size;
const uint8_t* ciphertext; /* ciphertext_size байт, включая CCM tag. */
uint16_t ciphertext_size;
const uint8_t* media; /* UUID/size/hash:56 либо NULL. */
const uint8_t* signature; /* Подпись автора:64. */
size_t size; /* Длина тела; parser допускает хвост после него. */
};
/* 0/-1: проверить границы/форму тела и вернуть view. Выход не меняется при ошибке.
* Проверка точной длины, подписей и адресата — обязанность принимающего модуля. */
int dm_message_parse(const uint8_t* body, size_t available, struct dm_message_view* out);
/* 0/-1: GROUPS проверяет ID беседы, упорядоченный уникальный snapshot, обе стороны,
* наличие автора на стороне 0 и подписи удостоверений. DEVICE — пустая операция:
* ID/подпись конкретной пары проверяет dm_core. Ключи самих устройств связаны с node_id. */
int dm_message_verify_targets(const struct dm_message_view* view);
/* GROUPS: найти node в снимке, 0/1 — сторона, -1 — отсутствует. При успехе
* x/ed (если не NULL) получают по 32 байта. Для DEVICE всегда -1. */
int dm_message_target(const struct dm_message_view* view, uint64_t node, uint8_t x[32], uint8_t ed[32]);
/* 0/-1: сформировать контекст GROUPS (без префикса сообщения/нулевого ct_len).
* VERSION=1:u8, parties:2*73,count:LE16,sorted certificates:count*137.
* Сторона 0 должна включать текущего отправителя. out меняется только при успехе;
* DM_CONTEXT_MAX достаточно. Источник включается, неизвестные устройства не ищутся. */
int dm_context_encode(struct UTUN_INSTANCE* inst, const struct dm_party parties[2],
uint8_t* out, size_t capacity, size_t* length);
#ifdef __cplusplus
}
#endif
#endif