Commit 130b9414ad for openssl.org
commit 130b9414ad3000db6b8b4c3a7a468c8feff7e2bd
Author: Pauli <paul.dale@oracle.com>
Date: Tue Sep 1 15:34:05 2026 +1000
ssl: use generated parsers for TLS capabilities
Replace repeated OSSL_PARAM lookups for provider TLS groups and signature algorithms with generated trie decoders.
Assisted-by: ChatGPT:gpt-5.6Sol
Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Merge-date: Fri Oct 2 08:01:02 2026
Merged-from: https://github.com/openssl/openssl/pull/32621
diff --git a/.gitignore b/.gitignore
index 31efbf2b67..a929da336a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -98,6 +98,7 @@ providers/common/include/prov/der_sm2.h
providers/common/include/prov/der_ml_dsa.h
providers/common/include/prov/der_hkdf.h
providers/fips/fipsparams.inc
+ssl/t1_lib.inc
providers/implementations/asymciphers/rsa_enc.inc
providers/implementations/asymciphers/sm2_enc.inc
providers/implementations/exchange/dh_exch.inc
diff --git a/build.info b/build.info
index 710c47a2b3..a58317cf89 100644
--- a/build.info
+++ b/build.info
@@ -80,6 +80,7 @@ DEPEND[]=include/openssl/asn1.h \
include/crypto/dso_conf.h \
include/crypto/ec_params.h \
include/crypto/rsa_params.h \
+ ssl/t1_lib.inc \
providers/implementations/asymciphers/rsa_enc.inc \
providers/implementations/asymciphers/sm2_enc.inc \
providers/implementations/exchange/dh_exch.inc \
@@ -221,7 +222,8 @@ GENERATE[include/openssl/x509_acert.h]=include/openssl/x509_acert.h.in
GENERATE[include/openssl/x509_vfy.h]=include/openssl/x509_vfy.h.in
GENERATE[include/crypto/dso_conf.h]=include/crypto/dso_conf.h.in
-DEPEND[providers/implementations/asymciphers/rsa_enc.inc \
+DEPEND[ssl/t1_lib.inc \
+ providers/implementations/asymciphers/rsa_enc.inc \
providers/implementations/asymciphers/sm2_enc.inc \
providers/implementations/exchange/dh_exch.inc \
providers/implementations/exchange/ecdh_exch.inc \
@@ -330,6 +332,7 @@ GENERATE[include/crypto/ec_params.h]=\
include/crypto/ec_params.h.in
GENERATE[include/crypto/rsa_params.h]=\
include/crypto/rsa_params.h.in
+GENERATE[ssl/t1_lib.inc]=ssl/t1_lib.inc.in
GENERATE[providers/implementations/asymciphers/rsa_enc.inc]=\
providers/implementations/asymciphers/rsa_enc.inc.in
GENERATE[providers/implementations/asymciphers/sm2_enc.inc]=\
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index dacc0169fe..04d8ecb97b 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -28,6 +28,7 @@
#include "ssl_local.h"
#include "quic/quic_local.h"
#include <openssl/ct.h>
+#include "ssl/t1_lib.inc"
#define MAX_SIGALGS 128
@@ -233,6 +234,7 @@ static OSSL_CALLBACK add_provider_groups;
static int add_provider_groups(const OSSL_PARAM params[], void *data)
{
struct provider_ctx_data_st *pgd = data;
+ struct tls_group_params_st prms;
SSL_CTX *ctx = pgd->ctx;
const OSSL_PARAM *p;
TLS_GROUP_INFO *ginf = NULL;
@@ -241,6 +243,9 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data)
unsigned int is_kem = 0;
int ret = 0;
+ if (!tls_group_params_decoder(params, &prms))
+ return 0;
+
if (ctx->group_list_max_len == ctx->group_list_len) {
TLS_GROUP_INFO *tmp = NULL;
@@ -263,7 +268,7 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data)
ginf = &ctx->group_list[ctx->group_list_len];
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_NAME);
+ p = prms.name;
if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
@@ -272,7 +277,7 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data)
if (ginf->tlsname == NULL)
goto err;
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL);
+ p = prms.internal;
if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
@@ -281,14 +286,14 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data)
if (ginf->realname == NULL)
goto err;
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_ID);
+ p = prms.id;
if (p == NULL || !OSSL_PARAM_get_uint(p, &gid) || gid > UINT16_MAX) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
}
ginf->group_id = (uint16_t)gid;
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_ALG);
+ p = prms.alg;
if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
@@ -297,38 +302,38 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data)
if (ginf->algorithm == NULL)
goto err;
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS);
+ p = prms.secbits;
if (p == NULL || !OSSL_PARAM_get_uint(p, &ginf->secbits)) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
}
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_IS_KEM);
+ p = prms.is_kem;
if (p != NULL && (!OSSL_PARAM_get_uint(p, &is_kem) || is_kem > 1)) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
}
ginf->is_kem = 1 & is_kem;
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MIN_TLS);
+ p = prms.min_tls;
if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->mintls)) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
}
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MAX_TLS);
+ p = prms.max_tls;
if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->maxtls)) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
}
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS);
+ p = prms.min_dtls;
if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->mindtls)) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
}
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS);
+ p = prms.max_dtls;
if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->maxdtls)) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
@@ -400,6 +405,7 @@ static OSSL_CALLBACK add_provider_sigalgs;
static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
{
struct provider_ctx_data_st *pgd = data;
+ struct tls_sigalg_params_st prms;
SSL_CTX *ctx = pgd->ctx;
OSSL_PROVIDER *provider = pgd->provider;
const OSSL_PARAM *p;
@@ -409,6 +415,9 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
unsigned int code_point = 0;
int ret = 0;
+ if (!tls_sigalg_params_decoder(params, &prms))
+ return 0;
+
if (ctx->sigalg_list_max_len == ctx->sigalg_list_len) {
TLS_SIGALG_INFO *tmp = NULL;
@@ -431,7 +440,7 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
sinf = &ctx->sigalg_list[ctx->sigalg_list_len];
/* First, mandatory parameters */
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_NAME);
+ p = prms.name;
if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
@@ -441,7 +450,7 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
if (sinf->sigalg_name == NULL)
goto err;
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_IANA_NAME);
+ p = prms.iana_name;
if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
@@ -451,8 +460,7 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
if (sinf->name == NULL)
goto err;
- p = OSSL_PARAM_locate_const(params,
- OSSL_CAPABILITY_TLS_SIGALG_CODE_POINT);
+ p = prms.code_point;
if (p == NULL
|| !OSSL_PARAM_get_uint(p, &code_point)
|| code_point > UINT16_MAX) {
@@ -461,15 +469,14 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
}
sinf->code_point = (uint16_t)code_point;
- p = OSSL_PARAM_locate_const(params,
- OSSL_CAPABILITY_TLS_SIGALG_SECURITY_BITS);
+ p = prms.secbits;
if (p == NULL || !OSSL_PARAM_get_uint(p, &sinf->secbits)) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
}
/* Now, optional parameters */
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_OID);
+ p = prms.oid;
if (p == NULL) {
sinf->sigalg_oid = NULL;
} else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
@@ -481,7 +488,7 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
goto err;
}
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_SIG_NAME);
+ p = prms.sig_name;
if (p == NULL) {
sinf->sig_name = NULL;
} else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
@@ -493,7 +500,7 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
goto err;
}
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_SIG_OID);
+ p = prms.sig_oid;
if (p == NULL) {
sinf->sig_oid = NULL;
} else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
@@ -505,7 +512,7 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
goto err;
}
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_HASH_NAME);
+ p = prms.hash_name;
if (p == NULL) {
sinf->hash_name = NULL;
} else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
@@ -517,7 +524,7 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
goto err;
}
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_HASH_OID);
+ p = prms.hash_oid;
if (p == NULL) {
sinf->hash_oid = NULL;
} else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
@@ -529,7 +536,7 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
goto err;
}
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE);
+ p = prms.keytype;
if (p == NULL) {
sinf->keytype = NULL;
} else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
@@ -541,7 +548,7 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
goto err;
}
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE_OID);
+ p = prms.keytype_oid;
if (p == NULL) {
sinf->keytype_oid = NULL;
} else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
@@ -555,12 +562,12 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
/* Optional, not documented prior to 3.5 */
sinf->mindtls = sinf->maxdtls = -1;
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_MIN_DTLS);
+ p = prms.min_dtls;
if (p != NULL && !OSSL_PARAM_get_int(p, &sinf->mindtls)) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
}
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_MAX_DTLS);
+ p = prms.max_dtls;
if (p != NULL && !OSSL_PARAM_get_int(p, &sinf->maxdtls)) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
@@ -572,12 +579,12 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
}
/* The remaining parameters below are mandatory again */
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_MIN_TLS);
+ p = prms.min_tls;
if (p == NULL || !OSSL_PARAM_get_int(p, &sinf->mintls)) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
}
- p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS);
+ p = prms.max_tls;
if (p == NULL || !OSSL_PARAM_get_int(p, &sinf->maxtls)) {
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
goto err;
diff --git a/ssl/t1_lib.inc.in b/ssl/t1_lib.inc.in
new file mode 100644
index 0000000000..bde00d638e
--- /dev/null
+++ b/ssl/t1_lib.inc.in
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+{-
+use OpenSSL::paramnames qw(produce_param_decoder);
+
+sub produce_ssl_param_decoder {
+ my $decoder = produce_param_decoder(@_);
+
+ # Remove the unavailable header inclusion.
+ $decoder =~ s|#include "prov/proverr.h"||;
+ return $decoder;
+}
+-}
+
+/*
+ * There is no need to produce a list of gettables/settables because libssl
+ * doesn't support these query functions.
+ */
+#define tls_group_params_list
+#define tls_sigalg_params_list
+
+{- produce_ssl_param_decoder('tls_group_params',
+ (['OSSL_CAPABILITY_TLS_GROUP_NAME', 'name', 'utf8_string', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL', 'internal', 'utf8_string', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_GROUP_ID', 'id', 'uint', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_GROUP_ALG', 'alg', 'utf8_string', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS', 'secbits', 'uint', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_GROUP_IS_KEM', 'is_kem', 'uint', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_GROUP_MIN_TLS', 'min_tls', 'int', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_GROUP_MAX_TLS', 'max_tls', 'int', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS', 'min_dtls', 'int', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS', 'max_dtls', 'int', 'duplicate: first'],
+ )); -}
+
+{- produce_ssl_param_decoder('tls_sigalg_params',
+ (['OSSL_CAPABILITY_TLS_SIGALG_NAME', 'name', 'utf8_string', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_SIGALG_IANA_NAME', 'iana_name', 'utf8_string', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_SIGALG_CODE_POINT', 'code_point', 'uint', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_SIGALG_SECURITY_BITS', 'secbits', 'uint', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_SIGALG_OID', 'oid', 'utf8_string', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_SIGALG_SIG_NAME', 'sig_name', 'utf8_string', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_SIGALG_SIG_OID', 'sig_oid', 'utf8_string', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_SIGALG_HASH_NAME', 'hash_name', 'utf8_string', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_SIGALG_HASH_OID', 'hash_oid', 'utf8_string', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE', 'keytype', 'utf8_string', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE_OID', 'keytype_oid', 'utf8_string', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_SIGALG_MIN_DTLS', 'min_dtls', 'int', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_SIGALG_MAX_DTLS', 'max_dtls', 'int', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_SIGALG_MIN_TLS', 'min_tls', 'int', 'duplicate: first'],
+ ['OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS', 'max_tls', 'int', 'duplicate: first'],
+ )); -}