Files
utun2/doc/devgroup_tz.txt
T

79 lines
12 KiB
Plaintext
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.
Внедрение группы устройств в чат (devgroup).
Первый этап: объединение устройств одного пользователя и группировка в списке участников.
1. Идентичность и хранение.
Устройство состоит максимум в одной devgroup. При создании группы генерируются две отдельные общие пары ключей:
X25519 для шифрования и Ed25519 для подписей. Публичный ключ Ed25519 идентифицирует группу.
Обе пары одинаковы на всех устройствах devgroup; при добавлении устройств передаются существующие ключи.
Принадлежность подтверждает подпись devgroup над идентичностью конкретного устройства (node_id и его публичные ключи).
Одного совпадения публичного ключа devgroup недостаточно.
Публичные данные devgroup хранятся в отдельных полях nodes: оба публичных ключа, удостоверение устройства, JSON профиля и его подпись.
Эти же данные входят в TOPO_NODE и подписанный снимок node_snapshots; nodes содержит их согласованную проекцию.
Принадлежность общая для узла, независимо от каналов; в peers_<channel_id> и userinfo поля devgroup не добавляются.
Секреты хранятся отдельно от публичного профиля и не теряются при перезапуске; текущий local_identity перезаписывается при старте.
2. Приглашение.
A выбирает «Это моё устройство» в контекстном меню B. Пункт виден только для неудалённого чужого устройства
без devgroup, доступного через живой BGP-маршрут. На Android меню доступно по ⋮ и долгому нажатию строки.
Сначала открывается пояснение об общей подгруппе/ключах и PIN. Только кнопка «Связать» начинает приглашение;
до отправки повторно проверяются выбранный канал, доступность B и отсутствие у B подгруппы.
На A показывается PIN из 4 цифр. На B запрос не открывает окно: в меню self (либо своей подгруппы)
появляется «Завершить спаривание». На Android этот пункт доступен по ⋮ и долгому нажатию.
Открытое пользователем окно объясняет операцию и предлагает просто закрыть его, если пользователь не связывает личные устройства.
Закрытие окна не принимает приглашение; до истечения срока его можно снова открыть из меню self.
B вводит PIN с экрана A и генерирует отдельный ответный PIN, отличный от введённого.
После проверки первого PIN на A появляется ввод ответного PIN с экрана B.
Ответный PIN не передаётся автоматически: A отправляет только введённую пользователем попытку, которую проверяет B.
До успешной проверки обоих PIN ключи не передаются; B принимает ключи только после проверки своего ответного PIN.
Обмен идёт через ETCP-router с обязательными сквозным шифрованием и подписью; BGP обеспечивает маршрут.
Приглашение одноразовое, привязано к ключам B и случайному ID, действует 2 минуты на оба шага, допускает по 3 попытки каждого PIN.
Только после успешной проверки обоих PIN A создаёт обе пары ключей, если группы ещё нет; иначе использует существующие.
A передаёт ключи и профиль группы. B проверяет и сохраняет их, затем подтверждает успех.
Повторы идемпотентны; потеря подтверждения означает неизвестный результат, а не отказ. Переданные секреты отменой не отзываются.
Устройство из другой devgroup должно сначала выйти из неё; неявного слияния групп нет.
3. Профиль и версии.
Ник, ver, timestamp и публичный ключ X25519 входят в расширяемый JSON, целиком подписанный ключом Ed25519 devgroup
с отдельным назначением подписи. Подпись связывает ключ шифрования с идентичностью группы.
Хранятся и пересылаются исходные подписанные байты. Победитель определяется по (ver, timestamp, SHA256(JSON)).
Локальное изменение увеличивает максимальную известную ver на 1; при репликации версия не увеличивается.
Для профиля devgroup задаётся отдельный ограниченный размер с учётом полного NODEINFO; лимит userinfo менять не требуется.
Версия профиля devgroup и timestamp подписанного снимка узла независимы.
4. Репликация первого этапа.
Данные devgroup распространяются через текущую синхронизацию nodes (NODEINFO/BGP) в составе общей подписанной записи узла.
Текущих гарантий доставки достаточно для первого этапа; отдельный протокол синхронизации и offline-доставки не добавляется.
Проверяются подпись узла, удостоверение принадлежности и подпись профиля devgroup. Обновление снимка заменяет блок целиком.
Более свежий профиль своей devgroup устройство принимает и публикует в новом собственном снимке во всех своих топологических группах.
Чужие снимки не меняются; неизменившийся профиль не вызывает новой публикации.
Синхронизация зависит от распространения NODEINFO через существующие группы; отдельная сеть устройств в первый этап не входит.
После восстановления связи и при вступлении в новую группу используется штатный обмен NODEINFO.
5. Выход.
Кнопка «Отключить от моих устройств» доступна в свойствах self. Выход удаляет локальные ключи и публикует новый собственный снимок с пустым блоком devgroup и увеличенным timestamp.
Локальное состояние, снимок node_snapshots и поля nodes меняются атомарно; уведомления и распространение выполняются после commit.
Старые сетевые записи не возвращают устройство в группу. Принудительный отзыв устройства со сменой ключей — отдельный этап.
6. Список участников и границы этапа.
В Qt и Android устройства с проверенной принадлежностью объединяются под раскрывающимся [+] с актуальным ником devgroup.
Принадлежность берётся из nodes по node_id; профиль выбирается простым поиском наиболее свежего проверенного объявления
среди текущих записей известных узлов devgroup по порядку из п. 3. Отдельный постоянный кеш профилей не нужен.
Изменение общей записи обновляет отображение участника во всех каналах, где он присутствует.
Внутри показываются устройства текущего канала. Права и действия остаются у конкретных устройств;
заголовок группы не подменяется node_id одного из них. Группа online, если доступно хотя бы одно активное устройство.
Звонки на все устройства и объединение DM в первый этап не входят.
Порядок реализации: nodes/TOPO_NODE/снимок и проверка devgroup → NODEINFO/BGP и профиль → приглашения → API/headless → Qt и Android.
Проверить подделки, конфликты версий, обновление через штатный обмен NODEINFO, повторы, потери ответов, перезапуск, ошибки сохранения и выход.
Логи показывают состояния и причины отказов, но не PIN и секреты.
Протокол приглашений (все сообщения signed+encrypted, общий заголовок kind1,id16):
OFFER=1 без тела; PIN=2 и RETURN_PIN=5: attempt1,PIN4; KEYS=3: ed_priv32,x_priv32,record;
RESULT=4: phase1,attempt1,result1. phase:1=первый PIN,2=ответный PIN,3=импорт; result:0=успех,1=повтор ввода,2=отказ.
Каждый счётчик попытки принимается один раз; сетевой повтор с тем же PIN возвращает прежний результат, с иным отвергается.
Состояния UI:1=ожидается первый PIN,2=проверка первого,3=отправлены ключи,4=успех,5=отказ,6=истёк,
7=результат неизвестен,8=ожидается ответный PIN,9=его проверка,10=B ожидает ключи после проверки ответного PIN.
Локальный status JSON содержит показываемый собственный PIN, input=1/2 для ввода и pin_error для повторной попытки.
Этот JSON предназначен только для локального UI/control API и не логируется; введённые PIN в снимок не попадают.