- tls_handshake12.c: 完整 TLS 1.2 client/server 状态机(ECDHE-RSA/ECDSA/RSA AES-GCM + CHACHA20-POLY1305),支持 1.3 收到 1.2 ServerHello/ClientHello 后回退 - tls_record.c: 修正 TLS 1.2 AEAD-GCM 两处 RFC 偏差: AAD length 字段应为明文长度 ctlen(RFC 5246 6.2.3.3)原为 ct+16; GCMNonce = fixed_iv(4) || explicit_nonce(8)(RFC 5288 3)原顺序相反 - tls_handshake13.c: CV/Finished transcript 处理、1.3 套件记录版本修正、链式证书构造 - x509.c: AttributeTypeAndValue 补 SEQUENCE; validity 2050 年前用 UTCTime - apps/pazessl: s_client/s_server 增加 -tls1_2 - 新增 build.ps1、build/run_tls_test.ps1、build/run_openssl_interop.ps1 验证: 自测 4/4(1.2/1.3 双向 + 回退); OpenSSL 互操作 4/4(s_client/s_server 双向 1.2/1.3)
24 KiB
24 KiB
PazeSSL / PazeSSH 项目代理规范 (AGENT.MD)
版本: v0.5 (2026-08-13) — TLS 1.2 完成(版本回退 + OpenSSL 互操作 4/4)+ X.509 RSA round-trip 修复 + PEM 密钥加载 + 多证书链支持 目标: 用纯 libc + 自底向上 C 语言实现 OpenSSL(平替 PazeSSL) ≤ 100,000 行 与 OpenSSH(平替 PazeSSH) ≤ 30,000 行。 约束: 仅使用libc 要能在裸机上实现,禁止依赖 OpenSSL / LibreSSL / libcrypto / mbedTLS / libgcrypt / libssh 等外部密码学或协议库。
一、总体架构
┌─────────────────────────────────────────────────────────────────┐
│ apps/ CLI 层 │
│ pazessl/ SSH/ sshd/ │
│ (s_client/s_server s_time verify x509) (ssh client) (sshd) │
├──────────┬──────────────────────────────────────────────────────┤
│ src/ssl │ src/ssh │
│ 100k预算 │ 30k预算 │
│ │ │
│ tls_bio │ ssh_packet (binary packet 二进制包层) │
│ tls_record │ ssh_transport (transport layer 传输层) │
│ tls_transcript │ ssh_kex (密钥交换) │
│ tls_keys │ ssh_keys (主机键/公钥) │
│ tls_extensions │ ssh_auth (用户认证:pw/pk/hostbased) │
│ tls_handshake13 │ ssh_channel (会话/shell/exec 通道) │
│ tls_handshake12 │ ssh_client (客户端入口) │
│ tls_client │ ssh_server (sshd 入口) │
│ tls_server │ │
│ tls_conn │ │
├──────────┴──────────────────────────────────────────────────────┤
│ src/crypto (≈7000 行,已完成) │
│ hash (SHA1/224/256/384/512, MD5) │
│ HMAC / HKDF / PBKDF2 │
│ AES-128/256 (ECB/CBC/CTR/GCM) AEAD │
│ ChaCha20 / Poly1305 / ChaCha20-Poly1305 AEAD │
│ bignum (Montgomery 模幂 / 模乘 / 模逆,最大 512 limb=2KB) │
│ RSA PKCS#1 v1.5 + PSS (加密/解密/签名/验签/CRT私钥/密钥生成) │
│ X25519 (曲线25519蒙哥马利梯) Ed25519 (EdDSA) │
│ P-256 (secp256r1 Jacobian 点运算, ECDSA) │
│ ASN.1 DER 读写器 / PEM 编解码 / Base64 / Hex │
│ X.509 v3 (DER/PEM 解析、签名验证、链验证、SAN、自签生成) │
├─────────────────────────────────────────────────────────────────┤
│ src/util (mem/error/log/version) + include/paze/*.h │
├─────────────────────────────────────────────────────────────────┤
二、行数预算(严格上限)
| 层级 / 模块 | 预算 | 已完成(2026-08-12) | 状态 |
|---|---|---|---|
| crypto + util + include | ≤ 10,000 | 6,510 | ✅ 完成(含 fe25519.c) |
| src/ssl (PazeSSL/TLS) | ≤ 60,000 | 2,328 | ✅ TLS 1.3 完成 (extensions/handshake13/client/server/conn) |
| src/ssh (PazeSSH/SSH2) | ≤ 25,000 | 3,779 | ✅ SSH2 全部模块完成 (packet/transport/kex/keys/auth/channel/client/server/scp/agent) |
| apps/ | ≤ 3,000 | 1,839 | ✅ pssh 单可执行(ssh/keygen/keyscan/copy-id/agent/add/sshd/scp) + pazessl |
| tests/ | ≤ 2,000 | 1,688 | ✅ paze_kat 统一测试 + 11 个独立 KAT 可执行程序 |
| 合计 | ≤ 100,000 | 16,144 | 83,856 剩余 |
关键红线:
- SSL 部分(src/ssl + include/paze/tls.h)绝对不可超过 60,000 行。
- SSH 部分(src/ssh)绝对不可超过 25,000 行。
- 任一模块若超限,必须精简:移除冷门特性、压缩 verbose 日志、合并小函数。
三、TLS 模块设计 (PazeSSL)
3.1 公共 API (include/paze/tls.h, 对外不透明)
typedef struct paze_tls_config paze_tls_config_t;
typedef struct paze_tls paze_tls_t;
// 配置
cfg = paze_tls_config_new(PAZE_TLS_CLIENT | PAZE_TLS_SERVER);
paze_tls_config_set_sni(cfg, "example.com");
paze_tls_config_set_alpn(cfg, {"h2","http/1.1"}, 2);
paze_tls_config_set_cert_chain(cfg, cert_pem, privkey_pem); // server
paze_tls_config_set_trust_roots(cfg, roots_pem); // client
paze_tls_config_set_verify(cfg, PAZE_TLS_VERIFY_REQUIRED, verify_cb, ctx);
paze_tls_config_set_versions(cfg, 1, 1); // 1.3 + 1.2 (默认)
paze_tls_config_free(cfg);
// 连接
tls = paze_tls_new(cfg);
paze_tls_set_bio(tls, (paze_tls_bio_t){ctx, read_fn, write_fn});
paze_status_t s = paze_tls_handshake(tls); // 阻塞循环调用
int n = paze_tls_read(tls, buf, buflen);
int n = paze_tls_write(tls, buf, n);
paze_tls_close(tls);
paze_tls_free(tls);
3.2 内部模块(已完成 + 待办)
| 文件 | 状态 | 说明 |
|---|---|---|
| tls.h | ✅ 完成 | 公共头:类型、cipher suite、常量、API |
| tls_internal.h | ✅ 完成 | 内部头:paze_tls_t 全字段、各模块共享原型 |
| tls_bio.c | ✅ 完成 | BIO read/write 阻塞循环封装 |
| tls_record.c | ✅ 完成 | 1.3 AEAD(iv xor seq) + 1.2 AEAD-GCM(explicit nonce+seq) |
| tls_transcript.c | ✅ 完成 | Transcript hash + HRR 合成 MessageHash |
| tls_keys.c | ✅ 完成 | HKDF-Expand-Label / Derive-Secret / 1.3 key schedule / 1.2 PRF / cipher_params |
| tls_extensions.c | ✅ 完成 | SNI/ALPN/key_share/supported_groups/sig_algos/supported_versions/renegotiation_info 编码+解析 |
| tls_handshake13.c | ✅ 完成 | TLS 1.3 client+server 状态机:ClientHello/ServerHello/EncryptedExtensions/Certificate/CertificateVerify/Finished (无 PSK/0-RTT) |
| tls_handshake12.c | ✅ 完成 | TLS 1.2 client+server 状态机:ServerHello/Certificate/ServerKeyExchange/CKE/CCS/Finished;含 1.3↔1.2 回退 |
| tls_client.c | ✅ 完成 | 客户端证书验证辅助:链验证+主机名匹配 |
| tls_server.c | ✅ 完成 | 服务端证书有效性检查 |
| tls_conn.c | ✅ 完成 | paze_tls_t 生命周期(new/free/set_bio/read/write/close/handshake) |
3.3 TLS 1.3 握手消息(关键编码,必须严格遵循 RFC 8446)
ClientHello
legacy_version(2)=0x0303, random(32), legacy_session_id(0..32),
cipher_suites(2+n), legacy_compression_methods(1+{0}), extensions(2+n)
EXT: supported_versions(客户端 0x0304/0x0303)
EXT: supported_groups(X25519 + secp256r1)
EXT: signature_algorithms(ecdsa_secp256r1_sha256 / rsa_pss_rsae_sha256 / rsa_pkcs1_sha256)
EXT: key_share(2+ (group 2 + len 2 + key_exchange) × N)
EXT: server_name(host_type=0)
EXT: application_layer_protocol_negotiation
EXT: renegotiation_info(空)
ServerHello(1.3):
legacy_version=0x0303, random, legacy_session_id_echo(同 CH),
cipher_suite, legacy_compression_method=0, extensions
EXT: supported_versions(选中 0x0304)
EXT: key_share(服务器选中的 share)
EncryptedExtensions: extensions(任意非握手相关)
Certificate [Request]:
request_context(0/1 bytes) + cert_list(证书序列)
CertificateEntry: cert_data(3+n) + extensions(2+n,含 status_request/OCSP)
CertificateVerify: algorithm(2) + signature(2+n)
签名内容: "TLS 1.3, server CertificateVerify" + 0x20 × 64 + 0x04 + Transcript-Hash
Finished: verify_data = HMAC(finished_key, Transcript-Hash)
3.4 关键 AEAD / Key Schedule 不变量
- TLS 1.3 nonce:
iv[0..11] XOR (00000000 || seq_be64),不重复使用。 - TLS 1.3 AAD:
type || 0x0303 || (plaintext_len+16)。 - TLS 1.2 AAD:
seq(8) || type || version || (明文长度),explicit nonce(8) 写在记录 body 开头,nonce =fixed_iv(4) || explicit_nonce(8)(RFC 5288 §3 GCMNonce),fixed_iv=key_material 中 write_IV(4 字节)。 - Transcript: 每次发送/收到握手消息后,连同 4 字节握手头一并 update。
- HRR 回退:调用
paze_tls_tr_reset_to_synthetic()重置 transcript 为MessageHash(Hash(CH1)),随后 HRR、CH2、SH… 追加其 后。 - PSS/RSA-PKCS1 签名:由
paze_rsa_pss_sign/paze_rsa_pkcs1_sign直接产出 signature 字节流。 - 证书链验证:调用
paze_x509_verify_chain(peer_chain[], chain_len, anchors[], anchor_count, now);之后paze_x509_match_host(leaf, sni)。
四、SSH 模块设计 (PazeSSH, ≤25,000 行)
4.1 协议栈(对应源文件)
┌──────────────────────────────────────────┐
│ apps/ssh / apps/sshd (CLI) │
├──────────────────────────────────────────┤
│ src/ssh/ssh_client.c / ssh_server.c │ ← 入口(connect/listen→accept→loop)
│ └── ssh_auth.c │ ← 用户认证(pubkey/password/hostbased)
│ └── ssh_channel.c │ ← 通道建立(session/shell/exec/pty)
│ └── ssh_kex.c │ ← 密钥交换 (curve25519-sha256@libssh.org,ecdh-sha2-nistp256)
│ └── ssh_transport.c │ ← 二进制包加密/解密、重加密、Mac/压缩、序号
│ └── ssh_packet.c │ ← 打包:uint32(长度) + padl(1) + payload + padding + mac
│ └── ssh_keys.c │ ← 主机键 RSA/Ed25519/ECDSA P256 加载+签名+验签
└──────────────────────────────────────────┘
4.2 密码学兼容性
- kex methods:
curve25519-sha256@libssh.org,ecdh-sha2-nistp256,diffie-hellman-group14-sha256(仅兼容,不建议启用) - host key algorithms:
ssh-ed25519,ecdsa-sha2-nistp256,rsa-sha2-512,rsa-sha2-256 - encryption:
chacha20-poly1305@openssh.com,aes128-gcm@openssh.com,aes256-gcm@openssh.com - MAC(非 AEAD):
hmac-sha2-256 - key format:
ssh-rsa / ssh-ed25519 / ecdsa-sha2-nistp256公钥格式 + PEM 私钥 - packet size:packet.c 中
uint32 block_size依 cipher 动态设置
4.3 行数分配建议
| 文件 | 预算 | 核心功能 | 状态 |
|---|---|---|---|
| ssh_packet.c | 600 | uint32 打包解包、padding、AEAD 加密/解密、序列号递增、mac 校验、Factory 函数 | ✅ |
| ssh_transport.c | 1,200 | 版本交换、KEXINIT 协商、算法名列表解析 | ✅ |
| ssh_keys.c | 1,500 | 主机键加载(PEM)、公钥 blob 格式、签名 verify/sign (Ed25519/ECDSA/RSA) | ✅ |
| ssh_kex.c | 1,800 | X25519/P-256 ECDH 交换、密钥派生(ChaCha20-Poly1305/256 bit keys)、NEWKEYS | ✅ |
| ssh_auth.c | 2,000 | USERAUTH_REQUEST/FAILURE/SUCCESS; password authentication | ✅ |
| ssh_channel.c | 2,500 | CHANNEL_OPEN/CONFIRM/DATA/REQUEST/CLOSE; session/shell/exec/pty-req | ✅ |
| ssh_client.c | 1,000 | TCP connect → transport_loop → auth → channel shell/exec | ✅ |
| ssh_server.c | 1,500 | listen → accept → transport → auth → channel pty+shell (echo 测试) | ✅ |
| 小计 | ≈ 12,100 | 全部 8 模块完成 | ✅ |
五、密码学原语清单(已完整实现,勿重复)
——哈希
paze_sha1, paze_sha256, paze_sha384, paze_sha512, paze_md5
通用描述符: paze_hash_sha256() 等 (含 digest_len/block_len/ctx_size/init/update/final)
——密钥派生
paze_hmac(alg, key, msg) / 流式 hmac_init/update/final
paze_hkdf_extract / expand / paze_hkdf
paze_pbkdf2
——对称 AEAD
paze_aes128/256_init + aesgcm_encrypt/decrypt (12 字节 nonce, 16 字节 tag)
paze_chacha20poly1305_encrypt/decrypt (RFC 8439, 12 字节 nonce, 32 字节 key)
AES ECB/CBC/CTR 模式(低层次,仅特殊场景用)
——椭圆曲线
curve25519: paze_curve25519_scalar_mult(pub, priv, basepoint_or_pubkey)
Ed25519: paze_ed25519_publickey / sign / verify (RFC 8032, SHA-512)
P-256: paze_p256_scalar_mult(R, k, P) / from_affine / to_affine / paze_ecdsa_sign / verify
——大整数 / RSA
paze_bn_t (最多 PAZE_BN_MAX_LIMBS 个 32-bit limb) 加减乘除 模 Montgomery 模幂 modexp
RSA: paze_rsa_pub_from_der / priv_from_pem?
paze_rsa_pkcs1_encrypt/decrypt/sign/verify
paze_rsa_pss_sign/verify
paze_rsa_gen(&priv, bits) —— 密钥生成(Miller-Rabin 素性检测)
——ASN.1 + X.509
paze_asn1_reader_t: enter_seq / read_tl / at_end / 基本类型 ASN1_* tag 常量
paze_x509_parse_der / parse_pem / free
paze_x509_verify_signature(cert, issuer)
paze_x509_verify_chain(chain[], chain_len, anchors[], anchor_count, now_unix_seconds)
paze_x509_check_validity / match_host(host) ← SAN dNSName 支持通配?不支持(严格)
paze_x509_make_self_signed(out, outlen, signer, CN, not_before, not_after) ← 测试用
——编码
paze_base64_encode/decode, paze_hex_encode/decode, paze_pem_encode/decode
六、跨平台 Socket + BIO 约定
6.1 apps 层的 BIO 构造(Windows + POSIX 同文件,用 #if _WIN32)
#ifdef _WIN32
#include <winsock2.h>
typedef SOCKET sock_t;
#define INVALID INVALID_SOCKET
#else
#include <unistd.h>
#include <sys/socket.h>
typedef int sock_t;
#define INVALID (-1)
#endif
static int sock_read(void *ctx, uint8_t *buf, size_t n) {
sock_t s = *(sock_t*)ctx;
return (int)recv(s, (char*)buf, (int)n, 0); // WIN/UNIX 同签名
}
static int sock_write(void *ctx, const uint8_t *buf, size_t n) {
sock_t s = *(sock_t*)ctx;
return (int)send(s, (char*)buf, (int)n, 0);
}
paze_tls_bio_t bio = { &sock, sock_read, sock_write };
paze_tls_set_bio(tls, bio);
6.2 错误码统一
PAZE_ERR_IO(-8): 底层 BIO 出错,不 retry。PAZE_ERR_VERIFY(-5): 验签失败 / record MAC 错误 / 证书不可信。PAZE_ERR_PROTOCOL(-10): 协议消息格式错误。- 其他负数按 paze_types.h。
七、构建系统
顶层 CMakeLists.txt 已规划静态库:
paze_crypto ← src/crypto + src/util
paze_ssl ← src/ssl/*.c (链接 paze_crypto)
paze_ssh ← src/ssh/*.c (链接 paze_crypto)
CLI: pazessl, paze-ssh, paze-sshd
TESTS: paze_kat (tests/kat.c)
构建命令 (Windows MinGW/GCC 或 MinGW-w64 / Unix GCC / Clang)
# Linux / macOS
mkdir -p build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc) && ctest
# Windows (MSVC)
mkdir build && cd build
cmake ..
cmake --build . --config Release && ctest -C Release
八、CLI 工具 (apps/)
pazessl (平替 openssl s_client / s_server / s_time / x509 / verify)
pazessl s_client -connect <host:port> [-CAfile roots.pem] [-servername SNI] [-alpn h2,http1.1]
pazessl s_server -accept <port> -cert cert.pem -key key.pem [-CAfile roots.pem]
pazessl verify -CAfile roots.pem cert.pem
pazessl x509 -in cert.pem [-text] [-noout]
pazessl s_time -connect <host:port> [-seconds 10]
pazessl genrsa -out key.pem [2048|4096]
pazessl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -subj /CN=test
paze-ssh (平替 ssh)
paze-ssh [-p port] [-i key.pem] [-l user] host [command]
paze-sshd (平替 sshd)
paze-sshd -p 22 -h host_key_ed25519.pem [-h host_key_rsa.pem] \
-f authorized_keys_dir # 目录下 $user/.ssh/authorized_keys
九、统一 KAT 测试 (tests/kat.c)
paze_kat 二进制须全部通过,作为 CI 门禁。
int main(void) {
int ok = 1;
ok &= test_sha2_vectors(); // NIST 向量
ok &= test_aes_gcm_vectors(); // NIST SP 800-38D
ok &= test_chacha20_poly(); // RFC 8439
ok &= test_rsa_2048_roundtrip();
ok &= test_ecdsa_p256_kat();
ok &= test_ed25519_rfc8032();
ok &= test_x25519_rfc7748();
ok &= test_hkdf_rfc5869();
ok &= test_pbkdf2_rfc6070();
ok &= test_x509_self_rsa();
ok &= test_x509_self_ecdsa();
ok &= test_tls13_self_handshake(); // ← 新: 内建回环测试
ok &= test_ssh_kex_loopback(); // ← 新
printf("KAT %s\n", ok ? "PASS" : "FAIL");
return ok ? 0 : 1;
}
十、遗留 TO-DO(完成顺序)
按依赖顺序:TLS extensions → handshake13 → conn → tests → SSH 全部 → CLI → verify
- ✅ 密码学原语 + X.509
- ✅ tls.h + tls_internal.h
- ✅ tls_bio / tls_record / tls_transcript / tls_keys
- ✅ tls_extensions (write + parse)
- ✅ tls_handshake13 (客户端 + 服务端状态机,无 PSK/0-RTT/HRR 实际数据)
- ✅ tls_client / tls_server / tls_conn (握手入口、证书验证、连接 API、应用读写)
- ✅ SSH 全部 (ssh_packet/transport/kex/keys/auth/channel/client/server)
- ✅ apps/ (pazessl s_client/s_server/verify/genrsa/req/x509 + paze-ssh + paze-sshd)
- ✅ tests/kat.c (SHA-256/X25519/Ed25519/RSA/X.509/TLS/SSH 测试)
- ✅ 全量构建:所有 3 个静态库 + 4 个 CLI 程序 + 12 个测试程序通过编译
遗留问题 (pre-existing, 非本次引入)
- ✅ tls_handshake12 (TLS 1.2 回退,ECDHE-RSA/ECDSA/RSA AES-GCM + CHACHA20-POLY1305;OpenSSL s_client/s_server 双向 1.2 互操作通过)
- 🔶 X.509 self-signed 证书解析 — RSA 部分已修复(X.509 SPKI 外层 SEQUENCE 缺失问题), ECDSA 仍失败(p256_from_affine 曲线点验证不通过)
- ⬜ X25519 ECDH 共享密钥不一致 (RFC 7748 标准测试向量不通过)
- ✅ SSH 密钥解析 — paze_rsa_priv_from_pem / paze_ecdsa_priv_from_pem 已实现, tls_conn 私钥加载已更新
- ⬜ TLS 1.3 密钥派生重放 (服务端收到 ClientHello 时若 cipher=SHA-384 需要重放 CH 到新 transcript,SHA-256 已覆盖)
- ⬜ 最终验证:全量
cloc/wc -l统计 + 所有 KAT 通过 + TLS 1.3 对公网 TLS 1.3 服务器握手测试
2026-08-11 新增功能
- ✅ paze_x509_build_spki 修复:AlgorithmIdentifier + BIT STRING 现包裹在外层 SEQUENCE 中
- ✅ paze_rsa_priv_from_pem / paze_rsa_pub_from_pem — RSA 密钥 PEM 加载
- ✅ paze_ecdsa_priv_from_pem / paze_ecdsa_pub_from_pem — ECDSA 密钥 PEM 加载 (RFC 5915)
- ✅ 多证书链 PEM 加载 (build_cert_chain_from_pem 支持多段)
- ✅ 多信任锚 PEM 加载 (paze_tls_config_set_trust_roots 支持多根证书)
十一、安全编码原则
- 常量时间:
- 密钥 / IV / padding 比较必须走
paze_memzero或paze_ct_equal。 - RSA PKCS1-v1_5 解密必须用累积 diff 而非早退(已在 rsa.c 中实现)。
- 密钥 / IV / padding 比较必须走
- 缓冲区边界:每个
memcpy前必须显式校验长度,不得假设rlen ≤ MAX_RECORD。 - 序列号溢出:若
seq == UINT64_MAX - 1(实际上不会到),需发 KeyUpdate 或关连接。 - 错误信息:不得泄漏内部状态;对外仅返回状态码,调试信息只写入
paze_log(DEBUG)。 - 内存清零:所有密钥材料(handshake_secret/master_secret/private keys)使用完毕后
paze_memzero。 - RSA PKCS1 长度校验:验签前严格重构 expected EM,整段常量时间比较(rsa.c 已如此实现)。
十二、引用
- TLS 1.3 — RFC 8446
- TLS 1.2 — RFC 5246
- AES-GCM — NIST SP 800-38D
- ChaCha20-Poly1305 — RFC 8439
- HKDF — RFC 5869
- X.509 & PKIX — RFC 5280
- SSH 协议族 — RFC 4250~4256
所有代码一定要能移植到裸机上!
十三、构建命令(已验证)
# Windows (Clang/MinGW via CMake):
mkdir build && cd build
cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_FLAGS="-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -D_WINSOCK_DEPRECATED_NO_WARNINGS"
make -j$(nproc)
# 运行测试
./paze_kat.exe
ctest
# Linux / macOS
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc) && ctest
注意: Windows 上需要 -D_CRT_SECURE_NO_WARNINGS 等宏以抑制 MSVC 运行时对 strcpy/strdup/gethostbyname 的废弃警告。
src/crypto/fe25519.c已在 CMakeLists.txt 中(2026-08-11 补充,原遗漏)strcasecmp在 Windows 上为_stricmp,已在tests/bn_check.c添加 compat 宏
十四、现有代码行数统计 (2026-08-12)
全量统计 src/ + include/ + apps/ + tests/ 下 *.c/*.h(93 + 18 = 111 个文件):
| 目录 | 行数 | 说明 |
|---|---|---|
| src/crypto | 4,938 | 哈希/AES/ChaCha20/曲线/RSA/X.509/ASN.1 |
| src/ssh | 3,779 | packet/transport/kex/keys/auth/channel/client/server/scp/agent |
| src/ssl | 2,328 | TLS 1.3 握手/记录/密钥派生 |
| include/paze | 1,453 | 公共头 |
| src/util | 77 | mem/error/log/version |
| include | 42 | 顶层头 |
| apps | 1,839 | pssh(8 子命令) + pazessl |
| tests | 1,688 | KAT 测试 |
| 合计 | 16,144 | 预算 ≤ 100,000,剩余 83,856 |
十五、pssh 与 OpenSSH 对比
命令对应
| OpenSSH | pssh | 说明 |
|---|---|---|
ssh |
pssh(默认)/ pssh ssh |
远程 shell / 执行命令 |
scp |
pssh scp |
文件传输(SFTP 子系统优先,兼容 OpenSSH 9.x;回退 legacy SCP) |
sftp |
pssh sshd 子系统 |
服务端 SFTP 子系统 v3,与 OpenSSH sftp/scp -s 互操作 |
ssh-keygen |
pssh keygen |
密钥生成(ed25519/rsa/ecdsa) |
ssh-keyscan |
pssh keyscan |
主机密钥扫描(known_hosts 格式) |
ssh-copy-id |
pssh copy-id |
安装公钥到 authorized_keys |
ssh-agent |
pssh agent |
agent 守护进程 |
ssh-add |
pssh add / pssh ssha |
agent 密钥管理 |
sshd |
pssh sshd |
SSH 服务器(多用户库 + 权限控制) |
认证与加密算法
| 项目 | OpenSSH | pssh |
|---|---|---|
| 密码认证 | ✓ | ✓(交互 * 掩码 / -pwd) |
| publickey 认证 | ✓ | ✓(-i 私钥 + agent 签名) |
| agent 代理认证 | ✓ | ✓(Windows 命名管道 \\.\pipe\openssh-ssh-agent) |
| 密钥交换 | curve25519/ECDH/DH/sntrup761 等 | curve25519-sha256@libssh.org(X25519) |
| 主机密钥 | ed25519/rsa/ecdsa/dsa | ed25519/rsa/ecdsa |
| 加密算法 | chacha20-poly1305、aes*-ctr、aes*-gcm 等 | chacha20-poly1305@openssh.com、aes128/256-gcm@openssh.com |
| 私钥格式 | openssh-key-v1(可 passphrase 加密) | openssh-key-v1(无加密) |
| 私钥指纹 | SHA256/MD5 | SHA256 |
功能对比
| 功能 | OpenSSH | pssh |
|---|---|---|
| 交互 shell + 方向键历史 | ✓ | ✓(UTF-8 中文正常) |
| 远程执行命令 | ✓ | ✓ |
| known_hosts 校验 | ✓(yes/no/accept-new) | ✓(同) |
| SCP 协议 | legacy + SFTP 模式(9.x 默认) | 仅 legacy SCP |
递归目录传输 -r |
✓ | ✓ |
保留时间戳 -p |
✓ | ✓ |
端口转发 -L/-R |
✓ | ✓(实测 HTTP 200) |
动态转发/SOCKS5 -D |
✓ | ✓(实测代理 HTTP 200) |
代理跳转 -J |
✓ | ✓(多级跳转 + 退出码透传) |
| config 文件 | ✓(~/.ssh/config) |
✓(~/.pssh/config.conf) |
| 服务器端 | 完整(用户库/子系统/authorized_keys) | 多用户库 + 分级权限(guest/user/admin) + authorized_keys 公钥认证 |
| 服务器端 exec/shell | ✓ | ✓(真正执行本地命令,stdout/stderr/exit-status 回传) |
| 服务器端 direct-tcpip | ✓ | ✓(出站连接 + 双向中继,需 admin 权限) |
主要差距(后续建议)
- 私钥 passphrase 加密(openssh-key-v1 AES 加密段)