ssh2_dh_secret() in the Windows CNG backend uses the server's
Diffie-Hellman public value f without the range check the other four
backends apply through ssh2_dh_validate(), so a malicious server can
send f of 0, 1 or p-1 and push the shared secret into a trivial subgroup
that openssl, libgcrypt, mbedtls and os400qc3 all reject with
LIBSSH2_ERROR_PROTO. This adds a WinCNG ssh2_dh_validate() that enforces
1 < f < p-1 and the same minimum-set-bits check on the big-endian value,
and calls it at the top of ssh2_dh_secret() like the other backends do.
The shared test_ssh2_dh_validate() in tests/test_simple.c was stubbed
out on WinCNG only because the function did not exist, so it now runs
against the real implementation too.
Reported-by: yaotushaozhu on github
Ref: GHSA-m9rg-h9jv-9gvh
Follow-up to fcf830788d#2239Closes#2645