diff options
author | Matt Caswell <matt@openssl.org> | 2017-01-13 14:25:15 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2017-01-30 10:17:52 +0000 |
commit | be62b22b527e89061f88c0b9eaefb0410982f41e (patch) | |
tree | 62bdce920d7922a0d72f87cdbc487811a6fa8b78 /apps/s_client.c | |
parent | f05bcf0f4581664f429154cdb689faef242cf843 (diff) |
Update the s_client -sess_out feature to work for TLSv1.3
Previously "-sess_out" wrote out the session as soon as the handshake
finished. In TLSv1.3 this won't work because the NewSessionTicket message
arrives post-handshake. Instead we use the session callback mechanism to
do this.
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2259)
Diffstat (limited to 'apps/s_client.c')
-rw-r--r-- | apps/s_client.c | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/apps/s_client.c b/apps/s_client.c index d2f10a6885..362f005cc5 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -90,6 +90,7 @@ static char *keymatexportlabel = NULL; static int keymatexportlen = 20; static BIO *bio_c_out = NULL; static int c_quiet = 0; +static char *sess_out = NULL; static void print_stuff(BIO *berr, SSL *con, int full); #ifndef OPENSSL_NO_OCSP @@ -779,6 +780,24 @@ static void freeandcopy(char **dest, const char *source) *dest = OPENSSL_strdup(source); } +static int new_session_cb(SSL *S, SSL_SESSION *sess) +{ + BIO *stmp = BIO_new_file(sess_out, "w"); + + if (stmp != NULL) { + PEM_write_bio_SSL_SESSION(stmp, sess); + BIO_free(stmp); + } else { + BIO_printf(bio_err, "Error writing session file %s\n", sess_out); + } + + /* + * We always return a "fail" response so that the session gets freed again + * because we haven't used the reference. + */ + return 0; +} + int s_client_main(int argc, char **argv) { BIO *sbio; @@ -804,7 +823,7 @@ int s_client_main(int argc, char **argv) char *port = OPENSSL_strdup(PORT); char *inrand = NULL; char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL; - char *sess_in = NULL, *sess_out = NULL, *crl_file = NULL, *p; + char *sess_in = NULL, *crl_file = NULL, *p; char *xmpphost = NULL; const char *ehlo = "mail.example.com"; struct timeval timeout, *timeoutp; @@ -1674,6 +1693,17 @@ int s_client_main(int argc, char **argv) } } + /* + * In TLSv1.3 NewSessionTicket messages arrive after the handshake and can + * come at any time. Therefore we use a callback to write out the session + * when we know about it. This approach works for < TLSv1.3 as well. + */ + if (sess_out) { + SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT + | SSL_SESS_CACHE_NO_INTERNAL_STORE); + SSL_CTX_sess_set_new_cb(ctx, new_session_cb); + } + con = SSL_new(ctx); if (sess_in) { SSL_SESSION *sess; @@ -2168,15 +2198,6 @@ int s_client_main(int argc, char **argv) tlsextcbp.ack ? "" : "not "); } - if (sess_out) { - BIO *stmp = BIO_new_file(sess_out, "w"); - if (stmp) { - PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con)); - BIO_free(stmp); - } else - BIO_printf(bio_err, "Error writing session file %s\n", - sess_out); - } if (c_brief) { BIO_puts(bio_err, "CONNECTION ESTABLISHED\n"); print_ssl_summary(con); |