From f5b48604779362c91a22080b6905413fbba28b74 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Fri, 8 Mar 2024 11:18:12 +0100 Subject: [PATCH 49/49] 0119-provider-sigalgs-in-signaturealgorithms-conf.patch Patch-name: 0119-provider-sigalgs-in-signaturealgorithms-conf.patch Patch-id: 119 Patch-status: | # https://github.com/openssl/openssl/issues/22779 --- ssl/s3_lib.c | 8 ++++---- ssl/ssl_lib.c | 2 +- ssl/ssl_local.h | 2 +- ssl/t1_lib.c | 45 ++++++++++++++++++++++++++++++++++----------- 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index e8ec98c221..48a1aa0e61 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -3685,13 +3685,13 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) return tls1_set_sigalgs(sc->cert, parg, larg, 0); case SSL_CTRL_SET_SIGALGS_LIST: - return tls1_set_sigalgs_list(sc->cert, parg, 0); + return tls1_set_sigalgs_list(s->ctx, sc->cert, parg, 0); case SSL_CTRL_SET_CLIENT_SIGALGS: return tls1_set_sigalgs(sc->cert, parg, larg, 1); case SSL_CTRL_SET_CLIENT_SIGALGS_LIST: - return tls1_set_sigalgs_list(sc->cert, parg, 1); + return tls1_set_sigalgs_list(s->ctx, sc->cert, parg, 1); case SSL_CTRL_GET_CLIENT_CERT_TYPES: { @@ -3968,13 +3968,13 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) return tls1_set_sigalgs(ctx->cert, parg, larg, 0); case SSL_CTRL_SET_SIGALGS_LIST: - return tls1_set_sigalgs_list(ctx->cert, parg, 0); + return tls1_set_sigalgs_list(ctx, ctx->cert, parg, 0); case SSL_CTRL_SET_CLIENT_SIGALGS: return tls1_set_sigalgs(ctx->cert, parg, larg, 1); case SSL_CTRL_SET_CLIENT_SIGALGS_LIST: - return tls1_set_sigalgs_list(ctx->cert, parg, 1); + return tls1_set_sigalgs_list(ctx, ctx->cert, parg, 1); case SSL_CTRL_SET_CLIENT_CERT_TYPES: return ssl3_set_req_cert_type(ctx->cert, parg, larg); diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 1329841aaf..4d95ab71cd 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -3078,7 +3078,7 @@ long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) return tls1_set_groups_list(ctx, NULL, NULL, parg); case SSL_CTRL_SET_SIGALGS_LIST: case SSL_CTRL_SET_CLIENT_SIGALGS_LIST: - return tls1_set_sigalgs_list(NULL, parg, 0); + return tls1_set_sigalgs_list(ctx, NULL, parg, 0); default: return 0; } diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index 0d3acfbe66..a73b2c4770 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -2796,7 +2796,7 @@ __owur int tls_use_ticket(SSL_CONNECTION *s); void ssl_set_sig_mask(uint32_t *pmask_a, SSL_CONNECTION *s, int op); -__owur int tls1_set_sigalgs_list(CERT *c, const char *str, int client); +__owur int tls1_set_sigalgs_list(SSL_CTX *ctx, CERT *c, const char *str, int client); __owur int tls1_set_raw_sigalgs(CERT *c, const uint16_t *psigs, size_t salglen, int client); __owur int tls1_set_sigalgs(CERT *c, const int *salg, size_t salglen, diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index fe680449c5..87f2ae7000 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -716,6 +716,7 @@ int ssl_load_sigalgs(SSL_CTX *ctx) /* now populate ctx->ssl_cert_info */ if (ctx->sigalg_list_len > 0) { + OPENSSL_free(ctx->ssl_cert_info); ctx->ssl_cert_info = OPENSSL_zalloc(sizeof(lu) * ctx->sigalg_list_len); if (ctx->ssl_cert_info == NULL) return 0; @@ -2889,6 +2890,7 @@ typedef struct { size_t sigalgcnt; /* TLSEXT_SIGALG_XXX values */ uint16_t sigalgs[TLS_MAX_SIGALGCNT]; + SSL_CTX *ctx; } sig_cb_st; static void get_sigorhash(int *psig, int *phash, const char *str) @@ -2913,7 +2915,8 @@ static void get_sigorhash(int *psig, int *phash, const char *str) static int sig_cb(const char *elem, int len, void *arg) { sig_cb_st *sarg = arg; - size_t i; + size_t i = 0; + int load_success = 0; const SIGALG_LOOKUP *s; char etmp[TLS_MAX_SIGSTRING_LEN], *p; int sig_alg = NID_undef, hash_alg = NID_undef; @@ -2943,17 +2946,36 @@ static int sig_cb(const char *elem, int len, void *arg) * in the table. */ if (p == NULL) { - for (i = 0, s = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl); - i++, s++) { - if (s->name != NULL && strcmp(etmp, s->name) == 0) { - sarg->sigalgs[sarg->sigalgcnt++] = s->sigalg; - break; - } + /* Load provider sigalgs */ + if (sarg->ctx) { + load_success = ssl_load_sigalgs(sarg->ctx); } - if (i == OSSL_NELEM(sigalg_lookup_tbl)) { - /* Ignore unknown algorithms if ignore_unknown */ - return ignore_unknown; + if (load_success) { + /* Check if a provider supports the sigalg */ + for (i = 0; i < sarg->ctx->sigalg_list_len; i++) { + if (sarg->ctx->sigalg_list[i].sigalg_name != NULL + && strcmp(etmp, + sarg->ctx->sigalg_list[i].sigalg_name) == 0) { + sarg->sigalgs[sarg->sigalgcnt++] = + sarg->ctx->sigalg_list[i].code_point; + break; + } + } } + /* Check the built-in sigalgs */ + if (!sarg->ctx || !load_success || i == sarg->ctx->sigalg_list_len) { + for (i = 0, s = sigalg_lookup_tbl; + i < OSSL_NELEM(sigalg_lookup_tbl); i++, s++) { + if (s->name != NULL && strcmp(etmp, s->name) == 0) { + sarg->sigalgs[sarg->sigalgcnt++] = s->sigalg; + break; + } + } + if (i == OSSL_NELEM(sigalg_lookup_tbl)) { + /* Ignore unknown algorithms if ignore_unknown */ + return ignore_unknown; + } + } } else { *p = 0; p++; @@ -2992,10 +3014,11 @@ static int sig_cb(const char *elem, int len, void *arg) * Set supported signature algorithms based on a colon separated list of the * form sig+hash e.g. RSA+SHA512:DSA+SHA512 */ -int tls1_set_sigalgs_list(CERT *c, const char *str, int client) +int tls1_set_sigalgs_list(SSL_CTX *ctx, CERT *c, const char *str, int client) { sig_cb_st sig; sig.sigalgcnt = 0; + sig.ctx = ctx; if (!CONF_parse_list(str, ':', 1, sig_cb, &sig)) return 0; if (sig.sigalgcnt == 0) { -- 2.44.0