116 行
10 KiB
Markdown
116 行
10 KiB
Markdown
# AGENT.md — 接手指南
|
||
|
||
## 项目结构
|
||
|
||
```
|
||
include/paze/ 公共头文件(tls.h 对外 API)
|
||
src/crypto/ 密码学原语:哈希/AES/ChaCha20/Poly1305/AEAD/X25519/Ed25519/bignum/RSA/P-256/KDF/ASN.1/X.509
|
||
src/ssl/ TLS 1.2+1.3:tls_record(记录层) tls_keys(key schedule) tls_extensions(扩展)
|
||
tls_handshake13/12(状态机) tls_transcript tls_conn(API/生命周期) tls_client/server(入口)
|
||
src/ssh/ SSH-2:transport/kex/auth/channel/client/server/sftp
|
||
src/util/ 内存/字节序/错误/日志
|
||
apps/ 命令行:pazessl / pssh(分发) / 独立命令(pscp/pkeygen/psshd/psftp…)
|
||
build/ 中间产物(编译)/测试脚本/互操作脚本
|
||
bin/ 构建输出(exe)
|
||
STATUS.md 完成度总表 AGENT.md 本文件
|
||
```
|
||
|
||
## 硬性规则
|
||
|
||
1. **目标平台 Los4**:不实现 Windows/Linux/macOS 编译目标(当前平台仅作构建宿主)。
|
||
2. **零第三方依赖**:仅 ISO C17 + libc;不用 OpenSSL/mbedTLS/GMP;熵来自系统调用。
|
||
3. **结构分层**:`crypto 原语 → ssl/ssh 协议 → apps 命令`,协议层不直接依赖应用层。
|
||
4. **常量时间**:密码学核心路径禁止密钥相关分支(用 `paze_ct_equal` 等)。
|
||
5. **编码风格**:纯 C、紧凑直接、注释用中文、不做多余抽象层、单文件状态机。
|
||
6. **构建**:`.\build.ps1`(gcc,C17),产物进 `bin/`,中间件留 `build/`。
|
||
7. **测试**:`build/run_tls_test.ps1` 自测、`build/run_openssl_interop.ps1` 互操作;改动后必须跑通自测。
|
||
8. **Git**:中文提交信息;不主动推送;**推送只发往 parlz(gitea):`https://git.parlz.com/Paze/PazeSSH.git`,不再提交 origin(GitHub)**;无 push 权限/网络问题时如实报告。
|
||
9. **文档**:改功能同步更新 STATUS.md;不建多余 .md。
|
||
|
||
## 已实现功能要点
|
||
|
||
### 0-RTT / HRR(TLS 1.3,RFC 8446)
|
||
- 状态机(`src/ssl/tls_handshake13.c`):
|
||
- 客户端:`paze_tls13_client_send_ch`(抽出的 CH 发送,幂等)、`client_handle_hrr`(识别 HRR 魔数 → `paze_tls_tr_reset_to_synthetic` 合成 MessageHash → CH2 仅选定组 share)、`client_rebuild_transcript`、EndOfEarlyData 在 client Finished **之前**用 early_write 发送
|
||
- 服务端:`server_try_psk`(ticket MAC+binder 验证)、`ch_ext_cb`/`ks_lookup_cb`(supported_groups 首组 vs key_share 查找决定 HRR)、`sent_hrr` 分支发送 HRR(random=魔数 `CF21AD74E58690691115AEDE1F40DFC9C4504D46C174A12E8B4A6F1346F84A4F`)、early_read 解密早数据入 `early_buf`、跳过 EndOfEarlyData 后切 handshake_read
|
||
- key schedule(`src/ssl/tls_keys.c`):`paze_tls13_derive_early_key`(PSK 关联 hash 直哈希最终 CH,client_early_traffic_secret → early_write/early_read)、`paze_tls13_psk_early_secret`
|
||
- 扩展(`src/ssl/tls_extensions.c`):`paze_tls_ext_write/parse_early_data`(type 42)、`key_share_client(…only_group)`
|
||
- 内部字段(`src/ssl/tls_internal.h`):`hrr_raw/ch2/had_hrr/hrr_group/sent_hrr`、`early_offer/early_sent/early_accepted/early_accept`、`early_read/early_write`
|
||
- 公共 API(`include/paze/tls.h` + `tls_conn.c`):`paze_tls_config_enable_early_data`、`paze_tls_early_write`(握手前发早数据)、`paze_tls_early_data_accepted`、`paze_tls_early_data_len`(服务端早数据缓冲)、`paze_tls_hrr_occurred`
|
||
- CLI(`apps/pazessl/main.c`):`s_client -early -sess_in/-sess_out -key_share X25519|P-256`;`s_server -early -reuse`
|
||
- 已知约束:0-RTT 仅在同进程会话复用(ticket_key 内存态)时可用;跨进程重启服务端会拒绝 PSK → early 记录解密失败(预期行为)
|
||
- 验证:`s_server -reuse 2 -early` + 两次 `s_client`(首次 `-sess_out`、二次 `-sess_in -early`)→ `early data received` + `early accepted`;`-key_share P-256` → `hrr=YES`
|
||
|
||
## 待办(按优先级)
|
||
|
||
### 1. 0-RTT / HRR — TLS 1.3 数据路径(✅ 已完成 2026-08-13,详见上文要点)
|
||
|
||
### 2. TLS secp384r1(✅ 已完成 2026-08-13)
|
||
|
||
已实现 P-384 完整链路:
|
||
- 曲线:`src/crypto/p384.c` + `include/paze/p384.h`(Jacobian 点运算、常量时间标量乘、仿射编解码,结构对齐 p256)
|
||
- ECDSA:`ecdsa.c/h` 新增 `paze_ecdsa_p384_sign/verify`(RFC 6979 确定性 k)、`paze_ecdsa_p384_priv_from_pem/der`(RFC 5915,secp384r1)
|
||
- X.509:`x509.c/h` 支持 secp384r1 证书解析(`pk_kind==ECDSA_P384`)、验签(ecdsa-with-SHA384,及 SHA256 配 P-384)、`paze_x509_build_spki384`、签发(`signer.ecdsa_d384`)
|
||
- TLS:`tls.h` 增 `PAZE_TLS_GROUP_SECP384R1(0x0018)` / `PAZE_TLS_SIG_ECDSA_SECP384R1_SHA384(0x0503)`;`tls_internal.h` `kex` 增 `P384` 与 `p384_priv[48]/p384_pub[97]`;`tls_handshake13.c` `kex_generate/ecdh`、sign_cv/verify_cv、HRR、服务端 key_share 支持 P-384(ECDH 按 SEC1 x 坐标 48 字节);`tls_extensions.c` supported_groups/signature_algorithms/key_share;TLS 1.2 ECDHE 亦支持
|
||
- CLI:`s_client -key_share P-384`
|
||
- 验证:P-384 曲线(n·G=∞、3G=2G+G)、ECDSA 双向(OpenSSL 验我的签名 + 我验 OpenSSL 签名)、X.509 P-384 自签名证书 OpenSSL `verify=OK`、TLS 端点 P-384 密钥交换(hrr=YES)+证书链/主机名验证全部通过;既有自测无回归
|
||
|
||
附带修复:
|
||
- `ecdsa.c` `bits2int`:输入短于群阶 qlen 时应右对齐而非左移(否则 P-384+SHA-256 验签错误)
|
||
- `tls_conn.c` 新增 `paze_tls_store_peer_cert`:对端证书 DER 拷贝到自有缓冲,避免 issuer/subject 指针指向被记录层复用的 `app_buf` 导致链验证失败(TLS 1.3 与 1.2 均在 Certificate 解析处使用)
|
||
|
||
### 3. SSH ProxyJump(✅ 基础完成)
|
||
|
||
客户端经跳板机转发连接目标主机,核心链路已实现(`apps/ssh/main.c` 初始版本即含):
|
||
- `-J <user@host[:port]>`:`connect_target()` 在跳板会话上用 `direct-tcpip` 通道承载目标 SSH 握手(嵌套会话),主事件循环直接轮询跳板 socket。
|
||
- config 文件 `ProxyJump` 字段解析(`src/ssh/ssh_config.c`)与匹配。
|
||
- 补全(2026-08-14):`pssh ssh -W host:port`(stdio/netcat 转发,目标 TCP 隧道桥接本地 stdio)、`-N`(仅端口转发不执行远程命令,配 `-L/-R/-D`)。
|
||
|
||
已知限制:`-J` 接受逗号分隔的多跳语法,但多级级联跳板在同步 I/O 架构下的应用数据阶段交互不稳定,实测多跳握手可完成但握手后易卡;故当前对多跳打印警告并**退化为仅第一跳的稳定单跳**。单跳与 `-W`/`-N` 均已实测验证。
|
||
|
||
### 4. secp521r1(TLS P-521)(✅ 已完成 2026-08-14)
|
||
|
||
复用 P-384 全链路套路新增 P-521:
|
||
- 曲线 `src/crypto/p521.c` + `include/paze/p521.h`(域 p=2^521-1,标量/仿射点 66/133 字节,常量时间标量乘;注意 P-521 非整字节对齐,标量乘须按大端位 `byte=65-t/8, bit=t&7` 遍历)。
|
||
- ECDSA:`ecdsa.c/h` 增 `paze_ecdsa_p521_sign/verify`(RFC 6979,配 SHA-512)与 RFC 5915 私钥解析。
|
||
- X.509:`x509.c/h` 支持 secp521r1 证书解析/验签/签发(`ecdsa_p521_pub[133]`、`build_spki521`、signer `ecdsa_d521[66]`、ecdsa-with-SHA512)。
|
||
- TLS:`PAZE_TLS_GROUP_SECP521R1(0x0019)` / `PAZE_TLS_SIG_ECDSA_SECP521R1_SHA512(0x0603)`,kex 增 `P521`,ECDH 按 SEC1 x 坐标 66 字节,supported_groups/key_share/CertificateVerify/HRR/TLS 1.2 ECDHE 均支持。
|
||
- CLI:`s_client -key_share P-521`。
|
||
- 验证:曲线(n·G=∞、3G=2G+G)、ECDSA 双向、X.509 证书 OpenSSL verify=OK、TLS 端点(密钥交换 hrr=YES+证书链/主机名验证)全部通过;既有自测无回归。
|
||
|
||
### 5. TLS 1.3 会话恢复持久化(✅ 已完成 2026-08-14)
|
||
|
||
session ticket key 支持持久化到文件:新增 `paze_tls_config_set_session_ticket_file`(设文件路径)与 `paze_tls_ensure_ticket_key`(首次生成时读取/写盘;PSK 验证入口 `server_try_psk` 亦调用以加载),实现服务端**跨进程重启**后会话恢复仍然有效。`pazessl s_server -ticket_file <file>`,端到端验证(重启后 resumed=YES)。
|
||
|
||
### 6. session ticket key 轮换(✅ 已完成 2026-08-14)
|
||
|
||
支持 2 代 ticket key:新增 `paze_tls_config_rotate_ticket_key`(当前 key 转上一代、新 key 装当前,写盘 2×32 字节);验证用所有已就绪 key 遍历匹配 MAC(不依赖 ticket 内槽位),轮换后旧 ticket 仍由上一代 key 平滑验证。`pazessl s_server -rotate_ticket_key`,验证:轮换后旧会话仍恢复 + 新会话跨进程恢复。
|
||
|
||
### 7. SSH config 兼容 + ECDSA KAT 基线(✅ 已完成 2026-08-14)
|
||
|
||
- `pssh ssh` config 读取优先级:`-F <file>` > `~/.ssh/config`(OpenSSH 兼容) > `~/.pssh/config.conf`;支持 `Host/HostName/Port/User/IdentityFile/ProxyJump/StrictHostKeyChecking`。
|
||
- 新增 `build/run_ecdsa_selfcheck.ps1`(KAT 基线):对 P-256/384/521 跑 ECDSA sign→verify 自洽,防回归。
|
||
|
||
### 8. 长连接保活 + fail2ban 兼容(✅ 已完成 2026-08-14)
|
||
|
||
- `pssh ssh -o ServerAliveInterval=N`(默认15s):空闲发 `keepalive@openssh.com` global request(ssh_keepalive_send, fire-and-forget),保持空闲连接不中断;服务端回包形成保活闭环。
|
||
- `psshd` 认证失败日志对齐 OpenSSH 格式(`Invalid user`/`Failed password ... from <IP>`),并记录对端 IP(`ssh_session_set_peer_ip`),fail2ban 默认 `sshd` filter 可直接匹配封禁。
|
||
|
||
### 9. keyboard-interactive 认证(✅ 已完成 2026-08-14)
|
||
|
||
- 客户端:password 失败后 fallback 到 keyboard-interactive(RFC 4256,收发 INFO_REQUEST/RESPONSE,以密码响应)。
|
||
- 服务端:方法含 `keyboard-interactive` 并复用用户库密码校验;`psshd -kbdint` 强制仅接受 ki。
|
||
- 验证:`pssh -pwd` 连 `psshd -kbdint` 经 ki 认证成功。
|
||
|
||
### 10. agent 转发(-A)(✅ 已完成 2026-08-14, POSIX)
|
||
|
||
- `pssh ssh -A`:开 `auth-agent@openssh.com` 通道,事件循环桥接本地 agent socket 与通道(`ssh_agent_fd`)。
|
||
- 限制:PazeSSH 仅 POSIX 可用;Windows agent 为命名管道(无 select fd)运行时明确禁用并提示;无本地 agent 时报 `cannot connect local agent`。
|
||
|
||
### 11. 自动重连(实用版)(✅ 已完成 2026-08-14)
|
||
|
||
- `pssh ssh -o ReconnectInterval=N`:断线(keepalive 发送失败判定)由外层循环自动重连并重新执行命令/重开 shell(pssh_cmd_ssh 返回 -2)。
|
||
- 说明:依赖 ServerAliveInterval 心跳探测(建议两者搭配);恢复的是"重连+重跑",不恢复进行中 PTY 状态。
|
||
|
||
|