reality: использовать NTP-время вместо time(NULL) в анти-реплей проверке timestamp
Часы colo2 отстают на ~52с (ntpd выключен), что ломало reality auth (diff < -30с = time_window). Теперь клиент и сервер передают ntp_time_get_seconds() в reality_client_hello_build_at / reality_server_hello_build_at вместо сырого системного времени.
This commit is contained in:
1 parent
481872d5db
commit
27b591daee
4 files changed
+24
-6
No files matched your search
@@ -488,9 +488,9 @@ static int reality_parse_client_hello(const uint8_t *ch, size_t ch_len,
|
||||
return REALITY_OK;
|
||||
}
|
||||
|
||||
int reality_server_hello_build(const struct reality_server_config *cfg,
|
||||
const uint8_t *ch, size_t ch_len,
|
||||
uint8_t *out, size_t out_cap, size_t *out_len) {
|
||||
int reality_server_hello_build_at(const struct reality_server_config *cfg, uint32_t now_sec,
|
||||
const uint8_t *ch, size_t ch_len,
|
||||
uint8_t *out, size_t out_cap, size_t *out_len) {
|
||||
if (!cfg || !ch || !out || !out_len || out_cap < REALITY_MAX_SH_SIZE) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_REALITY, "reality_server_hello_build: invalid args");
|
||||
return REALITY_ERR_ARG;
|
||||
@@ -546,7 +546,7 @@ int reality_server_hello_build(const struct reality_server_config *cfg,
|
||||
// сверка timestamp
|
||||
uint32_t ts = ((uint32_t)plain[4] << 24) | ((uint32_t)plain[5] << 16) |
|
||||
((uint32_t)plain[6] << 8) | plain[7];
|
||||
int64_t now = (int64_t)time(NULL);
|
||||
int64_t now = (int64_t)now_sec;
|
||||
int64_t diff = now - (int64_t)ts;
|
||||
if (diff < -(int64_t)cfg->time_window_sec || diff > (int64_t)cfg->time_window_sec) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_REALITY, "reality_server_hello_build: timestamp out of window ts=%u now=%lld diff=%lld",
|
||||
@@ -623,3 +623,9 @@ int reality_server_hello_build(const struct reality_server_config *cfg,
|
||||
DEBUG_INFO(DEBUG_CATEGORY_REALITY, "server hello built: total=%zu", *out_len);
|
||||
return REALITY_OK;
|
||||
}
|
||||
|
||||
int reality_server_hello_build(const struct reality_server_config *cfg,
|
||||
const uint8_t *ch, size_t ch_len,
|
||||
uint8_t *out, size_t out_cap, size_t *out_len) {
|
||||
return reality_server_hello_build_at(cfg, (uint32_t)time(NULL), ch, ch_len, out, out_cap, out_len);
|
||||
}
|
||||
@@ -105,6 +105,13 @@ int reality_server_hello_build(const struct reality_server_config *cfg,
|
||||
const uint8_t *ch, size_t ch_len,
|
||||
uint8_t *out, size_t out_cap, size_t *out_len);
|
||||
|
||||
// То же, но с явным now (unix-секунды) для анти-реплей проверки timestamp.
|
||||
// Вызывающий код передаёт синхронизированное время (ntp_time_get_seconds),
|
||||
// чтобы не зависеть от сырого time(NULL) при рассинхроне системных часов.
|
||||
int reality_server_hello_build_at(const struct reality_server_config *cfg, uint32_t now_sec,
|
||||
const uint8_t *ch, size_t ch_len,
|
||||
uint8_t *out, size_t out_cap, size_t *out_len);
|
||||
|
||||
// Сгенерировать X25519 пару ключей (для конфигурации: сервер хранит privkey,
|
||||
// клиент — pubkey сервера). Возвращает REALITY_OK / REALITY_ERR_CRYPTO.
|
||||
int reality_generate_keypair(uint8_t priv[REALITY_AUTH_KEY_SIZE],
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "secure_channel.h"
|
||||
#include "crc32.h"
|
||||
#include "etcp.h"
|
||||
#include "../ntp_time.h"
|
||||
#include "../lib/u_async.h"
|
||||
#include "../lib/socket_compat.h"
|
||||
#include "../lib/ll_queue.h"
|
||||
@@ -173,7 +174,9 @@ static void client_after_connect(struct stcp_conn *c) {
|
||||
int opt = 1; setsockopt(c->sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&opt, sizeof(opt));
|
||||
if (cli->reality_enabled) {
|
||||
uint8_t ch[REALITY_MAX_CH_SIZE]; size_t ch_len = 0;
|
||||
if (reality_client_hello_build(&cli->reality_cfg, ch, sizeof(ch), &ch_len) != REALITY_OK) {
|
||||
uint32_t now_sec = (c->etcp_conn && c->etcp_conn->instance)
|
||||
? (uint32_t)ntp_time_get_seconds(c->etcp_conn->instance) : (uint32_t)time(NULL);
|
||||
if (reality_client_hello_build_at(&cli->reality_cfg, now_sec, ch, sizeof(ch), &ch_len) != REALITY_OK) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_REALITY, "stcp_client: ClientHello build failed");
|
||||
stcp_conn_do_close(c, 1); return;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "../lib/debug_config.h"
|
||||
#include "../lib/platform_compat.h"
|
||||
#include "../utun_instance.h"
|
||||
#include "../ntp_time.h"
|
||||
#include "etcp.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -232,7 +233,8 @@ static void reality_ch_body_cb(struct stcp_conn *c, uint8_t *data, size_t len) {
|
||||
|
||||
uint8_t sh[REALITY_MAX_SH_SIZE];
|
||||
size_t sh_len = 0;
|
||||
int rc = reality_server_hello_build(&c->reality_srv, full, 5 + len, sh, sizeof(sh), &sh_len);
|
||||
uint32_t now_sec = c->inst ? (uint32_t)ntp_time_get_seconds(c->inst) : (uint32_t)time(NULL);
|
||||
int rc = reality_server_hello_build_at(&c->reality_srv, now_sec, full, 5 + len, sh, sizeof(sh), &sh_len);
|
||||
if (rc == REALITY_OK) {
|
||||
uint8_t *shbuf = u_malloc(sh_len);
|
||||
if (!shbuf) { stcp_conn_do_close(c, ENOMEM); return; }
|
||||
|
||||
Reference in new issue
Block a user