From 720b6cbe4a195fc5563be2334e8519a61b82eeef Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Thu, 1 Jun 2017 21:01:27 -0400 Subject: [PATCH] Avoid failing s_server when client's psk_identity is unexpected s_server has traditionally been very brittle in PSK mode. If the client offered any PSK identity other than "Client_identity" s_server would simply abort. This is breakage for breakage's sake, and unlike most other parts of s_server, which tend to allow more flexible connections. This change accomplishes two things: * when the client's psk_identity does *not* match the identity expected by the server, just warn, don't fail. * allow the server to expect instead a different psk_identity from the client besides "Client_identity" Signed-off-by: Daniel Kahn Gillmor Reviewed-by: Ben Kaduk Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/3605) --- apps/s_server.c | 18 ++++++++++++------ doc/man1/s_server.pod | 6 ++++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/apps/s_server.c b/apps/s_server.c index 815549b0c6..82fe5a4b74 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -149,7 +149,7 @@ static int dtlslisten = 0; static int early_data = 0; #ifndef OPENSSL_NO_PSK -static const char psk_identity[] = "Client_identity"; +static char *psk_identity = "Client_identity"; char *psk_key = NULL; /* by default PSK is not used */ static unsigned int psk_server_cb(SSL *ssl, const char *identity, @@ -171,12 +171,12 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity, /* here we could lookup the given identity e.g. from a database */ if (strcmp(identity, psk_identity) != 0) { - BIO_printf(bio_s_out, "PSK error: client identity not found" + BIO_printf(bio_s_out, "PSK warning: client identity not what we expected" " (got '%s' expected '%s')\n", identity, psk_identity); - goto out_err; - } - if (s_debug) + } else { + if (s_debug) BIO_printf(bio_s_out, "PSK client identity found\n"); + } /* convert the PSK key to binary */ key = OPENSSL_hexstr2buf(psk_key, &key_len); @@ -715,7 +715,7 @@ typedef enum OPTION_choice { OPT_STATUS_TIMEOUT, OPT_STATUS_URL, OPT_STATUS_FILE, OPT_MSG, OPT_MSGFILE, OPT_TRACE, OPT_SECURITY_DEBUG, OPT_SECURITY_DEBUG_VERBOSE, OPT_STATE, OPT_CRLF, OPT_QUIET, OPT_BRIEF, OPT_NO_DHE, - OPT_NO_RESUME_EPHEMERAL, OPT_PSK_HINT, OPT_PSK, OPT_SRPVFILE, + OPT_NO_RESUME_EPHEMERAL, OPT_PSK_IDENTITY, OPT_PSK_HINT, OPT_PSK, OPT_SRPVFILE, OPT_SRPUSERSEED, OPT_REV, OPT_WWW, OPT_UPPER_WWW, OPT_HTTP, OPT_ASYNC, OPT_SSL_CONFIG, OPT_MAX_SEND_FRAG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF, @@ -869,6 +869,7 @@ const OPTIONS s_server_options[] = { OPT_X_OPTIONS, {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, #ifndef OPENSSL_NO_PSK + {"psk_identity", OPT_PSK_IDENTITY, 's', "PSK identity to expect"}, {"psk_hint", OPT_PSK_HINT, 's', "PSK identity hint to use"}, {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"}, #endif @@ -1351,6 +1352,11 @@ int s_server_main(int argc, char *argv[]) case OPT_NO_RESUME_EPHEMERAL: no_resume_ephemeral = 1; break; + case OPT_PSK_IDENTITY: +#ifndef OPENSSL_NO_PSK + psk_identity = opt_arg(); +#endif + break; case OPT_PSK_HINT: #ifndef OPENSSL_NO_PSK psk_identity_hint = opt_arg(); diff --git a/doc/man1/s_server.pod b/doc/man1/s_server.pod index c3e763f4e0..b5245d8b4d 100644 --- a/doc/man1/s_server.pod +++ b/doc/man1/s_server.pod @@ -333,6 +333,12 @@ Inhibit printing of session and certificate information. Use the PSK identity hint B when using a PSK cipher suite. +=item B<-psk_identity identity> + +Expect the client to send PSK identity B when using a PSK +cipher suite, and warn if they do not. By default, the expected PSK +identity is the string "Client_identity". + =item B<-psk key> Use the PSK key B when using a PSK cipher suite. The key is -- 2.25.1