文件

10 KiB

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.3tls_record(记录层) tls_keys(key schedule) tls_extensions(扩展)
                     tls_handshake13/12(状态机) tls_transcript tls_conn(API/生命周期) tls_client/server(入口)
src/ssh/             SSH-2transport/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.ps1gcc,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 / HRRTLS 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_pskticket MAC+binder 验证)、ch_ext_cb/ks_lookup_cbsupported_groups 首组 vs key_share 查找决定 HRR)、sent_hrr 分支发送 HRRrandom=魔数 CF21AD74E58690691115AEDE1F40DFC9C4504D46C174A12E8B4A6F1346F84A4F)、early_read 解密早数据入 early_buf、跳过 EndOfEarlyData 后切 handshake_read
  • key schedulesrc/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_datatype 42)、key_share_client(…only_group)
  • 内部字段(src/ssl/tls_internal.h):hrr_raw/ch2/had_hrr/hrr_group/sent_hrrearly_offer/early_sent/early_accepted/early_acceptearly_read/early_write
  • 公共 APIinclude/paze/tls.h + tls_conn.c):paze_tls_config_enable_early_datapaze_tls_early_write(握手前发早数据)、paze_tls_early_data_acceptedpaze_tls_early_data_len(服务端早数据缓冲)、paze_tls_hrr_occurred
  • CLIapps/pazessl/main.c):s_client -early -sess_in/-sess_out -key_share X25519|P-256s_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-256hrr=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)
  • ECDSAecdsa.c/h 新增 paze_ecdsa_p384_sign/verifyRFC 6979 确定性 k)、paze_ecdsa_p384_priv_from_pem/derRFC 5915,secp384r1
  • X.509x509.c/h 支持 secp384r1 证书解析(pk_kind==ECDSA_P384)、验签(ecdsa-with-SHA384,及 SHA256 配 P-384)、paze_x509_build_spki384、签发(signer.ecdsa_d384
  • TLStls.hPAZE_TLS_GROUP_SECP384R1(0x0018) / PAZE_TLS_SIG_ECDSA_SECP384R1_SHA384(0x0503)tls_internal.h kexP384p384_priv[48]/p384_pub[97]tls_handshake13.c kex_generate/ecdh、sign_cv/verify_cv、HRR、服务端 key_share 支持 P-384ECDH 按 SEC1 x 坐标 48 字节);tls_extensions.c supported_groups/signature_algorithms/key_share;TLS 1.2 ECDHE 亦支持
  • CLIs_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:portstdio/netcat 转发,目标 TCP 隧道桥接本地 stdio)、-N(仅端口转发不执行远程命令,配 -L/-R/-D)。

已知限制:-J 接受逗号分隔的多跳语法,但多级级联跳板在同步 I/O 架构下的应用数据阶段交互不稳定,实测多跳握手可完成但握手后易卡;故当前对多跳打印警告并退化为仅第一跳的稳定单跳。单跳与 -W/-N 均已实测验证。

4. secp521r1TLS 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/hpaze_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 -pwdpsshd -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 状态。