From 0247086d9a0713e18a0f16949039a40fdb63ff7e Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Wed, 18 Jan 2017 17:22:18 +0000 Subject: [PATCH] Implement server side of PSK extension construction Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/2259) --- include/openssl/ssl.h | 1 + ssl/s3_lib.c | 3 +++ ssl/ssl_err.c | 1 + ssl/statem/extensions.c | 2 +- ssl/statem/extensions_srvr.c | 29 ++++++++++++++++++++++++----- ssl/statem/statem_locl.h | 2 ++ 6 files changed, 32 insertions(+), 6 deletions(-) diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index af8878c6bd..e8f351dfc5 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -2315,6 +2315,7 @@ int ERR_load_SSL_strings(void); # define SSL_F_TLS_CONSTRUCT_STOC_KEY_EXCHANGE 377 # define SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE 456 # define SSL_F_TLS_CONSTRUCT_STOC_NEXT_PROTO_NEG 457 +# define SSL_F_TLS_CONSTRUCT_STOC_PSK 504 # define SSL_F_TLS_CONSTRUCT_STOC_RENEGOTIATE 458 # define SSL_F_TLS_CONSTRUCT_STOC_SERVER_NAME 459 # define SSL_F_TLS_CONSTRUCT_STOC_SESSION_TICKET 460 diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 6c74bd169d..35684f4790 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -4113,6 +4113,9 @@ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret) rv = tls13_generate_secret(s, ssl_handshake_md(s), NULL, NULL, 0, (unsigned char *)&s->early_secret); + else + rv = 1; + rv = rv && tls13_generate_handshake_secret(s, pms, pmslen); } else { /* Generate master secret and discard premaster */ diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 4047d0e27d..589cfa2e5f 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -355,6 +355,7 @@ static ERR_STRING_DATA SSL_str_functs[] = { "tls_construct_stoc_key_share"}, {ERR_FUNC(SSL_F_TLS_CONSTRUCT_STOC_NEXT_PROTO_NEG), "tls_construct_stoc_next_proto_neg"}, + {ERR_FUNC(SSL_F_TLS_CONSTRUCT_STOC_PSK), "tls_construct_stoc_psk"}, {ERR_FUNC(SSL_F_TLS_CONSTRUCT_STOC_RENEGOTIATE), "tls_construct_stoc_renegotiate"}, {ERR_FUNC(SSL_F_TLS_CONSTRUCT_STOC_SERVER_NAME), diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index 95bfe75393..c9e7d30eaa 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -279,7 +279,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { TLSEXT_TYPE_psk, EXT_CLIENT_HELLO | EXT_TLS1_3_SERVER_HELLO | EXT_TLS_IMPLEMENTATION_ONLY | EXT_TLS1_3_ONLY, - NULL, tls_parse_ctos_psk, tls_parse_stoc_psk, NULL, + NULL, tls_parse_ctos_psk, tls_parse_stoc_psk, tls_construct_stoc_psk, tls_construct_ctos_psk, NULL } }; diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 314cd5ad88..5a5d846e04 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -1006,12 +1006,14 @@ int tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx, size_t encoded_pt_len = 0; EVP_PKEY *ckey = s->s3->peer_tmp, *skey = NULL; - if (s->hit) - return 1; - if (ckey == NULL) { - SSLerr(SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, ERR_R_INTERNAL_ERROR); - return 0; + /* No key_share received from client, must be resuming. */ + if (!s->hit || !tls13_generate_handshake_secret(s, NULL, 0)) { + *al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, ERR_R_INTERNAL_ERROR); + return 0; + } + return 1; } if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share) @@ -1079,3 +1081,20 @@ int tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, X509 *x, return 1; } + +int tls_construct_stoc_psk(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx, + int *al) +{ + if (!s->hit) + return 1; + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_psk) + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_put_bytes_u16(pkt, s->session->ext.tick_identity) + || !WPACKET_close(pkt)) { + SSLerr(SSL_F_TLS_CONSTRUCT_STOC_PSK, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} diff --git a/ssl/statem/statem_locl.h b/ssl/statem/statem_locl.h index 8079f30a93..cb6457f587 100644 --- a/ssl/statem/statem_locl.h +++ b/ssl/statem/statem_locl.h @@ -247,6 +247,8 @@ int tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx, #define TLSEXT_TYPE_cryptopro_bug 0xfde8 int tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx, int *al); +int tls_construct_stoc_psk(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx, + int *al); /* Client Extension processing */ int tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt, X509 *x, -- 2.25.1