From 049043127209a4a1846a1c0fcc56eff601c41be2 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Fri, 30 Dec 2016 11:26:39 +0000 Subject: [PATCH] Verify that the sig algs extension has been sent for TLSv1.3 Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/2157) --- include/openssl/ssl.h | 3 +++ include/openssl/tls1.h | 2 ++ ssl/ssl_err.c | 3 +++ ssl/ssl_locl.h | 1 + ssl/statem/extensions.c | 14 +++++++++++++- ssl/t1_lib.c | 2 +- ssl/tls13_enc.c | 8 ++++++++ test/tls13secretstest.c | 5 +++++ 8 files changed, 36 insertions(+), 2 deletions(-) diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index c6001c005d..2f6d59a05e 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -985,6 +985,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) # define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR # define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED # define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION +# define SSL_AD_MISSING_EXTENSION TLS13_AD_MISSING_EXTENSION # define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION # define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE # define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME @@ -2077,6 +2078,7 @@ int ERR_load_SSL_strings(void); # define SSL_F_FINAL_EC_PT_FORMATS 485 # define SSL_F_FINAL_EMS 486 # define SSL_F_FINAL_RENEGOTIATE 483 +# define SSL_F_FINAL_SIG_ALGS 497 # define SSL_F_OPENSSL_INIT_SSL 342 # define SSL_F_OSSL_STATEM_CLIENT13_READ_TRANSITION 436 # define SSL_F_OSSL_STATEM_CLIENT_CONSTRUCT_MESSAGE 430 @@ -2446,6 +2448,7 @@ int ERR_load_SSL_strings(void); # define SSL_R_MISSING_RSA_CERTIFICATE 168 # define SSL_R_MISSING_RSA_ENCRYPTING_CERT 169 # define SSL_R_MISSING_RSA_SIGNING_CERT 170 +# define SSL_R_MISSING_SIGALGS_EXTENSION 112 # define SSL_R_MISSING_SRP_PARAM 358 # define SSL_R_MISSING_TMP_DH_KEY 171 # define SSL_R_MISSING_TMP_ECDH_KEY 311 diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h index b2d3057304..707fb96054 100644 --- a/include/openssl/tls1.h +++ b/include/openssl/tls1.h @@ -103,6 +103,8 @@ extern "C" { # define TLS1_AD_INAPPROPRIATE_FALLBACK 86/* fatal */ # define TLS1_AD_USER_CANCELLED 90 # define TLS1_AD_NO_RENEGOTIATION 100 +/* TLSv1.3 alerts */ +# define TLS13_AD_MISSING_EXTENSION 109 /* fatal */ /* codes 110-114 are from RFC3546 */ # define TLS1_AD_UNSUPPORTED_EXTENSION 110 # define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111 diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 9f075e79cf..79cbf2ea60 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -52,6 +52,7 @@ static ERR_STRING_DATA SSL_str_functs[] = { {ERR_FUNC(SSL_F_FINAL_EC_PT_FORMATS), "final_ec_pt_formats"}, {ERR_FUNC(SSL_F_FINAL_EMS), "final_ems"}, {ERR_FUNC(SSL_F_FINAL_RENEGOTIATE), "final_renegotiate"}, + {ERR_FUNC(SSL_F_FINAL_SIG_ALGS), "final_sig_algs"}, {ERR_FUNC(SSL_F_OPENSSL_INIT_SSL), "OPENSSL_init_ssl"}, {ERR_FUNC(SSL_F_OSSL_STATEM_CLIENT13_READ_TRANSITION), "ossl_statem_client13_read_transition"}, @@ -565,6 +566,8 @@ static ERR_STRING_DATA SSL_str_reasons[] = { {ERR_REASON(SSL_R_MISSING_RSA_ENCRYPTING_CERT), "missing rsa encrypting cert"}, {ERR_REASON(SSL_R_MISSING_RSA_SIGNING_CERT), "missing rsa signing cert"}, + {ERR_REASON(SSL_R_MISSING_SIGALGS_EXTENSION), + "missing sigalgs extension"}, {ERR_REASON(SSL_R_MISSING_SRP_PARAM), "can't find SRP server param"}, {ERR_REASON(SSL_R_MISSING_TMP_DH_KEY), "missing tmp dh key"}, {ERR_REASON(SSL_R_MISSING_TMP_ECDH_KEY), "missing tmp ecdh key"}, diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 8186a7f5ba..efb03e2129 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -2102,6 +2102,7 @@ __owur int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, const unsigned char *p, size_t plen, int use_context); __owur int tls1_alert_code(int code); +__owur int tls13_alert_code(int code); __owur int ssl3_alert_code(int code); __owur int ssl_ok(SSL *s); diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index a68dd48835..4f54c3f771 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -38,6 +38,7 @@ static int final_ems(SSL *s, unsigned int context, int sent, int *al); #ifndef OPENSSL_NO_SRTP static int init_srtp(SSL *s, unsigned int context); #endif +static int final_sig_algs(SSL *s, unsigned int context, int sent, int *al); /* Structure to define a built-in extension */ typedef struct extensions_definition_st { @@ -152,7 +153,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { TLSEXT_TYPE_signature_algorithms, EXT_CLIENT_HELLO, init_sig_algs, tls_parse_ctos_sig_algs, NULL, NULL, - tls_construct_ctos_sig_algs, NULL + tls_construct_ctos_sig_algs, final_sig_algs }, #ifndef OPENSSL_NO_OCSP { @@ -926,3 +927,14 @@ static int init_srtp(SSL *s, unsigned int context) return 1; } #endif + +static int final_sig_algs(SSL *s, unsigned int context, int sent, int *al) +{ + if (!sent && SSL_IS_TLS13(s)) { + *al = TLS13_AD_MISSING_EXTENSION; + SSLerr(SSL_F_FINAL_SIG_ALGS, SSL_R_MISSING_SIGALGS_EXTENSION); + return 0; + } + + return 1; +} diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index da5797228a..dd25934e67 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -85,7 +85,7 @@ SSL3_ENC_METHOD const TLSv1_3_enc_data = { tls13_final_finish_mac, TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, - tls1_alert_code, + tls13_alert_code, tls1_export_keying_material, SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF, ssl3_set_handshake_header, diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c index 7ee9bb8ca3..449e6f9f36 100644 --- a/ssl/tls13_enc.c +++ b/ssl/tls13_enc.c @@ -406,3 +406,11 @@ int tls13_change_cipher_state(SSL *s, int which) OPENSSL_cleanse(key, sizeof(key)); return ret; } + +int tls13_alert_code(int code) +{ + if (code == SSL_AD_MISSING_EXTENSION) + return code; + + return tls1_alert_code(code); +} diff --git a/test/tls13secretstest.c b/test/tls13secretstest.c index 93b6e44257..68ebb9b8a7 100644 --- a/test/tls13secretstest.c +++ b/test/tls13secretstest.c @@ -179,6 +179,11 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, return 0; } +int tls1_alert_code(int code) +{ + return code; +} + /* End of mocked out code */ static int test_secret(SSL *s, unsigned char *prk,