Hi,
When the netcat server should check the certificate hash of the
client, it always succeeds. So nc -c -H -l is always successful,
no matter what certificate the client provides.
The bug is that the TLS context of the listen socket is used instead
of the accepted connection.
Also I would like to fail if the user wants to validate a hash, but
there is none. The fail open logic prevented that the bug was
detected for a long time.
ok?
bluhm
Index: usr.bin/nc/netcat.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.bin/nc/netcat.c,v
retrieving revision 1.214
diff -u -p -r1.214 netcat.c
--- usr.bin/nc/netcat.c 6 Jan 2020 19:39:58 -0000 1.214
+++ usr.bin/nc/netcat.c 7 Jan 2020 14:10:51 -0000
@@ -835,8 +835,8 @@ tls_setup_client(struct tls *tls_ctx, in
}
if (vflag)
report_tls(tls_ctx, host);
- if (tls_expecthash && tls_peer_cert_hash(tls_ctx) &&
- strcmp(tls_expecthash, tls_peer_cert_hash(tls_ctx)) != 0)
+ if (tls_expecthash && (tls_peer_cert_hash(tls_ctx) == NULL ||
+ strcmp(tls_expecthash, tls_peer_cert_hash(tls_ctx)) != 0))
errx(1, "peer certificate is not %s", tls_expecthash);
if (Zflag) {
save_peer_cert(tls_ctx, Zflag);
@@ -864,8 +864,9 @@ tls_setup_server(struct tls *tls_ctx, in
report_tls(tls_cctx, host);
if ((TLSopt & TLS_CCERT) && !gotcert)
warnx("No client certificate provided");
- else if (gotcert && tls_peer_cert_hash(tls_ctx) &&
tls_expecthash &&
- strcmp(tls_expecthash, tls_peer_cert_hash(tls_ctx)) != 0)
+ else if (gotcert && tls_expecthash &&
+ (tls_peer_cert_hash(tls_cctx) == NULL ||
+ strcmp(tls_expecthash, tls_peer_cert_hash(tls_cctx)) != 0))
warnx("peer certificate is not %s", tls_expecthash);
else if (gotcert && tls_expectname &&
(!tls_peer_cert_contains_name(tls_cctx, tls_expectname)))