summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorMichael Baentsch <57787676+baentsch@users.noreply.github.com>2022-09-26 17:32:05 +0200
committerPauli <pauli@openssl.org>2023-02-24 11:02:48 +1100
commitee58915cfd9d0ad67f52d43cc1a2ce549049d248 (patch)
treee892900c53900bd693498bdc9ff2152ae14bcbe6 /ssl
parent1817dcaf556df559a32eed14d0947ff961be7b4f (diff)
first cut at sigalg loading
Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/19312)
Diffstat (limited to 'ssl')
-rw-r--r--ssl/s3_lib.c8
-rw-r--r--ssl/ssl_cert.c80
-rw-r--r--ssl/ssl_cert_table.h2
-rw-r--r--ssl/ssl_ciph.c17
-rw-r--r--ssl/ssl_lib.c46
-rw-r--r--ssl/ssl_local.h67
-rw-r--r--ssl/ssl_rsa.c22
-rw-r--r--ssl/statem/statem_clnt.c18
-rw-r--r--ssl/statem/statem_lib.c7
-rw-r--r--ssl/t1_lib.c428
10 files changed, 597 insertions, 98 deletions
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index e7078efa6c..17e318b857 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -3366,6 +3366,7 @@ void ssl3_free(SSL *s)
OPENSSL_clear_free(sc->s3.tmp.pms, sc->s3.tmp.pmslen);
OPENSSL_free(sc->s3.tmp.peer_sigalgs);
OPENSSL_free(sc->s3.tmp.peer_cert_sigalgs);
+ OPENSSL_free(sc->s3.tmp.valid_flags);
ssl3_free_digest_list(sc);
OPENSSL_free(sc->s3.alpn_selected);
OPENSSL_free(sc->s3.alpn_proposed);
@@ -3390,6 +3391,7 @@ int ssl3_clear(SSL *s)
OPENSSL_clear_free(sc->s3.tmp.pms, sc->s3.tmp.pmslen);
OPENSSL_free(sc->s3.tmp.peer_sigalgs);
OPENSSL_free(sc->s3.tmp.peer_cert_sigalgs);
+ OPENSSL_free(sc->s3.tmp.valid_flags);
EVP_PKEY_free(sc->s3.tmp.pkey);
EVP_PKEY_free(sc->s3.peer_tmp);
@@ -4244,7 +4246,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *cl
if (SSL_CONNECTION_IS_TLS13(s)) {
#ifndef OPENSSL_NO_PSK
- int j;
+ size_t j;
/*
* If we allow "old" style PSK callbacks, and we have no certificate (so
@@ -4254,8 +4256,8 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *cl
* that.
*/
if (s->psk_server_callback != NULL) {
- for (j = 0; j < SSL_PKEY_NUM && !ssl_has_cert(s, j); j++);
- if (j == SSL_PKEY_NUM) {
+ for (j = 0; j < s->ssl_pkey_num && !ssl_has_cert(s, j); j++);
+ if (j == s->ssl_pkey_num) {
/* There are no certificates */
prefer_sha256 = 1;
}
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index 320f6d322e..1c4f452997 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -58,13 +58,25 @@ int SSL_get_ex_data_X509_STORE_CTX_idx(void)
return ssl_x509_store_ctx_idx;
}
-CERT *ssl_cert_new(void)
+CERT *ssl_cert_new(size_t ssl_pkey_num)
{
- CERT *ret = OPENSSL_zalloc(sizeof(*ret));
+ CERT *ret = NULL;
+
+ /* Should never happen */
+ if (!ossl_assert(ssl_pkey_num >= SSL_PKEY_NUM))
+ return NULL;
+ ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL)
return NULL;
+ ret->ssl_pkey_num = ssl_pkey_num;
+ ret->pkeys = OPENSSL_zalloc(ret->ssl_pkey_num * sizeof(CERT_PKEY));
+ if (ret->pkeys == NULL) {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+
ret->key = &(ret->pkeys[SSL_PKEY_RSA]);
ret->references = 1;
ret->sec_cb = ssl_security_default_callback;
@@ -73,6 +85,7 @@ CERT *ssl_cert_new(void)
ret->lock = CRYPTO_THREAD_lock_new();
if (ret->lock == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
+ OPENSSL_free(ret->pkeys);
OPENSSL_free(ret);
return NULL;
}
@@ -83,7 +96,7 @@ CERT *ssl_cert_new(void)
CERT *ssl_cert_dup(CERT *cert)
{
CERT *ret = OPENSSL_zalloc(sizeof(*ret));
- int i;
+ size_t i;
#ifndef OPENSSL_NO_COMP_ALG
int j;
#endif
@@ -91,6 +104,11 @@ CERT *ssl_cert_dup(CERT *cert)
if (ret == NULL)
return NULL;
+ ret->ssl_pkey_num = cert->ssl_pkey_num;
+ ret->pkeys = OPENSSL_zalloc(ret->ssl_pkey_num * sizeof(CERT_PKEY));
+ if (ret->pkeys == NULL)
+ return NULL;
+
ret->references = 1;
ret->key = &ret->pkeys[cert->key - cert->pkeys];
ret->lock = CRYPTO_THREAD_lock_new();
@@ -108,7 +126,7 @@ CERT *ssl_cert_dup(CERT *cert)
ret->dh_tmp_cb = cert->dh_tmp_cb;
ret->dh_tmp_auto = cert->dh_tmp_auto;
- for (i = 0; i < SSL_PKEY_NUM; i++) {
+ for (i = 0; i < ret->ssl_pkey_num; i++) {
CERT_PKEY *cpk = cert->pkeys + i;
CERT_PKEY *rpk = ret->pkeys + i;
@@ -217,14 +235,14 @@ CERT *ssl_cert_dup(CERT *cert)
void ssl_cert_clear_certs(CERT *c)
{
- int i;
+ size_t i;
#ifndef OPENSSL_NO_COMP_ALG
int j;
#endif
if (c == NULL)
return;
- for (i = 0; i < SSL_PKEY_NUM; i++) {
+ for (i = 0; i < c->ssl_pkey_num; i++) {
CERT_PKEY *cpk = c->pkeys + i;
X509_free(cpk->x509);
cpk->x509 = NULL;
@@ -269,6 +287,7 @@ void ssl_cert_free(CERT *c)
#ifndef OPENSSL_NO_PSK
OPENSSL_free(c->psk_identity_hint);
#endif
+ OPENSSL_free(c->pkeys);
CRYPTO_THREAD_lock_free(c->lock);
OPENSSL_free(c);
}
@@ -297,6 +316,7 @@ int ssl_cert_set0_chain(SSL_CONNECTION *s, SSL_CTX *ctx, STACK_OF(X509) *chain)
int ssl_cert_set1_chain(SSL_CONNECTION *s, SSL_CTX *ctx, STACK_OF(X509) *chain)
{
STACK_OF(X509) *dchain;
+
if (!chain)
return ssl_cert_set0_chain(s, ctx, NULL);
dchain = X509_chain_up_ref(chain);
@@ -313,6 +333,7 @@ int ssl_cert_add0_chain_cert(SSL_CONNECTION *s, SSL_CTX *ctx, X509 *x)
{
int r;
CERT_PKEY *cpk = s ? s->cert->key : ctx->cert->key;
+
if (!cpk)
return 0;
r = ssl_security_cert(s, ctx, x, 0, 0);
@@ -337,10 +358,11 @@ int ssl_cert_add1_chain_cert(SSL_CONNECTION *s, SSL_CTX *ctx, X509 *x)
int ssl_cert_select_current(CERT *c, X509 *x)
{
- int i;
+ size_t i;
+
if (x == NULL)
return 0;
- for (i = 0; i < SSL_PKEY_NUM; i++) {
+ for (i = 0; i < c->ssl_pkey_num; i++) {
CERT_PKEY *cpk = c->pkeys + i;
if (cpk->x509 == x && cpk->privatekey) {
c->key = cpk;
@@ -348,7 +370,7 @@ int ssl_cert_select_current(CERT *c, X509 *x)
}
}
- for (i = 0; i < SSL_PKEY_NUM; i++) {
+ for (i = 0; i < c->ssl_pkey_num; i++) {
CERT_PKEY *cpk = c->pkeys + i;
if (cpk->privatekey && cpk->x509 && !X509_cmp(cpk->x509, x)) {
c->key = cpk;
@@ -360,18 +382,19 @@ int ssl_cert_select_current(CERT *c, X509 *x)
int ssl_cert_set_current(CERT *c, long op)
{
- int i, idx;
+ size_t i, idx;
+
if (!c)
return 0;
if (op == SSL_CERT_SET_FIRST)
idx = 0;
else if (op == SSL_CERT_SET_NEXT) {
- idx = (int)(c->key - c->pkeys + 1);
- if (idx >= SSL_PKEY_NUM)
+ idx = (size_t)(c->key - c->pkeys + 1);
+ if (idx >= c->ssl_pkey_num)
return 0;
} else
return 0;
- for (i = idx; i < SSL_PKEY_NUM; i++) {
+ for (i = idx; i < c->ssl_pkey_num; i++) {
CERT_PKEY *cpk = c->pkeys + i;
if (cpk->x509 && cpk->privatekey) {
c->key = cpk;
@@ -1156,7 +1179,7 @@ int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid, void *other)
ctx->cert->sec_ex);
}
-int ssl_cert_lookup_by_nid(int nid, size_t *pidx)
+int ssl_cert_lookup_by_nid(int nid, size_t *pidx, SSL_CTX *ctx)
{
size_t i;
@@ -1166,16 +1189,22 @@ int ssl_cert_lookup_by_nid(int nid, size_t *pidx)
return 1;
}
}
-
+ for (i = 0; i < ctx->sigalg_list_len; i++) {
+ if (ctx->ssl_cert_info[i].nid == nid) {
+ *pidx = SSL_PKEY_NUM + i;
+ return 1;
+ }
+ }
return 0;
}
-const SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx)
+SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx, SSL_CTX *ctx)
{
size_t i;
+ /* check classic pk types */
for (i = 0; i < OSSL_NELEM(ssl_cert_info); i++) {
- const SSL_CERT_LOOKUP *tmp_lu = &ssl_cert_info[i];
+ SSL_CERT_LOOKUP *tmp_lu = &ssl_cert_info[i];
if (EVP_PKEY_is_a(pk, OBJ_nid2sn(tmp_lu->nid))
|| EVP_PKEY_is_a(pk, OBJ_nid2ln(tmp_lu->nid))) {
@@ -1184,13 +1213,26 @@ const SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx)
return tmp_lu;
}
}
+ /* check provider-loaded pk types */
+ for (i = 0; ctx->sigalg_list_len; i++) {
+ SSL_CERT_LOOKUP *tmp_lu = &(ctx->ssl_cert_info[i]);
+
+ if (EVP_PKEY_is_a(pk, OBJ_nid2sn(tmp_lu->nid))
+ || EVP_PKEY_is_a(pk, OBJ_nid2ln(tmp_lu->nid))) {
+ if (pidx != NULL)
+ *pidx = SSL_PKEY_NUM + i;
+ return &ctx->ssl_cert_info[i];
+ }
+ }
return NULL;
}
-const SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx)
+SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx, SSL_CTX *ctx)
{
- if (idx >= OSSL_NELEM(ssl_cert_info))
+ if (idx >= (OSSL_NELEM(ssl_cert_info) + ctx->sigalg_list_len))
return NULL;
+ else if (idx >= (OSSL_NELEM(ssl_cert_info)))
+ return &(ctx->ssl_cert_info[idx - SSL_PKEY_NUM]);
return &ssl_cert_info[idx];
}
diff --git a/ssl/ssl_cert_table.h b/ssl/ssl_cert_table.h
index f66c5fe390..e70d9d624e 100644
--- a/ssl/ssl_cert_table.h
+++ b/ssl/ssl_cert_table.h
@@ -10,7 +10,7 @@
/*
* Certificate table information. NB: table entries must match SSL_PKEY indices
*/
-static const SSL_CERT_LOOKUP ssl_cert_info [] = {
+static SSL_CERT_LOOKUP ssl_cert_info [] = {
{EVP_PKEY_RSA, SSL_aRSA}, /* SSL_PKEY_RSA */
{EVP_PKEY_RSA_PSS, SSL_aRSA}, /* SSL_PKEY_RSA_PSS_SIGN */
{EVP_PKEY_DSA, SSL_aDSS}, /* SSL_PKEY_DSA_SIGN */
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index 0ea998d383..a2b12a8811 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -2155,6 +2155,16 @@ int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c)
return ssl_cipher_table_auth[i].nid;
}
+int ssl_get_md_idx(int md_nid) {
+ int i;
+
+ for(i = 0; i < SSL_MD_NUM_IDX; i++) {
+ if (md_nid == ssl_cipher_table_mac[i].nid)
+ return i;
+ }
+ return -1;
+}
+
const EVP_MD *SSL_CIPHER_get_handshake_digest(const SSL_CIPHER *c)
{
int idx = c->algorithm2 & SSL_HANDSHAKE_MAC_MASK;
@@ -2223,8 +2233,13 @@ int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead,
int ssl_cert_is_disabled(SSL_CTX *ctx, size_t idx)
{
- const SSL_CERT_LOOKUP *cl = ssl_cert_lookup_by_idx(idx);
+ SSL_CERT_LOOKUP *cl;
+
+ /* A provider-loaded key type is always enabled */
+ if (idx >= SSL_PKEY_NUM)
+ return 0;
+ cl = ssl_cert_lookup_by_idx(idx, ctx);
if (cl == NULL || (cl->amask & ctx->disabled_auth_mask) != 0)
return 1;
return 0;
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index a2e2666962..1b2c527eb0 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -890,6 +890,7 @@ SSL *ossl_ssl_connection_new_int(SSL_CTX *ctx, const SSL_METHOD *method)
goto sslerr;
#endif
+ s->ssl_pkey_num = SSL_PKEY_NUM + ctx->sigalg_list_len;
return ssl;
cerr:
ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
@@ -1432,6 +1433,7 @@ void ossl_ssl_connection_free(SSL *ssl)
s->wbio = NULL;
BIO_free_all(s->rbio);
s->rbio = NULL;
+ OPENSSL_free(s->s3.tmp.valid_flags);
}
void SSL_set0_rbio(SSL *s, BIO *rbio)
@@ -3778,10 +3780,6 @@ SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq,
ret->session_timeout = meth->get_timeout();
ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
ret->verify_mode = SSL_VERIFY_NONE;
- if ((ret->cert = ssl_cert_new()) == NULL) {
- ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
- goto err;
- }
ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp);
if (ret->sessions == NULL) {
@@ -3802,20 +3800,38 @@ SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq,
#endif
/* initialize cipher/digest methods table */
- if (!ssl_load_ciphers(ret))
+ if (!ssl_load_ciphers(ret)) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
goto err;
- /* initialise sig algs */
- if (!ssl_setup_sig_algs(ret))
+ }
+
+ if (!ssl_load_groups(ret)) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
+ goto err;
+ }
+
+ /* load provider sigalgs */
+ if (!ssl_load_sigalgs(ret)) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
goto err;
+ }
- if (!ssl_load_groups(ret))
+ /* initialise sig algs */
+ if (!ssl_setup_sigalgs(ret)) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
goto err;
+ }
if (!SSL_CTX_set_ciphersuites(ret, OSSL_default_ciphersuites())) {
ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
goto err;
}
+ if ((ret->cert = ssl_cert_new(SSL_PKEY_NUM + ret->sigalg_list_len)) == NULL) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
+ goto err;
+ }
+
if (!ssl_create_cipher_list(ret,
ret->tls13_ciphersuites,
&ret->cipher_list, &ret->cipher_list_by_id,
@@ -4057,8 +4073,22 @@ void SSL_CTX_free(SSL_CTX *a)
OPENSSL_free(a->group_list[j].algorithm);
}
OPENSSL_free(a->group_list);
+ for (j = 0; j < a->sigalg_list_len; j++) {
+ OPENSSL_free(a->sigalg_list[j].name);
+ OPENSSL_free(a->sigalg_list[j].sigalg_name);
+ OPENSSL_free(a->sigalg_list[j].sigalg_oid);
+ OPENSSL_free(a->sigalg_list[j].sig_name);
+ OPENSSL_free(a->sigalg_list[j].sig_oid);
+ OPENSSL_free(a->sigalg_list[j].hash_name);
+ OPENSSL_free(a->sigalg_list[j].hash_oid);
+ OPENSSL_free(a->sigalg_list[j].keytype);
+ OPENSSL_free(a->sigalg_list[j].keytype_oid);
+ }
+ OPENSSL_free(a->sigalg_list);
+ OPENSSL_free(a->ssl_cert_info);
OPENSSL_free(a->sigalg_lookup_cache);
+ OPENSSL_free(a->tls12_sigalgs);
CRYPTO_THREAD_lock_free(a->lock);
#ifdef TSAN_REQUIRES_LOCKING
diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h
index e82564daf6..87fb1fd7cf 100644
--- a/ssl/ssl_local.h
+++ b/ssl/ssl_local.h
@@ -755,6 +755,31 @@ typedef struct tls_group_info_st {
char is_kem; /* Mode for this Group: 0 is KEX, 1 is KEM */
} TLS_GROUP_INFO;
+typedef struct tls_sigalg_info_st {
+ char *name; /* name as in IANA TLS specs */
+ uint16_t code_point; /* IANA-specified code point of sigalg-name */
+ char *sigalg_name; /* (combined) sigalg name */
+ char *sigalg_oid; /* (combined) sigalg OID */
+ char *sig_name; /* pure signature algorithm name */
+ char *sig_oid; /* pure signature algorithm OID */
+ char *hash_name; /* hash algorithm name */
+ char *hash_oid; /* hash algorithm OID */
+ char *keytype; /* keytype name */
+ char *keytype_oid; /* keytype OID */
+ unsigned int secbits; /* Bits of security (from SP800-57) */
+ int mintls; /* Minimum TLS version, -1 unsupported */
+ int maxtls; /* Maximum TLS version (or 0 for undefined) */
+} TLS_SIGALG_INFO;
+
+/*
+ * Structure containing table entry of certificate info corresponding to
+ * CERT_PKEY entries
+ */
+typedef struct {
+ int nid; /* NID of public key algorithm */
+ uint32_t amask; /* authmask corresponding to key type */
+} SSL_CERT_LOOKUP;
+
/* flags values */
# define TLS_GROUP_TYPE 0x0000000FU /* Mask for group type */
# define TLS_GROUP_CURVE_PRIME 0x00000001U
@@ -901,6 +926,7 @@ struct ssl_ctx_st {
size_t max_cert_list;
struct cert_st /* CERT */ *cert;
+ SSL_CERT_LOOKUP *ssl_cert_info;
int read_ahead;
/* callback that allows applications to peek at protocol messages */
@@ -1120,13 +1146,20 @@ struct ssl_ctx_st {
const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX];
size_t ssl_mac_secret_size[SSL_MD_NUM_IDX];
+ size_t tls12_sigalgs_len;
/* Cache of all sigalgs we know and whether they are available or not */
struct sigalg_lookup_st *sigalg_lookup_cache;
+ /* List of all sigalgs (code points) available, incl. from providers */
+ uint16_t *tls12_sigalgs;
TLS_GROUP_INFO *group_list;
size_t group_list_len;
size_t group_list_max_len;
+ TLS_SIGALG_INFO *sigalg_list;
+ size_t sigalg_list_len;
+ size_t sigalg_list_max_len;
+
/* masks of disabled algorithms */
uint32_t disabled_enc_mask;
uint32_t disabled_mac_mask;
@@ -1210,6 +1243,8 @@ struct ssl_connection_st {
size_t init_num; /* amount read/written */
size_t init_off; /* amount read/written */
+ size_t ssl_pkey_num;
+
struct {
long flags;
unsigned char server_random[SSL3_RANDOM_SIZE];
@@ -1244,6 +1279,7 @@ struct ssl_connection_st {
int total_renegotiations;
int num_renegotiations;
int in_read_app_data;
+
struct {
/* actually only need to be 16+20 for SSLv3 and 12 for TLS */
unsigned char finish_md[EVP_MAX_MD_SIZE * 2];
@@ -1307,7 +1343,7 @@ struct ssl_connection_st {
* SSL session: e.g. appropriate curve, signature algorithms etc.
* If zero it can't be used at all.
*/
- uint32_t valid_flags[SSL_PKEY_NUM];
+ uint32_t *valid_flags;
/*
* For servers the following masks are for the key and auth algorithms
* that are supported by the certs below. For clients they are masks of
@@ -1794,15 +1830,6 @@ typedef struct sigalg_lookup_st {
int enabled;
} SIGALG_LOOKUP;
-/*
- * Structure containing table entry of certificate info corresponding to
- * CERT_PKEY entries
- */
-typedef struct {
- int nid; /* NID of public key algorithm */
- uint32_t amask; /* authmask corresponding to key type */
-} SSL_CERT_LOOKUP;
-
/* DTLS structures */
# ifndef OPENSSL_NO_SCTP
@@ -2000,7 +2027,8 @@ typedef struct cert_st {
int dh_tmp_auto;
/* Flags related to certificates */
uint32_t cert_flags;
- CERT_PKEY pkeys[SSL_PKEY_NUM];
+ CERT_PKEY *pkeys;
+ size_t ssl_pkey_num;
/* Custom certificate types sent in certificate request message. */
uint8_t *ctype;
size_t ctype_len;
@@ -2355,7 +2383,7 @@ const char *ssl_protocol_to_string(int version);
/* Returns true if certificate and private key for 'idx' are present */
static ossl_inline int ssl_has_cert(const SSL_CONNECTION *s, int idx)
{
- if (idx < 0 || idx >= SSL_PKEY_NUM)
+ if (idx < 0 || idx >= (int)s->ssl_pkey_num)
return 0;
return s->cert->pkeys[idx].x509 != NULL
&& s->cert->pkeys[idx].privatekey != NULL;
@@ -2381,7 +2409,7 @@ __owur int ossl_ssl_connection_reset(SSL *ssl);
__owur int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes);
__owur int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written);
int ssl_clear_bad_session(SSL_CONNECTION *s);
-__owur CERT *ssl_cert_new(void);
+__owur CERT *ssl_cert_new(size_t ssl_pkey_num);
__owur CERT *ssl_cert_dup(CERT *cert);
void ssl_cert_clear_certs(CERT *c);
void ssl_cert_free(CERT *c);
@@ -2444,10 +2472,11 @@ __owur int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid,
void *other);
int ssl_get_security_level_bits(const SSL *s, const SSL_CTX *ctx, int *levelp);
-__owur int ssl_cert_lookup_by_nid(int nid, size_t *pidx);
-__owur const SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk,
- size_t *pidx);
-__owur const SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx);
+__owur int ssl_cert_lookup_by_nid(int nid, size_t *pidx, SSL_CTX *ctx);
+__owur SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk,
+ size_t *pidx,
+ SSL_CTX *ctx);
+__owur SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx, SSL_CTX *ctx);
int ssl_undefined_function(SSL *s);
__owur int ssl_undefined_void_function(void);
@@ -2460,8 +2489,9 @@ __owur STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL_CONNECTION *sc);
__owur int ssl_x509err2alert(int type);
void ssl_sort_cipher_list(void);
int ssl_load_ciphers(SSL_CTX *ctx);
-__owur int ssl_setup_sig_algs(SSL_CTX *ctx);
+__owur int ssl_setup_sigalgs(SSL_CTX *ctx);
int ssl_load_groups(SSL_CTX *ctx);
+int ssl_load_sigalgs(SSL_CTX *ctx);
__owur int ssl_fill_hello_random(SSL_CONNECTION *s, int server,
unsigned char *field, size_t len,
DOWNGRADE dgrd);
@@ -2750,6 +2780,7 @@ __owur int ssl_handshake_hash(SSL_CONNECTION *s,
unsigned char *out, size_t outlen,
size_t *hashlen);
__owur const EVP_MD *ssl_md(SSL_CTX *ctx, int idx);
+int ssl_get_md_idx(int md_nid);
__owur const EVP_MD *ssl_handshake_md(SSL_CONNECTION *s);
__owur const EVP_MD *ssl_prf_md(SSL_CONNECTION *s);
diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c
index 76466b55b9..3d4ad85a62 100644
--- a/ssl/ssl_rsa.c
+++ b/ssl/ssl_rsa.c
@@ -17,8 +17,8 @@
#include <openssl/x509v3.h>
#include <openssl/pem.h>
-static int ssl_set_cert(CERT *c, X509 *x509);
-static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
+static int ssl_set_cert(CERT *c, X509 *x509, SSL_CTX *ctx);
+static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey, SSL_CTX *ctx);
#define SYNTHV1CONTEXT (SSL_EXT_TLS1_2_AND_BELOW_ONLY \
| SSL_EXT_CLIENT_HELLO \
@@ -47,7 +47,7 @@ int SSL_use_certificate(SSL *ssl, X509 *x)
return 0;
}
- return ssl_set_cert(sc->cert, x);
+ return ssl_set_cert(sc->cert, x, SSL_CONNECTION_GET_CTX(sc));
}
int SSL_use_certificate_file(SSL *ssl, const char *file, int type)
@@ -128,11 +128,11 @@ int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
return ret;
}
-static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
+static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey, SSL_CTX *ctx)
{
size_t i;
- if (ssl_cert_lookup_by_pkey(pkey, &i) == NULL) {
+ if (ssl_cert_lookup_by_pkey(pkey, &i, ctx) == NULL) {
ERR_raise(ERR_LIB_SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
return 0;
}
@@ -160,7 +160,7 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- ret = ssl_set_pkey(sc->cert, pkey);
+ ret = ssl_set_pkey(sc->cert, pkey, SSL_CONNECTION_GET_CTX(sc));
return ret;
}
@@ -243,10 +243,10 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
ERR_raise(ERR_LIB_SSL, rv);
return 0;
}
- return ssl_set_cert(ctx->cert, x);
+ return ssl_set_cert(ctx->cert, x, ctx);
}
-static int ssl_set_cert(CERT *c, X509 *x)
+static int ssl_set_cert(CERT *c, X509 *x, SSL_CTX *ctx)
{
EVP_PKEY *pkey;
size_t i;
@@ -257,7 +257,7 @@ static int ssl_set_cert(CERT *c, X509 *x)
return 0;
}
- if (ssl_cert_lookup_by_pkey(pkey, &i) == NULL) {
+ if (ssl_cert_lookup_by_pkey(pkey, &i, ctx) == NULL) {
ERR_raise(ERR_LIB_SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
return 0;
}
@@ -371,7 +371,7 @@ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- return ssl_set_pkey(ctx->cert, pkey);
+ return ssl_set_pkey(ctx->cert, pkey, ctx);
}
int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
@@ -1010,7 +1010,7 @@ static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *pr
goto out;
}
}
- if (ssl_cert_lookup_by_pkey(pubkey, &i) == NULL) {
+ if (ssl_cert_lookup_by_pkey(pubkey, &i, ctx) == NULL) {
ERR_raise(ERR_LIB_SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
goto out;
}
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index f1ed43abd3..e5b036390a 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -1988,7 +1988,8 @@ WORK_STATE tls_post_process_server_certificate(SSL_CONNECTION *s,
return WORK_ERROR;
}
- if ((clu = ssl_cert_lookup_by_pkey(pkey, &certidx)) == NULL) {
+ if ((clu = ssl_cert_lookup_by_pkey(pkey, &certidx,
+ SSL_CONNECTION_GET_CTX(s))) == NULL) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
return WORK_ERROR;
}
@@ -2434,11 +2435,15 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL_CONNECTION *s, PACKET *pkt)
MSG_PROCESS_RETURN tls_process_certificate_request(SSL_CONNECTION *s,
PACKET *pkt)
{
- size_t i;
-
/* Clear certificate validity flags */
- for (i = 0; i < SSL_PKEY_NUM; i++)
- s->s3.tmp.valid_flags[i] = 0;
+ if (s->s3.tmp.valid_flags != NULL)
+ memset(s->s3.tmp.valid_flags, 0, s->ssl_pkey_num * sizeof(uint32_t));
+ else
+ s->s3.tmp.valid_flags = OPENSSL_zalloc(s->ssl_pkey_num * sizeof(uint32_t));
+
+ /* Give up for good if allocation didn't work */
+ if (s->s3.tmp.valid_flags == NULL)
+ return 0;
if (SSL_CONNECTION_IS_TLS13(s)) {
PACKET reqctx, extensions;
@@ -3768,7 +3773,8 @@ int ssl3_check_cert_and_algorithm(SSL_CONNECTION *s)
return 1;
/* This is the passed certificate */
- clu = ssl_cert_lookup_by_pkey(X509_get0_pubkey(s->session->peer), &idx);
+ clu = ssl_cert_lookup_by_pkey(X509_get0_pubkey(s->session->peer), &idx,
+ SSL_CONNECTION_GET_CTX(s));
/* Check certificate is recognised and suitable for cipher */
if (clu == NULL || (alg_a & clu->amask) == 0) {
diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c
index ebedbeefbb..1bc01e1d25 100644
--- a/ssl/statem/statem_lib.c
+++ b/ssl/statem/statem_lib.c
@@ -468,7 +468,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL_CONNECTION *s, PACKET *pkt)
goto err;
}
- if (ssl_cert_lookup_by_pkey(pkey, NULL) == NULL) {
+ if (ssl_cert_lookup_by_pkey(pkey, NULL, sctx) == NULL) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE);
goto err;
@@ -1602,7 +1602,7 @@ static int ssl_method_error(const SSL_CONNECTION *s, const SSL_METHOD *method)
*/
static int is_tls13_capable(const SSL_CONNECTION *s)
{
- int i;
+ size_t i;
int curve;
SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
@@ -1625,7 +1625,8 @@ static int is_tls13_capable(const SSL_CONNECTION *s)
if (s->psk_find_session_cb != NULL || s->cert->cert_cb != NULL)
return 1;
- for (i = 0; i < SSL_PKEY_NUM; i++) {
+ /* All provider-based sig algs are required to support at least TLS1.3 */
+ for (i = 0; i < s->ssl_pkey_num; i++) {
/* Skip over certs disallowed for TLSv1.3 */
switch (i) {
case SSL_PKEY_DSA_SIGN:
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 25aaa9b56d..5622532314 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -222,7 +222,7 @@ static const uint16_t suiteb_curves[] = {
OSSL_TLS_GROUP_ID_secp384r1,
};
-struct provider_group_data_st {
+struct provider_ctx_data_st {
SSL_CTX *ctx;
OSSL_PROVIDER *provider;
};
@@ -231,7 +231,7 @@ struct provider_group_data_st {
static OSSL_CALLBACK add_provider_groups;
static int add_provider_groups(const OSSL_PARAM params[], void *data)
{
- struct provider_group_data_st *pgd = data;
+ struct provider_ctx_data_st *pgd = data;
SSL_CTX *ctx = pgd->ctx;
OSSL_PROVIDER *provider = pgd->provider;
const OSSL_PARAM *p;
@@ -375,7 +375,7 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data)
static int discover_provider_groups(OSSL_PROVIDER *provider, void *vctx)
{
- struct provider_group_data_st pgd;
+ struct provider_ctx_data_st pgd;
pgd.ctx = vctx;
pgd.provider = provider;
@@ -417,6 +417,319 @@ int ssl_load_groups(SSL_CTX *ctx)
return 1;
}
+#define TLS_SIGALG_LIST_MALLOC_BLOCK_SIZE 10
+static OSSL_CALLBACK add_provider_sigalgs;
+static int add_provider_sigalgs(const OSSL_PARAM params[], void *data)
+{
+ struct provider_ctx_data_st *pgd = data;
+ SSL_CTX *ctx = pgd->ctx;
+ OSSL_PROVIDER *provider = pgd->provider;
+ const OSSL_PARAM *p;
+ TLS_SIGALG_INFO *sinf = NULL;
+ EVP_KEYMGMT *keymgmt;
+ const char *keytype;
+ unsigned int code_point = 0;
+ int ret = 0;
+
+ if (ctx->sigalg_list_max_len == ctx->sigalg_list_len) {
+ TLS_SIGALG_INFO *tmp = NULL;
+
+ if (ctx->sigalg_list_max_len == 0)
+ tmp = OPENSSL_malloc(sizeof(TLS_SIGALG_INFO)
+ * TLS_SIGALG_LIST_MALLOC_BLOCK_SIZE);
+ else
+ tmp = OPENSSL_realloc(ctx->sigalg_list,
+ (ctx->sigalg_list_max_len
+ + TLS_SIGALG_LIST_MALLOC_BLOCK_SIZE)
+ * sizeof(TLS_SIGALG_INFO));
+ if (tmp == NULL)
+ return 0;
+ ctx->sigalg_list = tmp;
+ memset(tmp + ctx->sigalg_list_max_len, 0,
+ sizeof(TLS_SIGALG_INFO) * TLS_SIGALG_LIST_MALLOC_BLOCK_SIZE);
+ ctx->sigalg_list_max_len += TLS_SIGALG_LIST_MALLOC_BLOCK_SIZE;
+ }
+
+ sinf = &ctx->sigalg_list[ctx->sigalg_list_len];
+
+ /* First, mandatory parameters */
+ p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_NAME);
+ if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
+ goto err;
+ }
+ OPENSSL_free(sinf->sigalg_name);
+ sinf->sigalg_name = OPENSSL_strdup(p->data);
+ if (sinf->sigalg_name == NULL)
+ goto err;
+
+ p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_IANA_NAME);
+ if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
+ goto err;
+ }
+ OPENSSL_free(sinf->name);
+ sinf->name = OPENSSL_strdup(p->data);
+ if (sinf->name == NULL)
+ goto err;
+
+ p = OSSL_PARAM_locate_const(params,
+ OSSL_CAPABILITY_TLS_SIGALG_CODE_POINT);
+ if (p == NULL
+ || !OSSL_PARAM_get_uint(p, &code_point)
+ || code_point > UINT16_MAX) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
+ goto err;
+ }
+ sinf->code_point = (uint16_t)code_point;
+
+ p = OSSL_PARAM_locate_const(params,
+ OSSL_CAPABILITY_TLS_SIGALG_SECURITY_BITS);
+ 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);
+ if (p == NULL) {
+ sinf->sigalg_oid = NULL;
+ } else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
+ goto err;
+ } else {
+ OPENSSL_free(sinf->sigalg_oid);
+ sinf->sigalg_oid = OPENSSL_strdup(p->data);
+ if (sinf->sigalg_oid == NULL)
+ goto err;
+ }
+
+ p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_SIG_NAME);
+ if (p == NULL) {
+ sinf->sig_name = NULL;
+ } else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
+ goto err;
+ } else {
+ OPENSSL_free(sinf->sig_name);
+ sinf->sig_name = OPENSSL_strdup(p->data);
+ if (sinf->sig_name == NULL)
+ goto err;
+ }
+
+ p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_SIG_OID);
+ if (p == NULL) {
+ sinf->sig_oid = NULL;
+ } else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
+ goto err;
+ } else {
+ OPENSSL_free(sinf->sig_oid);
+ sinf->sig_oid = OPENSSL_strdup(p->data);
+ if (sinf->sig_oid == NULL)
+ goto err;
+ }
+
+ p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_HASH_NAME);
+ if (p == NULL) {
+ sinf->hash_name = NULL;
+ } else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
+ goto err;
+ } else {
+ OPENSSL_free(sinf->hash_name);
+ sinf->hash_name = OPENSSL_strdup(p->data);
+ if (sinf->hash_name == NULL)
+ goto err;
+ }
+
+ p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_HASH_OID);
+ if (p == NULL) {
+ sinf->hash_oid = NULL;
+ } else if (p->data_type != OSSL_PARAM_UTF8_STRING) {
+ goto err;
+ } else {
+ OPENSSL_free(sinf->hash_oid);
+ sinf->hash_oid = OPENSSL_strdup(p->data);
+ if (sinf->hash_oid == NULL)
+ goto err;