• src/ssh/kex/dh-gex-sha256

    From Deuc¿@VERT to Git commit to main/sbbs/m on Monday, March 23, 2026 20:49:00
    https://gitlab.synchro.net/main/sbbs/-/commit/a06e7e2cb45f81116329b146
    Modified Files:
    src/ssh/kex/dh-gex-sha256.c src/ssh/ssh-internal.h ssh-trans.c src/ssh/test/dssh_test_internal.h test_transport.c
    Log Message:
    Expose version_tx, parse_bn_mpint, dh_value_valid for testing; add 12 tests

    Move DSSH_TESTABLE macro definition from ssh-trans.c to ssh-internal.h
    so all library source files can use it.

    Expose three static functions via DSSH_TESTABLE:
    - version_tx (ssh-trans.c): sends the SSH version identification line
    - parse_bn_mpint (dh-gex-sha256.c): parses an mpint from wire format
    - dh_value_valid (dh-gex-sha256.c): validates DH e/f in [1, p-1]

    Add test accessors dssh_test_set_sw_version/set_version_comment to
    bypass set_version validation for defense-in-depth testing.

    New tests:
    - version_tx TOOLONG with oversized version string
    - version_tx TOOLONG with oversized comment
    - parse_bn_mpint: valid, short header, truncated data
    - dh_value_valid: zero, negative, equal to p, greater than p,
    valid interior, boundary values (1 and p-1)

    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Tuesday, March 24, 2026 20:58:00
    https://gitlab.synchro.net/main/sbbs/-/commit/c0bcf664ecd60723b2ff6b48
    Modified Files:
    src/ssh/kex/dh-gex-sha256.c src/ssh/test/dssh_test_internal.h test_transport.c
    Log Message:
    Add unit tests for formerly-guarded paths

    Tests for code paths that were previously hidden behind
    #ifndef DSSH_TESTING guards:

    - guard/rekey_time_zero: rekey_needed returns false when rekey_time==0
    - guard/blocksize_lt8: enc module with blocksize=1 (clamped to 8)
    - guard/ed25519_sign_small_buf: sign with 4-byte buffer  TOOLONG
    - guard/ed25519_pubkey_small_buf: pubkey with 4-byte buffer  TOOLONG
    - guard/rsa_sign_small_buf: sign with 4-byte buffer  TOOLONG
    - guard/rsa_pubkey_small_buf: pubkey with 4-byte buffer  TOOLONG
    - guard/bn_mpint_small_buf: serialize_bn_mpint with 4-byte buffer  TOOLONG

    Expose serialize_bn_mpint as DSSH_TESTABLE for direct testing.

    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Tuesday, March 24, 2026 20:58:00
    https://gitlab.synchro.net/main/sbbs/-/commit/90c0fe97d40e233d74210d18
    Modified Files:
    src/ssh/kex/dh-gex-sha256.c src/ssh/test/dssh_test_internal.h dssh_test_ossl.c dssh_test_ossl.h test_alloc.c test_transport.c
    Log Message:
    DH-GEX coverage: thread-local ossl filter, client iterate, server tests

    Add per-thread ossl injection filter: _Thread_local ossl_this_thread
    defaults to true (all threads participate, backward compatible). dssh_test_ossl_exclude_thread() lets a thread opt out so its ossl
    calls pass straight through without incrementing the counter. This
    enables two-threaded KEX tests where only one side is injected.

    ossl/kex_client iterate: two-threaded DH-GEX with the server thread
    excluded from injection. Covers all client-side ossl failure paths (BN_CTX_new, BN_new, BN_rand, BN_mod_exp, EVP_Digest*, verify).

    DH-GEX server targeted tests (10 tests in test_transport.c):
    - NULL pubkey/sign function pointers
    - recv failure (no packets / partial packets)
    - wrong msg_type for GEX_REQUEST and GEX_INIT
    - short GEX_REQUEST payload
    - NULL provider / provider returning error
    - invalid e value (e=0)

    DH-GEX helper tests (3 tests in test_transport.c):
    - serialize_bn_mpint malloc failure via alloc injection
    - serialize_bn_mpint with BN value 0 (bn_bytes == 0 branch)
    - compute_exchange_hash alloc iterate (serialize_bn_mpint mres
    failures covering all 5 ok && (mres == 0) False branches)

    Source cleanup in dh-gex-sha256.c:
    - parse_bn_mpint: wrap dead dssh_parse_uint32 check in
    #ifndef DSSH_TESTING (matching ssh-arch.c pattern)
    - compute_exchange_hash: fold int ok = EVP_DigestInit_ex(...)
    to eliminate dead ok && short-circuit on first use
    - compute_exchange_hash made DSSH_TESTABLE for direct testing

    DH-GEX branch coverage: 78.52%  90.80% (55  23 missed).
    Overall: 83.56%  85.71% (414  359 missed).

    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Tuesday, March 24, 2026 20:58:00
    https://gitlab.synchro.net/main/sbbs/-/commit/405365deef5dbd0cfaadcde4
    Modified Files:
    src/ssh/kex/dh-gex-sha256.c src/ssh/test/dssh_test_alloc.c dssh_test_alloc.h test_alloc.c test_transport.c
    Log Message:
    dh-gex-sha256.c: 100% branch coverage

    Thread-local alloc injection: add dssh_test_alloc_exclude_thread()
    matching the ossl pattern, so server threads can opt out of library
    malloc failure injection during two-threaded KEX tests.

    alloc/kex_server iterate: single-threaded server KEX with library
    alloc injection via dssh_test_alloc_fail_after(). Covers malloc
    failures in serialize_bn_mpint, shared_secret, reply buffer, and
    exchange_hash on the server path.

    alloc/kex_client iterate: two-threaded KEX with server excluded
    from alloc injection. Covers client-side malloc failures.

    Client ka guard tests: two-threaded KEX with client's
    key_algo_selected set to NULL or stub with NULL verify.

    Client parse tests (7 tests via bad-server threads):
    - recv GROUP failure (server closes before sending)
    - GEX_GROUP empty / missing g
    - GEX_REPLY wrong msg_type
    - GEX_REPLY too short for K_S / K_S overrun
    - GEX_REPLY f=0 (invalid DH value)
    - GEX_REPLY too short for sig / sig overrun

    Server ka==NULL targeted test.

    Source cleanup: break client-side K_S and sig parse chains out of
    || expressions, guard dead dssh_parse_uint32 checks with
    #ifndef DSSH_TESTING (same pattern as parse_bn_mpint line 60).

    Result: dh-gex-sha256.c 246/246 branches covered (100.00%).

    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Thursday, April 23, 2026 18:36:00
    https://gitlab.synchro.net/main/sbbs/-/commit/7ef8523720fab936c3da6e86
    Modified Files:
    src/ssh/kex/dh-gex-sha256.c src/ssh/test/test_alloc.c
    Log Message:
    DeuceSSH: reject weak DH-GEX groups below client_min

    The client sends GEX_REQUEST(min=2048, n=4096, max=8192) but never
    verified the bit-length of the server-provided p in GEX_GROUP. RFC
    4419 3 only SHOULDs that the server honor min; a hostile or
    misconfigured server could downgrade to, say, a 768-bit group and the
    client would complete the handshake, deriving session keys over a
    Logjam-scale weak group before the host-key signature is checked.

    Add a backend-neutral bit-length check in dhgex_client() before ops->client_keygen(), so both the OpenSSL and Botan backends benefit
    from a single fix. Introduce a small mpint_bits() helper that walks
    past the at-most-one 0x00 sign-pad byte and counts the remaining bits.
    Reject with DSSH_ERROR_INVALID when |p| < client_min.

    New negative test test_dhgex_client_group_too_small feeds a 768-bit p
    through the existing bad_server_group_thread harness and confirms the
    client rejects.

    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net