From f127b8aa28b7602a6572ae26e45b5b7ebe36d8d3 Mon Sep 17 00:00:00 2001 From: Daniel Fiala Date: Tue, 24 May 2022 15:11:58 +0200 Subject: Convert serverinfo in SSL_CTX_use_serverinfo() to v2. Fixes openssl#18183. Reviewed-by: Matt Caswell Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/18614) (cherry picked from commit 555dd9390ba56f1c400d3f067a2dfe7b00fbf7d3) --- ssl/ssl_rsa.c | 81 +++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 21 deletions(-) (limited to 'ssl') diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c index 69c7bc2f9d..4f45e60535 100644 --- a/ssl/ssl_rsa.c +++ b/ssl/ssl_rsa.c @@ -703,16 +703,68 @@ static int serverinfo_process_buffer(unsigned int version, return 1; } +static size_t extension_contextoff(unsigned int version) +{ + return version == SSL_SERVERINFOV1 ? 4 : 0; +} + +static size_t extension_append_length(unsigned int version, size_t extension_length) +{ + return extension_length + extension_contextoff(version); +} + +static void extension_append(unsigned int version, + const unsigned char *extension, + const size_t extension_length, + unsigned char *serverinfo) +{ + const size_t contextoff = extension_contextoff(version); + + if (contextoff > 0) { + /* We know this only uses the last 2 bytes */ + serverinfo[0] = 0; + serverinfo[1] = 0; + serverinfo[2] = (SYNTHV1CONTEXT >> 8) & 0xff; + serverinfo[3] = SYNTHV1CONTEXT & 0xff; + } + + memcpy(serverinfo + contextoff, extension, extension_length); +} + int SSL_CTX_use_serverinfo_ex(SSL_CTX *ctx, unsigned int version, const unsigned char *serverinfo, size_t serverinfo_length) { - unsigned char *new_serverinfo; + unsigned char *new_serverinfo = NULL; if (ctx == NULL || serverinfo == NULL || serverinfo_length == 0) { ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } + if (version == SSL_SERVERINFOV1) { + /* + * Convert serverinfo version v1 to v2 and call yourself recursively + * over the converted serverinfo. + */ + const size_t sinfo_length = extension_append_length(SSL_SERVERINFOV1, + serverinfo_length); + unsigned char *sinfo; + int ret; + + sinfo = OPENSSL_malloc(sinfo_length); + if (sinfo == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + extension_append(SSL_SERVERINFOV1, serverinfo, serverinfo_length, sinfo); + + ret = SSL_CTX_use_serverinfo_ex(ctx, SSL_SERVERINFOV2, sinfo, + sinfo_length); + + OPENSSL_free(sinfo); + return ret; + } if (!serverinfo_process_buffer(version, serverinfo, serverinfo_length, NULL)) { ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_SERVERINFO_DATA); @@ -765,7 +817,7 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) unsigned int name_len; int ret = 0; BIO *bin = NULL; - size_t num_extensions = 0, contextoff = 0; + size_t num_extensions = 0; if (ctx == NULL || file == NULL) { ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); @@ -784,6 +836,7 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) for (num_extensions = 0;; num_extensions++) { unsigned int version; + size_t append_length; if (PEM_read_bio(bin, &name, &header, &extension, &extension_length) == 0) { @@ -826,11 +879,6 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) ERR_raise(ERR_LIB_SSL, SSL_R_BAD_DATA); goto end; } - /* - * File does not have a context value so we must take account of - * this later. - */ - contextoff = 4; } else { /* 8 byte header: 4 bytes context, 2 bytes type, 2 bytes len */ if (extension_length < 8 @@ -841,25 +889,16 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) } } /* Append the decoded extension to the serverinfo buffer */ - tmp = OPENSSL_realloc(serverinfo, serverinfo_length + extension_length - + contextoff); + append_length = extension_append_length(version, extension_length); + tmp = OPENSSL_realloc(serverinfo, serverinfo_length + append_length); if (tmp == NULL) { ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); goto end; } serverinfo = tmp; - if (contextoff > 0) { - unsigned char *sinfo = serverinfo + serverinfo_length; - - /* We know this only uses the last 2 bytes */ - sinfo[0] = 0; - sinfo[1] = 0; - sinfo[2] = (SYNTHV1CONTEXT >> 8) & 0xff; - sinfo[3] = SYNTHV1CONTEXT & 0xff; - } - memcpy(serverinfo + serverinfo_length + contextoff, - extension, extension_length); - serverinfo_length += extension_length + contextoff; + extension_append(version, extension, extension_length, + serverinfo + serverinfo_length); + serverinfo_length += append_length; OPENSSL_free(name); name = NULL; -- cgit v1.2.3