xref: /freebsd/crypto/openssl/ssl/t1_lib.c (revision a7148ab39c03abd4d1a84997c70bf96f15dd2a09)
1e71b7053SJung-uk Kim /*
244096ebdSEnji Cooper  * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
374664626SKris Kennaway  *
4b077aed3SPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
5e71b7053SJung-uk Kim  * this file except in compliance with the License.  You can obtain a copy
6e71b7053SJung-uk Kim  * in the file LICENSE in the source distribution or at
7e71b7053SJung-uk Kim  * https://www.openssl.org/source/license.html
81f13597dSJung-uk Kim  */
974664626SKris Kennaway 
1074664626SKris Kennaway #include <stdio.h>
11e71b7053SJung-uk Kim #include <stdlib.h>
1274664626SKris Kennaway #include <openssl/objects.h>
13db522d3aSSimon L. B. Nielsen #include <openssl/evp.h>
14db522d3aSSimon L. B. Nielsen #include <openssl/hmac.h>
15b077aed3SPierre Pronchery #include <openssl/core_names.h>
16db522d3aSSimon L. B. Nielsen #include <openssl/ocsp.h>
17e71b7053SJung-uk Kim #include <openssl/conf.h>
18e71b7053SJung-uk Kim #include <openssl/x509v3.h>
19e71b7053SJung-uk Kim #include <openssl/dh.h>
20e71b7053SJung-uk Kim #include <openssl/bn.h>
21b077aed3SPierre Pronchery #include <openssl/provider.h>
22b077aed3SPierre Pronchery #include <openssl/param_build.h>
23e71b7053SJung-uk Kim #include "internal/nelem.h"
24b077aed3SPierre Pronchery #include "internal/sizes.h"
25b077aed3SPierre Pronchery #include "internal/tlsgroups.h"
26aa795734SPierre Pronchery #include "internal/cryptlib.h"
2717f01e99SJung-uk Kim #include "ssl_local.h"
28e71b7053SJung-uk Kim #include <openssl/ct.h>
2974664626SKris Kennaway 
30da327cd2SJung-uk Kim static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey);
3117f01e99SJung-uk Kim static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu);
32da327cd2SJung-uk Kim 
33e71b7053SJung-uk Kim SSL3_ENC_METHOD const TLSv1_enc_data = {
3474664626SKris Kennaway     tls1_enc,
3574664626SKris Kennaway     tls1_mac,
3674664626SKris Kennaway     tls1_setup_key_block,
3774664626SKris Kennaway     tls1_generate_master_secret,
3874664626SKris Kennaway     tls1_change_cipher_state,
3974664626SKris Kennaway     tls1_final_finish_mac,
4074664626SKris Kennaway     TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
4174664626SKris Kennaway     TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
4274664626SKris Kennaway     tls1_alert_code,
431f13597dSJung-uk Kim     tls1_export_keying_material,
447bded2dbSJung-uk Kim     0,
457bded2dbSJung-uk Kim     ssl3_set_handshake_header,
46e71b7053SJung-uk Kim     tls_close_construct_packet,
477bded2dbSJung-uk Kim     ssl3_handshake_write
487bded2dbSJung-uk Kim };
497bded2dbSJung-uk Kim 
50e71b7053SJung-uk Kim SSL3_ENC_METHOD const TLSv1_1_enc_data = {
517bded2dbSJung-uk Kim     tls1_enc,
527bded2dbSJung-uk Kim     tls1_mac,
537bded2dbSJung-uk Kim     tls1_setup_key_block,
547bded2dbSJung-uk Kim     tls1_generate_master_secret,
557bded2dbSJung-uk Kim     tls1_change_cipher_state,
567bded2dbSJung-uk Kim     tls1_final_finish_mac,
577bded2dbSJung-uk Kim     TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
587bded2dbSJung-uk Kim     TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
597bded2dbSJung-uk Kim     tls1_alert_code,
607bded2dbSJung-uk Kim     tls1_export_keying_material,
617bded2dbSJung-uk Kim     SSL_ENC_FLAG_EXPLICIT_IV,
627bded2dbSJung-uk Kim     ssl3_set_handshake_header,
63e71b7053SJung-uk Kim     tls_close_construct_packet,
647bded2dbSJung-uk Kim     ssl3_handshake_write
657bded2dbSJung-uk Kim };
667bded2dbSJung-uk Kim 
67e71b7053SJung-uk Kim SSL3_ENC_METHOD const TLSv1_2_enc_data = {
687bded2dbSJung-uk Kim     tls1_enc,
697bded2dbSJung-uk Kim     tls1_mac,
707bded2dbSJung-uk Kim     tls1_setup_key_block,
717bded2dbSJung-uk Kim     tls1_generate_master_secret,
727bded2dbSJung-uk Kim     tls1_change_cipher_state,
737bded2dbSJung-uk Kim     tls1_final_finish_mac,
747bded2dbSJung-uk Kim     TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
757bded2dbSJung-uk Kim     TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
767bded2dbSJung-uk Kim     tls1_alert_code,
777bded2dbSJung-uk Kim     tls1_export_keying_material,
787bded2dbSJung-uk Kim     SSL_ENC_FLAG_EXPLICIT_IV | SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF
797bded2dbSJung-uk Kim         | SSL_ENC_FLAG_TLS1_2_CIPHERS,
807bded2dbSJung-uk Kim     ssl3_set_handshake_header,
81e71b7053SJung-uk Kim     tls_close_construct_packet,
82e71b7053SJung-uk Kim     ssl3_handshake_write
83e71b7053SJung-uk Kim };
84e71b7053SJung-uk Kim 
85e71b7053SJung-uk Kim SSL3_ENC_METHOD const TLSv1_3_enc_data = {
86e71b7053SJung-uk Kim     tls13_enc,
87e71b7053SJung-uk Kim     tls1_mac,
88e71b7053SJung-uk Kim     tls13_setup_key_block,
89e71b7053SJung-uk Kim     tls13_generate_master_secret,
90e71b7053SJung-uk Kim     tls13_change_cipher_state,
91e71b7053SJung-uk Kim     tls13_final_finish_mac,
92e71b7053SJung-uk Kim     TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
93e71b7053SJung-uk Kim     TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
94e71b7053SJung-uk Kim     tls13_alert_code,
95e71b7053SJung-uk Kim     tls13_export_keying_material,
96e71b7053SJung-uk Kim     SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF,
97e71b7053SJung-uk Kim     ssl3_set_handshake_header,
98e71b7053SJung-uk Kim     tls_close_construct_packet,
997bded2dbSJung-uk Kim     ssl3_handshake_write
10074664626SKris Kennaway };
10174664626SKris Kennaway 
tls1_default_timeout(void)1023b4e3dcbSSimon L. B. Nielsen long tls1_default_timeout(void)
10374664626SKris Kennaway {
1046f9291ceSJung-uk Kim     /*
1056f9291ceSJung-uk Kim      * 2 hours, the 24 hours mentioned in the TLSv1 spec is way too long for
1066f9291ceSJung-uk Kim      * http, the cache would over fill
1076f9291ceSJung-uk Kim      */
10874664626SKris Kennaway     return (60 * 60 * 2);
10974664626SKris Kennaway }
11074664626SKris Kennaway 
tls1_new(SSL * s)11174664626SKris Kennaway int tls1_new(SSL *s)
11274664626SKris Kennaway {
1136f9291ceSJung-uk Kim     if (!ssl3_new(s))
114e71b7053SJung-uk Kim         return 0;
115e71b7053SJung-uk Kim     if (!s->method->ssl_clear(s))
116e71b7053SJung-uk Kim         return 0;
117e71b7053SJung-uk Kim 
118e71b7053SJung-uk Kim     return 1;
11974664626SKris Kennaway }
12074664626SKris Kennaway 
tls1_free(SSL * s)12174664626SKris Kennaway void tls1_free(SSL *s)
12274664626SKris Kennaway {
123e71b7053SJung-uk Kim     OPENSSL_free(s->ext.session_ticket);
12474664626SKris Kennaway     ssl3_free(s);
12574664626SKris Kennaway }
12674664626SKris Kennaway 
tls1_clear(SSL * s)127e71b7053SJung-uk Kim int tls1_clear(SSL *s)
12874664626SKris Kennaway {
129e71b7053SJung-uk Kim     if (!ssl3_clear(s))
130e71b7053SJung-uk Kim         return 0;
131e71b7053SJung-uk Kim 
132e71b7053SJung-uk Kim     if (s->method->version == TLS_ANY_VERSION)
133b077aed3SPierre Pronchery         s->version = TLS_MAX_VERSION_INTERNAL;
134e71b7053SJung-uk Kim     else
1351f13597dSJung-uk Kim         s->version = s->method->version;
136e71b7053SJung-uk Kim 
137e71b7053SJung-uk Kim     return 1;
13874664626SKris Kennaway }
13974664626SKris Kennaway 
140b077aed3SPierre Pronchery /* Legacy NID to group_id mapping. Only works for groups we know about */
141b077aed3SPierre Pronchery static struct {
142b077aed3SPierre Pronchery     int nid;
143b077aed3SPierre Pronchery     uint16_t group_id;
144b077aed3SPierre Pronchery } nid_to_group[] = {
145b077aed3SPierre Pronchery     {NID_sect163k1, OSSL_TLS_GROUP_ID_sect163k1},
146b077aed3SPierre Pronchery     {NID_sect163r1, OSSL_TLS_GROUP_ID_sect163r1},
147b077aed3SPierre Pronchery     {NID_sect163r2, OSSL_TLS_GROUP_ID_sect163r2},
148b077aed3SPierre Pronchery     {NID_sect193r1, OSSL_TLS_GROUP_ID_sect193r1},
149b077aed3SPierre Pronchery     {NID_sect193r2, OSSL_TLS_GROUP_ID_sect193r2},
150b077aed3SPierre Pronchery     {NID_sect233k1, OSSL_TLS_GROUP_ID_sect233k1},
151b077aed3SPierre Pronchery     {NID_sect233r1, OSSL_TLS_GROUP_ID_sect233r1},
152b077aed3SPierre Pronchery     {NID_sect239k1, OSSL_TLS_GROUP_ID_sect239k1},
153b077aed3SPierre Pronchery     {NID_sect283k1, OSSL_TLS_GROUP_ID_sect283k1},
154b077aed3SPierre Pronchery     {NID_sect283r1, OSSL_TLS_GROUP_ID_sect283r1},
155b077aed3SPierre Pronchery     {NID_sect409k1, OSSL_TLS_GROUP_ID_sect409k1},
156b077aed3SPierre Pronchery     {NID_sect409r1, OSSL_TLS_GROUP_ID_sect409r1},
157b077aed3SPierre Pronchery     {NID_sect571k1, OSSL_TLS_GROUP_ID_sect571k1},
158b077aed3SPierre Pronchery     {NID_sect571r1, OSSL_TLS_GROUP_ID_sect571r1},
159b077aed3SPierre Pronchery     {NID_secp160k1, OSSL_TLS_GROUP_ID_secp160k1},
160b077aed3SPierre Pronchery     {NID_secp160r1, OSSL_TLS_GROUP_ID_secp160r1},
161b077aed3SPierre Pronchery     {NID_secp160r2, OSSL_TLS_GROUP_ID_secp160r2},
162b077aed3SPierre Pronchery     {NID_secp192k1, OSSL_TLS_GROUP_ID_secp192k1},
163b077aed3SPierre Pronchery     {NID_X9_62_prime192v1, OSSL_TLS_GROUP_ID_secp192r1},
164b077aed3SPierre Pronchery     {NID_secp224k1, OSSL_TLS_GROUP_ID_secp224k1},
165b077aed3SPierre Pronchery     {NID_secp224r1, OSSL_TLS_GROUP_ID_secp224r1},
166b077aed3SPierre Pronchery     {NID_secp256k1, OSSL_TLS_GROUP_ID_secp256k1},
167b077aed3SPierre Pronchery     {NID_X9_62_prime256v1, OSSL_TLS_GROUP_ID_secp256r1},
168b077aed3SPierre Pronchery     {NID_secp384r1, OSSL_TLS_GROUP_ID_secp384r1},
169b077aed3SPierre Pronchery     {NID_secp521r1, OSSL_TLS_GROUP_ID_secp521r1},
170b077aed3SPierre Pronchery     {NID_brainpoolP256r1, OSSL_TLS_GROUP_ID_brainpoolP256r1},
171b077aed3SPierre Pronchery     {NID_brainpoolP384r1, OSSL_TLS_GROUP_ID_brainpoolP384r1},
172b077aed3SPierre Pronchery     {NID_brainpoolP512r1, OSSL_TLS_GROUP_ID_brainpoolP512r1},
173b077aed3SPierre Pronchery     {EVP_PKEY_X25519, OSSL_TLS_GROUP_ID_x25519},
174b077aed3SPierre Pronchery     {EVP_PKEY_X448, OSSL_TLS_GROUP_ID_x448},
175b077aed3SPierre Pronchery     {NID_id_tc26_gost_3410_2012_256_paramSetA, 0x0022},
176b077aed3SPierre Pronchery     {NID_id_tc26_gost_3410_2012_256_paramSetB, 0x0023},
177b077aed3SPierre Pronchery     {NID_id_tc26_gost_3410_2012_256_paramSetC, 0x0024},
178b077aed3SPierre Pronchery     {NID_id_tc26_gost_3410_2012_256_paramSetD, 0x0025},
179b077aed3SPierre Pronchery     {NID_id_tc26_gost_3410_2012_512_paramSetA, 0x0026},
180b077aed3SPierre Pronchery     {NID_id_tc26_gost_3410_2012_512_paramSetB, 0x0027},
181b077aed3SPierre Pronchery     {NID_id_tc26_gost_3410_2012_512_paramSetC, 0x0028},
182b077aed3SPierre Pronchery     {NID_ffdhe2048, OSSL_TLS_GROUP_ID_ffdhe2048},
183b077aed3SPierre Pronchery     {NID_ffdhe3072, OSSL_TLS_GROUP_ID_ffdhe3072},
184b077aed3SPierre Pronchery     {NID_ffdhe4096, OSSL_TLS_GROUP_ID_ffdhe4096},
185b077aed3SPierre Pronchery     {NID_ffdhe6144, OSSL_TLS_GROUP_ID_ffdhe6144},
186b077aed3SPierre Pronchery     {NID_ffdhe8192, OSSL_TLS_GROUP_ID_ffdhe8192}
1871f13597dSJung-uk Kim };
1881f13597dSJung-uk Kim 
1897bded2dbSJung-uk Kim static const unsigned char ecformats_default[] = {
1907bded2dbSJung-uk Kim     TLSEXT_ECPOINTFORMAT_uncompressed,
1917bded2dbSJung-uk Kim     TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime,
1927bded2dbSJung-uk Kim     TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2
1931f13597dSJung-uk Kim };
1941f13597dSJung-uk Kim 
195e71b7053SJung-uk Kim /* The default curves */
196b077aed3SPierre Pronchery static const uint16_t supported_groups_default[] = {
197e71b7053SJung-uk Kim     29,                      /* X25519 (29) */
198e71b7053SJung-uk Kim     23,                      /* secp256r1 (23) */
199e71b7053SJung-uk Kim     30,                      /* X448 (30) */
200e71b7053SJung-uk Kim     25,                      /* secp521r1 (25) */
201e71b7053SJung-uk Kim     24,                      /* secp384r1 (24) */
202b077aed3SPierre Pronchery     34,                      /* GC256A (34) */
203b077aed3SPierre Pronchery     35,                      /* GC256B (35) */
204b077aed3SPierre Pronchery     36,                      /* GC256C (36) */
205b077aed3SPierre Pronchery     37,                      /* GC256D (37) */
206b077aed3SPierre Pronchery     38,                      /* GC512A (38) */
207b077aed3SPierre Pronchery     39,                      /* GC512B (39) */
208b077aed3SPierre Pronchery     40,                      /* GC512C (40) */
209b077aed3SPierre Pronchery     0x100,                   /* ffdhe2048 (0x100) */
210b077aed3SPierre Pronchery     0x101,                   /* ffdhe3072 (0x101) */
211b077aed3SPierre Pronchery     0x102,                   /* ffdhe4096 (0x102) */
212b077aed3SPierre Pronchery     0x103,                   /* ffdhe6144 (0x103) */
213b077aed3SPierre Pronchery     0x104,                   /* ffdhe8192 (0x104) */
2147bded2dbSJung-uk Kim };
2157bded2dbSJung-uk Kim 
216e71b7053SJung-uk Kim static const uint16_t suiteb_curves[] = {
217e71b7053SJung-uk Kim     TLSEXT_curve_P_256,
218e71b7053SJung-uk Kim     TLSEXT_curve_P_384
2197bded2dbSJung-uk Kim };
2207bded2dbSJung-uk Kim 
221b077aed3SPierre Pronchery struct provider_group_data_st {
222b077aed3SPierre Pronchery     SSL_CTX *ctx;
223b077aed3SPierre Pronchery     OSSL_PROVIDER *provider;
224b077aed3SPierre Pronchery };
225b077aed3SPierre Pronchery 
226b077aed3SPierre Pronchery #define TLS_GROUP_LIST_MALLOC_BLOCK_SIZE        10
227b077aed3SPierre Pronchery static OSSL_CALLBACK add_provider_groups;
add_provider_groups(const OSSL_PARAM params[],void * data)228b077aed3SPierre Pronchery static int add_provider_groups(const OSSL_PARAM params[], void *data)
2291f13597dSJung-uk Kim {
230b077aed3SPierre Pronchery     struct provider_group_data_st *pgd = data;
231b077aed3SPierre Pronchery     SSL_CTX *ctx = pgd->ctx;
232b077aed3SPierre Pronchery     OSSL_PROVIDER *provider = pgd->provider;
233b077aed3SPierre Pronchery     const OSSL_PARAM *p;
234b077aed3SPierre Pronchery     TLS_GROUP_INFO *ginf = NULL;
235b077aed3SPierre Pronchery     EVP_KEYMGMT *keymgmt;
236b077aed3SPierre Pronchery     unsigned int gid;
237b077aed3SPierre Pronchery     unsigned int is_kem = 0;
238b077aed3SPierre Pronchery     int ret = 0;
239b077aed3SPierre Pronchery 
240b077aed3SPierre Pronchery     if (ctx->group_list_max_len == ctx->group_list_len) {
241b077aed3SPierre Pronchery         TLS_GROUP_INFO *tmp = NULL;
242b077aed3SPierre Pronchery 
243b077aed3SPierre Pronchery         if (ctx->group_list_max_len == 0)
244b077aed3SPierre Pronchery             tmp = OPENSSL_malloc(sizeof(TLS_GROUP_INFO)
245b077aed3SPierre Pronchery                                  * TLS_GROUP_LIST_MALLOC_BLOCK_SIZE);
246b077aed3SPierre Pronchery         else
247b077aed3SPierre Pronchery             tmp = OPENSSL_realloc(ctx->group_list,
248b077aed3SPierre Pronchery                                   (ctx->group_list_max_len
249b077aed3SPierre Pronchery                                    + TLS_GROUP_LIST_MALLOC_BLOCK_SIZE)
250b077aed3SPierre Pronchery                                   * sizeof(TLS_GROUP_INFO));
251b077aed3SPierre Pronchery         if (tmp == NULL) {
252b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
253b077aed3SPierre Pronchery             return 0;
254b077aed3SPierre Pronchery         }
255b077aed3SPierre Pronchery         ctx->group_list = tmp;
256b077aed3SPierre Pronchery         memset(tmp + ctx->group_list_max_len,
257b077aed3SPierre Pronchery                0,
258b077aed3SPierre Pronchery                sizeof(TLS_GROUP_INFO) * TLS_GROUP_LIST_MALLOC_BLOCK_SIZE);
259b077aed3SPierre Pronchery         ctx->group_list_max_len += TLS_GROUP_LIST_MALLOC_BLOCK_SIZE;
26074664626SKris Kennaway     }
261f579bf8eSKris Kennaway 
262b077aed3SPierre Pronchery     ginf = &ctx->group_list[ctx->group_list_len];
263b077aed3SPierre Pronchery 
264b077aed3SPierre Pronchery     p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_NAME);
265b077aed3SPierre Pronchery     if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) {
266b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
267b077aed3SPierre Pronchery         goto err;
268b077aed3SPierre Pronchery     }
269b077aed3SPierre Pronchery     ginf->tlsname = OPENSSL_strdup(p->data);
270b077aed3SPierre Pronchery     if (ginf->tlsname == NULL) {
271b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
272b077aed3SPierre Pronchery         goto err;
273b077aed3SPierre Pronchery     }
274b077aed3SPierre Pronchery 
275b077aed3SPierre Pronchery     p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL);
276b077aed3SPierre Pronchery     if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) {
277b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
278b077aed3SPierre Pronchery         goto err;
279b077aed3SPierre Pronchery     }
280b077aed3SPierre Pronchery     ginf->realname = OPENSSL_strdup(p->data);
281b077aed3SPierre Pronchery     if (ginf->realname == NULL) {
282b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
283b077aed3SPierre Pronchery         goto err;
284b077aed3SPierre Pronchery     }
285b077aed3SPierre Pronchery 
286b077aed3SPierre Pronchery     p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_ID);
287b077aed3SPierre Pronchery     if (p == NULL || !OSSL_PARAM_get_uint(p, &gid) || gid > UINT16_MAX) {
288b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
289b077aed3SPierre Pronchery         goto err;
290b077aed3SPierre Pronchery     }
291b077aed3SPierre Pronchery     ginf->group_id = (uint16_t)gid;
292b077aed3SPierre Pronchery 
293b077aed3SPierre Pronchery     p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_ALG);
294b077aed3SPierre Pronchery     if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) {
295b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
296b077aed3SPierre Pronchery         goto err;
297b077aed3SPierre Pronchery     }
298b077aed3SPierre Pronchery     ginf->algorithm = OPENSSL_strdup(p->data);
299b077aed3SPierre Pronchery     if (ginf->algorithm == NULL) {
300b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
301b077aed3SPierre Pronchery         goto err;
302b077aed3SPierre Pronchery     }
303b077aed3SPierre Pronchery 
304b077aed3SPierre Pronchery     p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS);
305b077aed3SPierre Pronchery     if (p == NULL || !OSSL_PARAM_get_uint(p, &ginf->secbits)) {
306b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
307b077aed3SPierre Pronchery         goto err;
308b077aed3SPierre Pronchery     }
309b077aed3SPierre Pronchery 
310b077aed3SPierre Pronchery     p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_IS_KEM);
311b077aed3SPierre Pronchery     if (p != NULL && (!OSSL_PARAM_get_uint(p, &is_kem) || is_kem > 1)) {
312b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
313b077aed3SPierre Pronchery         goto err;
314b077aed3SPierre Pronchery     }
315b077aed3SPierre Pronchery     ginf->is_kem = 1 & is_kem;
316b077aed3SPierre Pronchery 
317b077aed3SPierre Pronchery     p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MIN_TLS);
318b077aed3SPierre Pronchery     if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->mintls)) {
319b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
320b077aed3SPierre Pronchery         goto err;
321b077aed3SPierre Pronchery     }
322b077aed3SPierre Pronchery 
323b077aed3SPierre Pronchery     p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MAX_TLS);
324b077aed3SPierre Pronchery     if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->maxtls)) {
325b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
326b077aed3SPierre Pronchery         goto err;
327b077aed3SPierre Pronchery     }
328b077aed3SPierre Pronchery 
329b077aed3SPierre Pronchery     p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS);
330b077aed3SPierre Pronchery     if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->mindtls)) {
331b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
332b077aed3SPierre Pronchery         goto err;
333b077aed3SPierre Pronchery     }
334b077aed3SPierre Pronchery 
335b077aed3SPierre Pronchery     p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS);
336b077aed3SPierre Pronchery     if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->maxdtls)) {
337b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
338b077aed3SPierre Pronchery         goto err;
339b077aed3SPierre Pronchery     }
340b077aed3SPierre Pronchery     /*
341b077aed3SPierre Pronchery      * Now check that the algorithm is actually usable for our property query
342b077aed3SPierre Pronchery      * string. Regardless of the result we still return success because we have
343b077aed3SPierre Pronchery      * successfully processed this group, even though we may decide not to use
344b077aed3SPierre Pronchery      * it.
345b077aed3SPierre Pronchery      */
346b077aed3SPierre Pronchery     ret = 1;
347b077aed3SPierre Pronchery     ERR_set_mark();
348b077aed3SPierre Pronchery     keymgmt = EVP_KEYMGMT_fetch(ctx->libctx, ginf->algorithm, ctx->propq);
349b077aed3SPierre Pronchery     if (keymgmt != NULL) {
350b077aed3SPierre Pronchery         /*
351b077aed3SPierre Pronchery          * We have successfully fetched the algorithm - however if the provider
352b077aed3SPierre Pronchery          * doesn't match this one then we ignore it.
353b077aed3SPierre Pronchery          *
354b077aed3SPierre Pronchery          * Note: We're cheating a little here. Technically if the same algorithm
355b077aed3SPierre Pronchery          * is available from more than one provider then it is undefined which
356b077aed3SPierre Pronchery          * implementation you will get back. Theoretically this could be
357b077aed3SPierre Pronchery          * different every time...we assume here that you'll always get the
358b077aed3SPierre Pronchery          * same one back if you repeat the exact same fetch. Is this a reasonable
359b077aed3SPierre Pronchery          * assumption to make (in which case perhaps we should document this
360b077aed3SPierre Pronchery          * behaviour)?
361b077aed3SPierre Pronchery          */
362b077aed3SPierre Pronchery         if (EVP_KEYMGMT_get0_provider(keymgmt) == provider) {
363b077aed3SPierre Pronchery             /* We have a match - so we will use this group */
364b077aed3SPierre Pronchery             ctx->group_list_len++;
365b077aed3SPierre Pronchery             ginf = NULL;
366b077aed3SPierre Pronchery         }
367b077aed3SPierre Pronchery         EVP_KEYMGMT_free(keymgmt);
368b077aed3SPierre Pronchery     }
369b077aed3SPierre Pronchery     ERR_pop_to_mark();
370b077aed3SPierre Pronchery  err:
371b077aed3SPierre Pronchery     if (ginf != NULL) {
372b077aed3SPierre Pronchery         OPENSSL_free(ginf->tlsname);
373b077aed3SPierre Pronchery         OPENSSL_free(ginf->realname);
374b077aed3SPierre Pronchery         OPENSSL_free(ginf->algorithm);
375b077aed3SPierre Pronchery         ginf->algorithm = ginf->tlsname = ginf->realname = NULL;
376b077aed3SPierre Pronchery     }
377b077aed3SPierre Pronchery     return ret;
378b077aed3SPierre Pronchery }
379b077aed3SPierre Pronchery 
discover_provider_groups(OSSL_PROVIDER * provider,void * vctx)380b077aed3SPierre Pronchery static int discover_provider_groups(OSSL_PROVIDER *provider, void *vctx)
381b077aed3SPierre Pronchery {
382b077aed3SPierre Pronchery     struct provider_group_data_st pgd;
383b077aed3SPierre Pronchery 
384b077aed3SPierre Pronchery     pgd.ctx = vctx;
385b077aed3SPierre Pronchery     pgd.provider = provider;
386b077aed3SPierre Pronchery     return OSSL_PROVIDER_get_capabilities(provider, "TLS-GROUP",
387b077aed3SPierre Pronchery                                           add_provider_groups, &pgd);
388b077aed3SPierre Pronchery }
389b077aed3SPierre Pronchery 
ssl_load_groups(SSL_CTX * ctx)390b077aed3SPierre Pronchery int ssl_load_groups(SSL_CTX *ctx)
391b077aed3SPierre Pronchery {
392b077aed3SPierre Pronchery     size_t i, j, num_deflt_grps = 0;
393b077aed3SPierre Pronchery     uint16_t tmp_supp_groups[OSSL_NELEM(supported_groups_default)];
394b077aed3SPierre Pronchery 
395b077aed3SPierre Pronchery     if (!OSSL_PROVIDER_do_all(ctx->libctx, discover_provider_groups, ctx))
396b077aed3SPierre Pronchery         return 0;
397b077aed3SPierre Pronchery 
398b077aed3SPierre Pronchery     for (i = 0; i < OSSL_NELEM(supported_groups_default); i++) {
399b077aed3SPierre Pronchery         for (j = 0; j < ctx->group_list_len; j++) {
400b077aed3SPierre Pronchery             if (ctx->group_list[j].group_id == supported_groups_default[i]) {
401b077aed3SPierre Pronchery                 tmp_supp_groups[num_deflt_grps++] = ctx->group_list[j].group_id;
402b077aed3SPierre Pronchery                 break;
403b077aed3SPierre Pronchery             }
404b077aed3SPierre Pronchery         }
405b077aed3SPierre Pronchery     }
406b077aed3SPierre Pronchery 
407b077aed3SPierre Pronchery     if (num_deflt_grps == 0)
408b077aed3SPierre Pronchery         return 1;
409b077aed3SPierre Pronchery 
410b077aed3SPierre Pronchery     ctx->ext.supported_groups_default
411b077aed3SPierre Pronchery         = OPENSSL_malloc(sizeof(uint16_t) * num_deflt_grps);
412b077aed3SPierre Pronchery 
413b077aed3SPierre Pronchery     if (ctx->ext.supported_groups_default == NULL) {
414b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
415b077aed3SPierre Pronchery         return 0;
416b077aed3SPierre Pronchery     }
417b077aed3SPierre Pronchery 
418b077aed3SPierre Pronchery     memcpy(ctx->ext.supported_groups_default,
419b077aed3SPierre Pronchery            tmp_supp_groups,
420b077aed3SPierre Pronchery            num_deflt_grps * sizeof(tmp_supp_groups[0]));
421b077aed3SPierre Pronchery     ctx->ext.supported_groups_default_len = num_deflt_grps;
422b077aed3SPierre Pronchery 
423b077aed3SPierre Pronchery     return 1;
424b077aed3SPierre Pronchery }
425b077aed3SPierre Pronchery 
tls1_group_name2id(SSL_CTX * ctx,const char * name)426b077aed3SPierre Pronchery static uint16_t tls1_group_name2id(SSL_CTX *ctx, const char *name)
427f579bf8eSKris Kennaway {
428e71b7053SJung-uk Kim     size_t i;
429b077aed3SPierre Pronchery 
430b077aed3SPierre Pronchery     for (i = 0; i < ctx->group_list_len; i++) {
431b077aed3SPierre Pronchery         if (strcmp(ctx->group_list[i].tlsname, name) == 0
432b077aed3SPierre Pronchery                 || strcmp(ctx->group_list[i].realname, name) == 0)
433b077aed3SPierre Pronchery             return ctx->group_list[i].group_id;
434f579bf8eSKris Kennaway     }
435b077aed3SPierre Pronchery 
436b077aed3SPierre Pronchery     return 0;
437b077aed3SPierre Pronchery }
438b077aed3SPierre Pronchery 
tls1_group_id_lookup(SSL_CTX * ctx,uint16_t group_id)439b077aed3SPierre Pronchery const TLS_GROUP_INFO *tls1_group_id_lookup(SSL_CTX *ctx, uint16_t group_id)
440b077aed3SPierre Pronchery {
441b077aed3SPierre Pronchery     size_t i;
442b077aed3SPierre Pronchery 
443b077aed3SPierre Pronchery     for (i = 0; i < ctx->group_list_len; i++) {
444b077aed3SPierre Pronchery         if (ctx->group_list[i].group_id == group_id)
445b077aed3SPierre Pronchery             return &ctx->group_list[i];
446b077aed3SPierre Pronchery     }
447b077aed3SPierre Pronchery 
448b077aed3SPierre Pronchery     return NULL;
449b077aed3SPierre Pronchery }
450b077aed3SPierre Pronchery 
tls1_group_id2nid(uint16_t group_id,int include_unknown)451b077aed3SPierre Pronchery int tls1_group_id2nid(uint16_t group_id, int include_unknown)
452b077aed3SPierre Pronchery {
453b077aed3SPierre Pronchery     size_t i;
454b077aed3SPierre Pronchery 
455b077aed3SPierre Pronchery     if (group_id == 0)
456b077aed3SPierre Pronchery         return NID_undef;
457b077aed3SPierre Pronchery 
458b077aed3SPierre Pronchery     /*
459b077aed3SPierre Pronchery      * Return well known Group NIDs - for backwards compatibility. This won't
460b077aed3SPierre Pronchery      * work for groups we don't know about.
461b077aed3SPierre Pronchery      */
462b077aed3SPierre Pronchery     for (i = 0; i < OSSL_NELEM(nid_to_group); i++)
463b077aed3SPierre Pronchery     {
464b077aed3SPierre Pronchery         if (nid_to_group[i].group_id == group_id)
465b077aed3SPierre Pronchery             return nid_to_group[i].nid;
466b077aed3SPierre Pronchery     }
467b077aed3SPierre Pronchery     if (!include_unknown)
468b077aed3SPierre Pronchery         return NID_undef;
469b077aed3SPierre Pronchery     return TLSEXT_nid_unknown | (int)group_id;
470b077aed3SPierre Pronchery }
471b077aed3SPierre Pronchery 
tls1_nid2group_id(int nid)472b077aed3SPierre Pronchery uint16_t tls1_nid2group_id(int nid)
473b077aed3SPierre Pronchery {
474b077aed3SPierre Pronchery     size_t i;
475b077aed3SPierre Pronchery 
476b077aed3SPierre Pronchery     /*
477b077aed3SPierre Pronchery      * Return well known Group ids - for backwards compatibility. This won't
478b077aed3SPierre Pronchery      * work for groups we don't know about.
479b077aed3SPierre Pronchery      */
480b077aed3SPierre Pronchery     for (i = 0; i < OSSL_NELEM(nid_to_group); i++)
481b077aed3SPierre Pronchery     {
482b077aed3SPierre Pronchery         if (nid_to_group[i].nid == nid)
483b077aed3SPierre Pronchery             return nid_to_group[i].group_id;
484b077aed3SPierre Pronchery     }
485b077aed3SPierre Pronchery 
486e71b7053SJung-uk Kim     return 0;
4871f13597dSJung-uk Kim }
4887bded2dbSJung-uk Kim 
4897bded2dbSJung-uk Kim /*
490e71b7053SJung-uk Kim  * Set *pgroups to the supported groups list and *pgroupslen to
491e71b7053SJung-uk Kim  * the number of groups supported.
4927bded2dbSJung-uk Kim  */
tls1_get_supported_groups(SSL * s,const uint16_t ** pgroups,size_t * pgroupslen)493e71b7053SJung-uk Kim void tls1_get_supported_groups(SSL *s, const uint16_t **pgroups,
494e71b7053SJung-uk Kim                                size_t *pgroupslen)
4957bded2dbSJung-uk Kim {
4967bded2dbSJung-uk Kim     /* For Suite B mode only include P-256, P-384 */
4977bded2dbSJung-uk Kim     switch (tls1_suiteb(s)) {
4987bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_128_LOS:
499e71b7053SJung-uk Kim         *pgroups = suiteb_curves;
500e71b7053SJung-uk Kim         *pgroupslen = OSSL_NELEM(suiteb_curves);
5017bded2dbSJung-uk Kim         break;
5027bded2dbSJung-uk Kim 
5037bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:
504e71b7053SJung-uk Kim         *pgroups = suiteb_curves;
505e71b7053SJung-uk Kim         *pgroupslen = 1;
5067bded2dbSJung-uk Kim         break;
5077bded2dbSJung-uk Kim 
5087bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_192_LOS:
509e71b7053SJung-uk Kim         *pgroups = suiteb_curves + 1;
510e71b7053SJung-uk Kim         *pgroupslen = 1;
5117bded2dbSJung-uk Kim         break;
512e71b7053SJung-uk Kim 
5137bded2dbSJung-uk Kim     default:
514e71b7053SJung-uk Kim         if (s->ext.supportedgroups == NULL) {
515b077aed3SPierre Pronchery             *pgroups = s->ctx->ext.supported_groups_default;
516b077aed3SPierre Pronchery             *pgroupslen = s->ctx->ext.supported_groups_default_len;
5177bded2dbSJung-uk Kim         } else {
518e71b7053SJung-uk Kim             *pgroups = s->ext.supportedgroups;
519e71b7053SJung-uk Kim             *pgroupslen = s->ext.supportedgroups_len;
5207bded2dbSJung-uk Kim         }
521e71b7053SJung-uk Kim         break;
5227bded2dbSJung-uk Kim     }
5237bded2dbSJung-uk Kim }
5247bded2dbSJung-uk Kim 
tls_valid_group(SSL * s,uint16_t group_id,int minversion,int maxversion,int isec,int * okfortls13)525b077aed3SPierre Pronchery int tls_valid_group(SSL *s, uint16_t group_id, int minversion, int maxversion,
526b077aed3SPierre Pronchery                     int isec, int *okfortls13)
5277bded2dbSJung-uk Kim {
528b077aed3SPierre Pronchery     const TLS_GROUP_INFO *ginfo = tls1_group_id_lookup(s->ctx, group_id);
529b077aed3SPierre Pronchery     int ret;
530e71b7053SJung-uk Kim 
531b077aed3SPierre Pronchery     if (okfortls13 != NULL)
532b077aed3SPierre Pronchery         *okfortls13 = 0;
533b077aed3SPierre Pronchery 
534b077aed3SPierre Pronchery     if (ginfo == NULL)
5357bded2dbSJung-uk Kim         return 0;
536b077aed3SPierre Pronchery 
537b077aed3SPierre Pronchery     if (SSL_IS_DTLS(s)) {
538b077aed3SPierre Pronchery         if (ginfo->mindtls < 0 || ginfo->maxdtls < 0)
5397bded2dbSJung-uk Kim             return 0;
540b077aed3SPierre Pronchery         if (ginfo->maxdtls == 0)
541b077aed3SPierre Pronchery             ret = 1;
542b077aed3SPierre Pronchery         else
543b077aed3SPierre Pronchery             ret = DTLS_VERSION_LE(minversion, ginfo->maxdtls);
544b077aed3SPierre Pronchery         if (ginfo->mindtls > 0)
545b077aed3SPierre Pronchery             ret &= DTLS_VERSION_GE(maxversion, ginfo->mindtls);
546b077aed3SPierre Pronchery     } else {
547b077aed3SPierre Pronchery         if (ginfo->mintls < 0 || ginfo->maxtls < 0)
548b077aed3SPierre Pronchery             return 0;
549b077aed3SPierre Pronchery         if (ginfo->maxtls == 0)
550b077aed3SPierre Pronchery             ret = 1;
551b077aed3SPierre Pronchery         else
552b077aed3SPierre Pronchery             ret = (minversion <= ginfo->maxtls);
553b077aed3SPierre Pronchery         if (ginfo->mintls > 0)
554b077aed3SPierre Pronchery             ret &= (maxversion >= ginfo->mintls);
555b077aed3SPierre Pronchery         if (ret && okfortls13 != NULL && maxversion == TLS1_3_VERSION)
556b077aed3SPierre Pronchery             *okfortls13 = (ginfo->maxtls == 0)
557b077aed3SPierre Pronchery                           || (ginfo->maxtls >= TLS1_3_VERSION);
558b077aed3SPierre Pronchery     }
559b077aed3SPierre Pronchery     ret &= !isec
560b077aed3SPierre Pronchery            || strcmp(ginfo->algorithm, "EC") == 0
561b077aed3SPierre Pronchery            || strcmp(ginfo->algorithm, "X25519") == 0
562b077aed3SPierre Pronchery            || strcmp(ginfo->algorithm, "X448") == 0;
563b077aed3SPierre Pronchery 
564b077aed3SPierre Pronchery     return ret;
565b077aed3SPierre Pronchery }
566b077aed3SPierre Pronchery 
567b077aed3SPierre Pronchery /* See if group is allowed by security callback */
tls_group_allowed(SSL * s,uint16_t group,int op)568b077aed3SPierre Pronchery int tls_group_allowed(SSL *s, uint16_t group, int op)
569b077aed3SPierre Pronchery {
570b077aed3SPierre Pronchery     const TLS_GROUP_INFO *ginfo = tls1_group_id_lookup(s->ctx, group);
571b077aed3SPierre Pronchery     unsigned char gtmp[2];
572b077aed3SPierre Pronchery 
573b077aed3SPierre Pronchery     if (ginfo == NULL)
574b077aed3SPierre Pronchery         return 0;
575b077aed3SPierre Pronchery 
576b077aed3SPierre Pronchery     gtmp[0] = group >> 8;
577b077aed3SPierre Pronchery     gtmp[1] = group & 0xff;
578b077aed3SPierre Pronchery     return ssl_security(s, op, ginfo->secbits,
579b077aed3SPierre Pronchery                         tls1_group_id2nid(ginfo->group_id, 0), (void *)gtmp);
5807bded2dbSJung-uk Kim }
581e71b7053SJung-uk Kim 
582e71b7053SJung-uk Kim /* Return 1 if "id" is in "list" */
tls1_in_list(uint16_t id,const uint16_t * list,size_t listlen)583e71b7053SJung-uk Kim static int tls1_in_list(uint16_t id, const uint16_t *list, size_t listlen)
584e71b7053SJung-uk Kim {
585e71b7053SJung-uk Kim     size_t i;
586e71b7053SJung-uk Kim     for (i = 0; i < listlen; i++)
587e71b7053SJung-uk Kim         if (list[i] == id)
5887bded2dbSJung-uk Kim             return 1;
5897bded2dbSJung-uk Kim     return 0;
5907bded2dbSJung-uk Kim }
5917bded2dbSJung-uk Kim 
5927bded2dbSJung-uk Kim /*-
593e71b7053SJung-uk Kim  * For nmatch >= 0, return the id of the |nmatch|th shared group or 0
594e71b7053SJung-uk Kim  * if there is no match.
5957bded2dbSJung-uk Kim  * For nmatch == -1, return number of matches
596e71b7053SJung-uk Kim  * For nmatch == -2, return the id of the group to use for
597e71b7053SJung-uk Kim  * a tmp key, or 0 if there is no match.
5987bded2dbSJung-uk Kim  */
tls1_shared_group(SSL * s,int nmatch)599e71b7053SJung-uk Kim uint16_t tls1_shared_group(SSL *s, int nmatch)
6007bded2dbSJung-uk Kim {
601e71b7053SJung-uk Kim     const uint16_t *pref, *supp;
602e71b7053SJung-uk Kim     size_t num_pref, num_supp, i;
6037bded2dbSJung-uk Kim     int k;
604aa795734SPierre Pronchery     SSL_CTX *ctx = s->ctx;
605e71b7053SJung-uk Kim 
6067bded2dbSJung-uk Kim     /* Can't do anything on client side */
6077bded2dbSJung-uk Kim     if (s->server == 0)
608e71b7053SJung-uk Kim         return 0;
6097bded2dbSJung-uk Kim     if (nmatch == -2) {
6107bded2dbSJung-uk Kim         if (tls1_suiteb(s)) {
6117bded2dbSJung-uk Kim             /*
6127bded2dbSJung-uk Kim              * For Suite B ciphersuite determines curve: we already know
6137bded2dbSJung-uk Kim              * these are acceptable due to previous checks.
6147bded2dbSJung-uk Kim              */
615b077aed3SPierre Pronchery             unsigned long cid = s->s3.tmp.new_cipher->id;
616e71b7053SJung-uk Kim 
6177bded2dbSJung-uk Kim             if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
618e71b7053SJung-uk Kim                 return TLSEXT_curve_P_256;
6197bded2dbSJung-uk Kim             if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
620e71b7053SJung-uk Kim                 return TLSEXT_curve_P_384;
6217bded2dbSJung-uk Kim             /* Should never happen */
622e71b7053SJung-uk Kim             return 0;
6237bded2dbSJung-uk Kim         }
6247bded2dbSJung-uk Kim         /* If not Suite B just return first preference shared curve */
6257bded2dbSJung-uk Kim         nmatch = 0;
6267bded2dbSJung-uk Kim     }
6277bded2dbSJung-uk Kim     /*
628e71b7053SJung-uk Kim      * If server preference set, our groups are the preference order
629e71b7053SJung-uk Kim      * otherwise peer decides.
6307bded2dbSJung-uk Kim      */
631e71b7053SJung-uk Kim     if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
632e71b7053SJung-uk Kim         tls1_get_supported_groups(s, &pref, &num_pref);
633e71b7053SJung-uk Kim         tls1_get_peer_groups(s, &supp, &num_supp);
634e71b7053SJung-uk Kim     } else {
635e71b7053SJung-uk Kim         tls1_get_peer_groups(s, &pref, &num_pref);
636e71b7053SJung-uk Kim         tls1_get_supported_groups(s, &supp, &num_supp);
6377bded2dbSJung-uk Kim     }
6387bded2dbSJung-uk Kim 
639e71b7053SJung-uk Kim     for (k = 0, i = 0; i < num_pref; i++) {
640e71b7053SJung-uk Kim         uint16_t id = pref[i];
641aa795734SPierre Pronchery         const TLS_GROUP_INFO *inf;
642e71b7053SJung-uk Kim 
643e71b7053SJung-uk Kim         if (!tls1_in_list(id, supp, num_supp)
644b077aed3SPierre Pronchery                 || !tls_group_allowed(s, id, SSL_SECOP_CURVE_SHARED))
645e71b7053SJung-uk Kim             continue;
646aa795734SPierre Pronchery         inf = tls1_group_id_lookup(ctx, id);
647aa795734SPierre Pronchery         if (!ossl_assert(inf != NULL))
648aa795734SPierre Pronchery             return 0;
649aa795734SPierre Pronchery         if (SSL_IS_DTLS(s)) {
650aa795734SPierre Pronchery             if (inf->maxdtls == -1)
651aa795734SPierre Pronchery                 continue;
652aa795734SPierre Pronchery             if ((inf->mindtls != 0 && DTLS_VERSION_LT(s->version, inf->mindtls))
653aa795734SPierre Pronchery                     || (inf->maxdtls != 0
654aa795734SPierre Pronchery                         && DTLS_VERSION_GT(s->version, inf->maxdtls)))
655aa795734SPierre Pronchery                 continue;
656aa795734SPierre Pronchery         } else {
657aa795734SPierre Pronchery             if (inf->maxtls == -1)
658aa795734SPierre Pronchery                 continue;
659aa795734SPierre Pronchery             if ((inf->mintls != 0 && s->version < inf->mintls)
660aa795734SPierre Pronchery                     || (inf->maxtls != 0 && s->version > inf->maxtls))
661aa795734SPierre Pronchery                 continue;
662aa795734SPierre Pronchery         }
663aa795734SPierre Pronchery 
664e71b7053SJung-uk Kim         if (nmatch == k)
665e71b7053SJung-uk Kim             return id;
6667bded2dbSJung-uk Kim          k++;
6677bded2dbSJung-uk Kim     }
6687bded2dbSJung-uk Kim     if (nmatch == -1)
6697bded2dbSJung-uk Kim         return k;
6707bded2dbSJung-uk Kim     /* Out of range (nmatch > k). */
671e71b7053SJung-uk Kim     return 0;
6727bded2dbSJung-uk Kim }
6737bded2dbSJung-uk Kim 
tls1_set_groups(uint16_t ** pext,size_t * pextlen,int * groups,size_t ngroups)674e71b7053SJung-uk Kim int tls1_set_groups(uint16_t **pext, size_t *pextlen,
675e71b7053SJung-uk Kim                     int *groups, size_t ngroups)
6767bded2dbSJung-uk Kim {
677e71b7053SJung-uk Kim     uint16_t *glist;
6787bded2dbSJung-uk Kim     size_t i;
6797bded2dbSJung-uk Kim     /*
680b077aed3SPierre Pronchery      * Bitmap of groups included to detect duplicates: two variables are added
681b077aed3SPierre Pronchery      * to detect duplicates as some values are more than 32.
6827bded2dbSJung-uk Kim      */
683b077aed3SPierre Pronchery     unsigned long *dup_list = NULL;
684b077aed3SPierre Pronchery     unsigned long dup_list_egrp = 0;
685b077aed3SPierre Pronchery     unsigned long dup_list_dhgrp = 0;
6867bded2dbSJung-uk Kim 
687c9cf7b5cSJung-uk Kim     if (ngroups == 0) {
688b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH);
689c9cf7b5cSJung-uk Kim         return 0;
690c9cf7b5cSJung-uk Kim     }
691e71b7053SJung-uk Kim     if ((glist = OPENSSL_malloc(ngroups * sizeof(*glist))) == NULL) {
692b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
6937bded2dbSJung-uk Kim         return 0;
6947bded2dbSJung-uk Kim     }
695e71b7053SJung-uk Kim     for (i = 0; i < ngroups; i++) {
696e71b7053SJung-uk Kim         unsigned long idmask;
697e71b7053SJung-uk Kim         uint16_t id;
698e71b7053SJung-uk Kim         id = tls1_nid2group_id(groups[i]);
699b077aed3SPierre Pronchery         if ((id & 0x00FF) >= (sizeof(unsigned long) * 8))
700b077aed3SPierre Pronchery             goto err;
701b077aed3SPierre Pronchery         idmask = 1L << (id & 0x00FF);
702b077aed3SPierre Pronchery         dup_list = (id < 0x100) ? &dup_list_egrp : &dup_list_dhgrp;
703b077aed3SPierre Pronchery         if (!id || ((*dup_list) & idmask))
704b077aed3SPierre Pronchery             goto err;
705b077aed3SPierre Pronchery         *dup_list |= idmask;
706e71b7053SJung-uk Kim         glist[i] = id;
7077bded2dbSJung-uk Kim     }
7087bded2dbSJung-uk Kim     OPENSSL_free(*pext);
709e71b7053SJung-uk Kim     *pext = glist;
710e71b7053SJung-uk Kim     *pextlen = ngroups;
7117bded2dbSJung-uk Kim     return 1;
712b077aed3SPierre Pronchery err:
713b077aed3SPierre Pronchery     OPENSSL_free(glist);
714b077aed3SPierre Pronchery     return 0;
7157bded2dbSJung-uk Kim }
7167bded2dbSJung-uk Kim 
717b077aed3SPierre Pronchery # define GROUPLIST_INCREMENT   40
718b077aed3SPierre Pronchery # define GROUP_NAME_BUFFER_LENGTH 64
7197bded2dbSJung-uk Kim typedef struct {
720b077aed3SPierre Pronchery     SSL_CTX *ctx;
721b077aed3SPierre Pronchery     size_t gidcnt;
722b077aed3SPierre Pronchery     size_t gidmax;
723b077aed3SPierre Pronchery     uint16_t *gid_arr;
724b077aed3SPierre Pronchery } gid_cb_st;
7257bded2dbSJung-uk Kim 
gid_cb(const char * elem,int len,void * arg)726b077aed3SPierre Pronchery static int gid_cb(const char *elem, int len, void *arg)
7277bded2dbSJung-uk Kim {
728b077aed3SPierre Pronchery     gid_cb_st *garg = arg;
7297bded2dbSJung-uk Kim     size_t i;
730b077aed3SPierre Pronchery     uint16_t gid = 0;
731b077aed3SPierre Pronchery     char etmp[GROUP_NAME_BUFFER_LENGTH];
732b077aed3SPierre Pronchery 
7337bded2dbSJung-uk Kim     if (elem == NULL)
7347bded2dbSJung-uk Kim         return 0;
735b077aed3SPierre Pronchery     if (garg->gidcnt == garg->gidmax) {
736b077aed3SPierre Pronchery         uint16_t *tmp =
73744096ebdSEnji Cooper             OPENSSL_realloc(garg->gid_arr,
73844096ebdSEnji Cooper                             (garg->gidmax + GROUPLIST_INCREMENT) * sizeof(*garg->gid_arr));
739b077aed3SPierre Pronchery         if (tmp == NULL)
7407bded2dbSJung-uk Kim             return 0;
741b077aed3SPierre Pronchery         garg->gidmax += GROUPLIST_INCREMENT;
742b077aed3SPierre Pronchery         garg->gid_arr = tmp;
743b077aed3SPierre Pronchery     }
7447bded2dbSJung-uk Kim     if (len > (int)(sizeof(etmp) - 1))
7457bded2dbSJung-uk Kim         return 0;
7467bded2dbSJung-uk Kim     memcpy(etmp, elem, len);
7477bded2dbSJung-uk Kim     etmp[len] = 0;
748b077aed3SPierre Pronchery 
749b077aed3SPierre Pronchery     gid = tls1_group_name2id(garg->ctx, etmp);
750b077aed3SPierre Pronchery     if (gid == 0) {
751b077aed3SPierre Pronchery         ERR_raise_data(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT,
752b077aed3SPierre Pronchery                        "group '%s' cannot be set", etmp);
7537bded2dbSJung-uk Kim         return 0;
754b077aed3SPierre Pronchery     }
755b077aed3SPierre Pronchery     for (i = 0; i < garg->gidcnt; i++)
756b077aed3SPierre Pronchery         if (garg->gid_arr[i] == gid)
7577bded2dbSJung-uk Kim             return 0;
758b077aed3SPierre Pronchery     garg->gid_arr[garg->gidcnt++] = gid;
7597bded2dbSJung-uk Kim     return 1;
7607bded2dbSJung-uk Kim }
7617bded2dbSJung-uk Kim 
762b077aed3SPierre Pronchery /* Set groups based on a colon separated list */
tls1_set_groups_list(SSL_CTX * ctx,uint16_t ** pext,size_t * pextlen,const char * str)763b077aed3SPierre Pronchery int tls1_set_groups_list(SSL_CTX *ctx, uint16_t **pext, size_t *pextlen,
764b077aed3SPierre Pronchery                          const char *str)
7657bded2dbSJung-uk Kim {
766b077aed3SPierre Pronchery     gid_cb_st gcb;
767b077aed3SPierre Pronchery     uint16_t *tmparr;
768b077aed3SPierre Pronchery     int ret = 0;
769e71b7053SJung-uk Kim 
770b077aed3SPierre Pronchery     gcb.gidcnt = 0;
771b077aed3SPierre Pronchery     gcb.gidmax = GROUPLIST_INCREMENT;
772b077aed3SPierre Pronchery     gcb.gid_arr = OPENSSL_malloc(gcb.gidmax * sizeof(*gcb.gid_arr));
773b077aed3SPierre Pronchery     if (gcb.gid_arr == NULL)
7747bded2dbSJung-uk Kim         return 0;
775b077aed3SPierre Pronchery     gcb.ctx = ctx;
776b077aed3SPierre Pronchery     if (!CONF_parse_list(str, ':', 1, gid_cb, &gcb))
777b077aed3SPierre Pronchery         goto end;
778b077aed3SPierre Pronchery     if (pext == NULL) {
779b077aed3SPierre Pronchery         ret = 1;
780b077aed3SPierre Pronchery         goto end;
7817bded2dbSJung-uk Kim     }
7827bded2dbSJung-uk Kim 
783e71b7053SJung-uk Kim     /*
784b077aed3SPierre Pronchery      * gid_cb ensurse there are no duplicates so we can just go ahead and set
785b077aed3SPierre Pronchery      * the result
786e71b7053SJung-uk Kim      */
787b077aed3SPierre Pronchery     tmparr = OPENSSL_memdup(gcb.gid_arr, gcb.gidcnt * sizeof(*tmparr));
788b077aed3SPierre Pronchery     if (tmparr == NULL)
789b077aed3SPierre Pronchery         goto end;
790b077aed3SPierre Pronchery     OPENSSL_free(*pext);
791b077aed3SPierre Pronchery     *pext = tmparr;
792b077aed3SPierre Pronchery     *pextlen = gcb.gidcnt;
793b077aed3SPierre Pronchery     ret = 1;
794b077aed3SPierre Pronchery  end:
795b077aed3SPierre Pronchery     OPENSSL_free(gcb.gid_arr);
796b077aed3SPierre Pronchery     return ret;
7977bded2dbSJung-uk Kim }
7987bded2dbSJung-uk Kim 
799e71b7053SJung-uk Kim /* Check a group id matches preferences */
tls1_check_group_id(SSL * s,uint16_t group_id,int check_own_groups)800e71b7053SJung-uk Kim int tls1_check_group_id(SSL *s, uint16_t group_id, int check_own_groups)
801e71b7053SJung-uk Kim     {
802e71b7053SJung-uk Kim     const uint16_t *groups;
803e71b7053SJung-uk Kim     size_t groups_len;
804e71b7053SJung-uk Kim 
805e71b7053SJung-uk Kim     if (group_id == 0)
806e71b7053SJung-uk Kim         return 0;
807e71b7053SJung-uk Kim 
808e71b7053SJung-uk Kim     /* Check for Suite B compliance */
809b077aed3SPierre Pronchery     if (tls1_suiteb(s) && s->s3.tmp.new_cipher != NULL) {
810b077aed3SPierre Pronchery         unsigned long cid = s->s3.tmp.new_cipher->id;
811e71b7053SJung-uk Kim 
812e71b7053SJung-uk Kim         if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) {
813e71b7053SJung-uk Kim             if (group_id != TLSEXT_curve_P_256)
814e71b7053SJung-uk Kim                 return 0;
815e71b7053SJung-uk Kim         } else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) {
816e71b7053SJung-uk Kim             if (group_id != TLSEXT_curve_P_384)
817e71b7053SJung-uk Kim                 return 0;
818e71b7053SJung-uk Kim         } else {
819e71b7053SJung-uk Kim             /* Should never happen */
820e71b7053SJung-uk Kim             return 0;
821e71b7053SJung-uk Kim         }
822e71b7053SJung-uk Kim     }
823e71b7053SJung-uk Kim 
824e71b7053SJung-uk Kim     if (check_own_groups) {
825e71b7053SJung-uk Kim         /* Check group is one of our preferences */
826e71b7053SJung-uk Kim         tls1_get_supported_groups(s, &groups, &groups_len);
827e71b7053SJung-uk Kim         if (!tls1_in_list(group_id, groups, groups_len))
828e71b7053SJung-uk Kim             return 0;
829e71b7053SJung-uk Kim     }
830e71b7053SJung-uk Kim 
831b077aed3SPierre Pronchery     if (!tls_group_allowed(s, group_id, SSL_SECOP_CURVE_CHECK))
832e71b7053SJung-uk Kim         return 0;
833e71b7053SJung-uk Kim 
834e71b7053SJung-uk Kim     /* For clients, nothing more to check */
835e71b7053SJung-uk Kim     if (!s->server)
836e71b7053SJung-uk Kim         return 1;
837e71b7053SJung-uk Kim 
838e71b7053SJung-uk Kim     /* Check group is one of peers preferences */
839e71b7053SJung-uk Kim     tls1_get_peer_groups(s, &groups, &groups_len);
840e71b7053SJung-uk Kim 
841e71b7053SJung-uk Kim     /*
842e71b7053SJung-uk Kim      * RFC 4492 does not require the supported elliptic curves extension
843e71b7053SJung-uk Kim      * so if it is not sent we can just choose any curve.
844e71b7053SJung-uk Kim      * It is invalid to send an empty list in the supported groups
845e71b7053SJung-uk Kim      * extension, so groups_len == 0 always means no extension.
846e71b7053SJung-uk Kim      */
847e71b7053SJung-uk Kim     if (groups_len == 0)
848e71b7053SJung-uk Kim             return 1;
849e71b7053SJung-uk Kim     return tls1_in_list(group_id, groups, groups_len);
850e71b7053SJung-uk Kim }
851e71b7053SJung-uk Kim 
tls1_get_formatlist(SSL * s,const unsigned char ** pformats,size_t * num_formats)852e71b7053SJung-uk Kim void tls1_get_formatlist(SSL *s, const unsigned char **pformats,
8537bded2dbSJung-uk Kim                          size_t *num_formats)
8547bded2dbSJung-uk Kim {
8557bded2dbSJung-uk Kim     /*
8567bded2dbSJung-uk Kim      * If we have a custom point format list use it otherwise use default
8577bded2dbSJung-uk Kim      */
858e71b7053SJung-uk Kim     if (s->ext.ecpointformats) {
859e71b7053SJung-uk Kim         *pformats = s->ext.ecpointformats;
860e71b7053SJung-uk Kim         *num_formats = s->ext.ecpointformats_len;
8617bded2dbSJung-uk Kim     } else {
8627bded2dbSJung-uk Kim         *pformats = ecformats_default;
8637bded2dbSJung-uk Kim         /* For Suite B we don't support char2 fields */
8647bded2dbSJung-uk Kim         if (tls1_suiteb(s))
8657bded2dbSJung-uk Kim             *num_formats = sizeof(ecformats_default) - 1;
8667bded2dbSJung-uk Kim         else
8677bded2dbSJung-uk Kim             *num_formats = sizeof(ecformats_default);
8687bded2dbSJung-uk Kim     }
8697bded2dbSJung-uk Kim }
8707bded2dbSJung-uk Kim 
871b077aed3SPierre Pronchery /* Check a key is compatible with compression extension */
tls1_check_pkey_comp(SSL * s,EVP_PKEY * pkey)872b077aed3SPierre Pronchery static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey)
873b077aed3SPierre Pronchery {
874b077aed3SPierre Pronchery     unsigned char comp_id;
875b077aed3SPierre Pronchery     size_t i;
876b077aed3SPierre Pronchery     int point_conv;
877b077aed3SPierre Pronchery 
878b077aed3SPierre Pronchery     /* If not an EC key nothing to check */
879b077aed3SPierre Pronchery     if (!EVP_PKEY_is_a(pkey, "EC"))
880b077aed3SPierre Pronchery         return 1;
881b077aed3SPierre Pronchery 
882b077aed3SPierre Pronchery 
883b077aed3SPierre Pronchery     /* Get required compression id */
884b077aed3SPierre Pronchery     point_conv = EVP_PKEY_get_ec_point_conv_form(pkey);
885b077aed3SPierre Pronchery     if (point_conv == 0)
886b077aed3SPierre Pronchery         return 0;
887b077aed3SPierre Pronchery     if (point_conv == POINT_CONVERSION_UNCOMPRESSED) {
888b077aed3SPierre Pronchery             comp_id = TLSEXT_ECPOINTFORMAT_uncompressed;
889b077aed3SPierre Pronchery     } else if (SSL_IS_TLS13(s)) {
890b077aed3SPierre Pronchery         /*
891b077aed3SPierre Pronchery          * ec_point_formats extension is not used in TLSv1.3 so we ignore
892b077aed3SPierre Pronchery          * this check.
893b077aed3SPierre Pronchery          */
894b077aed3SPierre Pronchery         return 1;
895b077aed3SPierre Pronchery     } else {
896b077aed3SPierre Pronchery         int field_type = EVP_PKEY_get_field_type(pkey);
897b077aed3SPierre Pronchery 
898b077aed3SPierre Pronchery         if (field_type == NID_X9_62_prime_field)
899b077aed3SPierre Pronchery             comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
900b077aed3SPierre Pronchery         else if (field_type == NID_X9_62_characteristic_two_field)
901b077aed3SPierre Pronchery             comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
902b077aed3SPierre Pronchery         else
903b077aed3SPierre Pronchery             return 0;
904b077aed3SPierre Pronchery     }
905b077aed3SPierre Pronchery     /*
906b077aed3SPierre Pronchery      * If point formats extension present check it, otherwise everything is
907b077aed3SPierre Pronchery      * supported (see RFC4492).
908b077aed3SPierre Pronchery      */
909b077aed3SPierre Pronchery     if (s->ext.peer_ecpointformats == NULL)
910b077aed3SPierre Pronchery         return 1;
911b077aed3SPierre Pronchery 
912b077aed3SPierre Pronchery     for (i = 0; i < s->ext.peer_ecpointformats_len; i++) {
913b077aed3SPierre Pronchery         if (s->ext.peer_ecpointformats[i] == comp_id)
914b077aed3SPierre Pronchery             return 1;
915b077aed3SPierre Pronchery     }
916b077aed3SPierre Pronchery     return 0;
917b077aed3SPierre Pronchery }
918b077aed3SPierre Pronchery 
919b077aed3SPierre Pronchery /* Return group id of a key */
tls1_get_group_id(EVP_PKEY * pkey)920b077aed3SPierre Pronchery static uint16_t tls1_get_group_id(EVP_PKEY *pkey)
921b077aed3SPierre Pronchery {
922b077aed3SPierre Pronchery     int curve_nid = ssl_get_EC_curve_nid(pkey);
923b077aed3SPierre Pronchery 
924b077aed3SPierre Pronchery     if (curve_nid == NID_undef)
925b077aed3SPierre Pronchery         return 0;
926b077aed3SPierre Pronchery     return tls1_nid2group_id(curve_nid);
927b077aed3SPierre Pronchery }
928b077aed3SPierre Pronchery 
9297bded2dbSJung-uk Kim /*
9307bded2dbSJung-uk Kim  * Check cert parameters compatible with extensions: currently just checks EC
9317bded2dbSJung-uk Kim  * certificates have compatible curves and compression.
9327bded2dbSJung-uk Kim  */
tls1_check_cert_param(SSL * s,X509 * x,int check_ee_md)933e71b7053SJung-uk Kim static int tls1_check_cert_param(SSL *s, X509 *x, int check_ee_md)
9347bded2dbSJung-uk Kim {
935e71b7053SJung-uk Kim     uint16_t group_id;
9367bded2dbSJung-uk Kim     EVP_PKEY *pkey;
937e71b7053SJung-uk Kim     pkey = X509_get0_pubkey(x);
938e71b7053SJung-uk Kim     if (pkey == NULL)
9397bded2dbSJung-uk Kim         return 0;
9407bded2dbSJung-uk Kim     /* If not EC nothing to do */
941b077aed3SPierre Pronchery     if (!EVP_PKEY_is_a(pkey, "EC"))
9427bded2dbSJung-uk Kim         return 1;
943e71b7053SJung-uk Kim     /* Check compression */
944e71b7053SJung-uk Kim     if (!tls1_check_pkey_comp(s, pkey))
9457bded2dbSJung-uk Kim         return 0;
946e71b7053SJung-uk Kim     group_id = tls1_get_group_id(pkey);
9477bded2dbSJung-uk Kim     /*
948e71b7053SJung-uk Kim      * For a server we allow the certificate to not be in our list of supported
949e71b7053SJung-uk Kim      * groups.
9507bded2dbSJung-uk Kim      */
951e71b7053SJung-uk Kim     if (!tls1_check_group_id(s, group_id, !s->server))
9527bded2dbSJung-uk Kim         return 0;
9537bded2dbSJung-uk Kim     /*
9547bded2dbSJung-uk Kim      * Special case for suite B. We *MUST* sign using SHA256+P-256 or
955e71b7053SJung-uk Kim      * SHA384+P-384.
9567bded2dbSJung-uk Kim      */
957e71b7053SJung-uk Kim     if (check_ee_md && tls1_suiteb(s)) {
9587bded2dbSJung-uk Kim         int check_md;
9597bded2dbSJung-uk Kim         size_t i;
960e71b7053SJung-uk Kim 
9617bded2dbSJung-uk Kim         /* Check to see we have necessary signing algorithm */
962e71b7053SJung-uk Kim         if (group_id == TLSEXT_curve_P_256)
9637bded2dbSJung-uk Kim             check_md = NID_ecdsa_with_SHA256;
964e71b7053SJung-uk Kim         else if (group_id == TLSEXT_curve_P_384)
9657bded2dbSJung-uk Kim             check_md = NID_ecdsa_with_SHA384;
9667bded2dbSJung-uk Kim         else
9677bded2dbSJung-uk Kim             return 0;           /* Should never happen */
968da327cd2SJung-uk Kim         for (i = 0; i < s->shared_sigalgslen; i++) {
969da327cd2SJung-uk Kim             if (check_md == s->shared_sigalgs[i]->sigandhash)
970e71b7053SJung-uk Kim                 return 1;;
971e71b7053SJung-uk Kim         }
9727bded2dbSJung-uk Kim         return 0;
9737bded2dbSJung-uk Kim     }
974e71b7053SJung-uk Kim     return 1;
9757bded2dbSJung-uk Kim }
9767bded2dbSJung-uk Kim 
977e71b7053SJung-uk Kim /*
978e71b7053SJung-uk Kim  * tls1_check_ec_tmp_key - Check EC temporary key compatibility
979e71b7053SJung-uk Kim  * @s: SSL connection
980e71b7053SJung-uk Kim  * @cid: Cipher ID we're considering using
981e71b7053SJung-uk Kim  *
982e71b7053SJung-uk Kim  * Checks that the kECDHE cipher suite we're considering using
983e71b7053SJung-uk Kim  * is compatible with the client extensions.
984e71b7053SJung-uk Kim  *
985e71b7053SJung-uk Kim  * Returns 0 when the cipher can't be used or 1 when it can.
986e71b7053SJung-uk Kim  */
tls1_check_ec_tmp_key(SSL * s,unsigned long cid)9877bded2dbSJung-uk Kim int tls1_check_ec_tmp_key(SSL *s, unsigned long cid)
9887bded2dbSJung-uk Kim {
989e71b7053SJung-uk Kim     /* If not Suite B just need a shared group */
990e71b7053SJung-uk Kim     if (!tls1_suiteb(s))
991e71b7053SJung-uk Kim         return tls1_shared_group(s, 0) != 0;
9927bded2dbSJung-uk Kim     /*
9937bded2dbSJung-uk Kim      * If Suite B, AES128 MUST use P-256 and AES256 MUST use P-384, no other
9947bded2dbSJung-uk Kim      * curves permitted.
9957bded2dbSJung-uk Kim      */
9967bded2dbSJung-uk Kim     if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
997e71b7053SJung-uk Kim         return tls1_check_group_id(s, TLSEXT_curve_P_256, 1);
998e71b7053SJung-uk Kim     if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
999e71b7053SJung-uk Kim         return tls1_check_group_id(s, TLSEXT_curve_P_384, 1);
10007bded2dbSJung-uk Kim 
10017bded2dbSJung-uk Kim     return 0;
10027bded2dbSJung-uk Kim }
10037bded2dbSJung-uk Kim 
1004e71b7053SJung-uk Kim /* Default sigalg schemes */
1005e71b7053SJung-uk Kim static const uint16_t tls12_sigalgs[] = {
1006e71b7053SJung-uk Kim     TLSEXT_SIGALG_ecdsa_secp256r1_sha256,
1007e71b7053SJung-uk Kim     TLSEXT_SIGALG_ecdsa_secp384r1_sha384,
1008e71b7053SJung-uk Kim     TLSEXT_SIGALG_ecdsa_secp521r1_sha512,
1009e71b7053SJung-uk Kim     TLSEXT_SIGALG_ed25519,
1010e71b7053SJung-uk Kim     TLSEXT_SIGALG_ed448,
1011e71b7053SJung-uk Kim 
1012e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pss_pss_sha256,
1013e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pss_pss_sha384,
1014e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pss_pss_sha512,
1015e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pss_rsae_sha256,
1016e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pss_rsae_sha384,
1017e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pss_rsae_sha512,
1018e71b7053SJung-uk Kim 
1019e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pkcs1_sha256,
1020e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pkcs1_sha384,
1021e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pkcs1_sha512,
1022e71b7053SJung-uk Kim 
1023e71b7053SJung-uk Kim     TLSEXT_SIGALG_ecdsa_sha224,
1024e71b7053SJung-uk Kim     TLSEXT_SIGALG_ecdsa_sha1,
1025b077aed3SPierre Pronchery 
1026e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pkcs1_sha224,
1027e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pkcs1_sha1,
1028b077aed3SPierre Pronchery 
1029e71b7053SJung-uk Kim     TLSEXT_SIGALG_dsa_sha224,
1030e71b7053SJung-uk Kim     TLSEXT_SIGALG_dsa_sha1,
1031e71b7053SJung-uk Kim 
1032e71b7053SJung-uk Kim     TLSEXT_SIGALG_dsa_sha256,
1033e71b7053SJung-uk Kim     TLSEXT_SIGALG_dsa_sha384,
1034e71b7053SJung-uk Kim     TLSEXT_SIGALG_dsa_sha512,
1035b077aed3SPierre Pronchery 
1036e71b7053SJung-uk Kim #ifndef OPENSSL_NO_GOST
1037b077aed3SPierre Pronchery     TLSEXT_SIGALG_gostr34102012_256_intrinsic,
1038b077aed3SPierre Pronchery     TLSEXT_SIGALG_gostr34102012_512_intrinsic,
1039e71b7053SJung-uk Kim     TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256,
1040e71b7053SJung-uk Kim     TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512,
1041e71b7053SJung-uk Kim     TLSEXT_SIGALG_gostr34102001_gostr3411,
1042e71b7053SJung-uk Kim #endif
1043e71b7053SJung-uk Kim };
1044e71b7053SJung-uk Kim 
1045b077aed3SPierre Pronchery 
1046e71b7053SJung-uk Kim static const uint16_t suiteb_sigalgs[] = {
1047e71b7053SJung-uk Kim     TLSEXT_SIGALG_ecdsa_secp256r1_sha256,
1048e71b7053SJung-uk Kim     TLSEXT_SIGALG_ecdsa_secp384r1_sha384
1049e71b7053SJung-uk Kim };
1050e71b7053SJung-uk Kim 
1051e71b7053SJung-uk Kim static const SIGALG_LOOKUP sigalg_lookup_tbl[] = {
1052e71b7053SJung-uk Kim     {"ecdsa_secp256r1_sha256", TLSEXT_SIGALG_ecdsa_secp256r1_sha256,
1053e71b7053SJung-uk Kim      NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
1054b077aed3SPierre Pronchery      NID_ecdsa_with_SHA256, NID_X9_62_prime256v1, 1},
1055e71b7053SJung-uk Kim     {"ecdsa_secp384r1_sha384", TLSEXT_SIGALG_ecdsa_secp384r1_sha384,
1056e71b7053SJung-uk Kim      NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
1057b077aed3SPierre Pronchery      NID_ecdsa_with_SHA384, NID_secp384r1, 1},
1058e71b7053SJung-uk Kim     {"ecdsa_secp521r1_sha512", TLSEXT_SIGALG_ecdsa_secp521r1_sha512,
1059e71b7053SJung-uk Kim      NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
1060b077aed3SPierre Pronchery      NID_ecdsa_with_SHA512, NID_secp521r1, 1},
1061e71b7053SJung-uk Kim     {"ed25519", TLSEXT_SIGALG_ed25519,
1062e71b7053SJung-uk Kim      NID_undef, -1, EVP_PKEY_ED25519, SSL_PKEY_ED25519,
1063b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1064e71b7053SJung-uk Kim     {"ed448", TLSEXT_SIGALG_ed448,
1065e71b7053SJung-uk Kim      NID_undef, -1, EVP_PKEY_ED448, SSL_PKEY_ED448,
1066b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1067e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_ecdsa_sha224,
1068e71b7053SJung-uk Kim      NID_sha224, SSL_MD_SHA224_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
1069b077aed3SPierre Pronchery      NID_ecdsa_with_SHA224, NID_undef, 1},
1070e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_ecdsa_sha1,
1071e71b7053SJung-uk Kim      NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
1072b077aed3SPierre Pronchery      NID_ecdsa_with_SHA1, NID_undef, 1},
1073e71b7053SJung-uk Kim     {"rsa_pss_rsae_sha256", TLSEXT_SIGALG_rsa_pss_rsae_sha256,
1074e71b7053SJung-uk Kim      NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA,
1075b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1076e71b7053SJung-uk Kim     {"rsa_pss_rsae_sha384", TLSEXT_SIGALG_rsa_pss_rsae_sha384,
1077e71b7053SJung-uk Kim      NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA,
1078b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1079e71b7053SJung-uk Kim     {"rsa_pss_rsae_sha512", TLSEXT_SIGALG_rsa_pss_rsae_sha512,
1080e71b7053SJung-uk Kim      NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA,
1081b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1082e71b7053SJung-uk Kim     {"rsa_pss_pss_sha256", TLSEXT_SIGALG_rsa_pss_pss_sha256,
1083e71b7053SJung-uk Kim      NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN,
1084b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1085e71b7053SJung-uk Kim     {"rsa_pss_pss_sha384", TLSEXT_SIGALG_rsa_pss_pss_sha384,
1086e71b7053SJung-uk Kim      NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN,
1087b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1088e71b7053SJung-uk Kim     {"rsa_pss_pss_sha512", TLSEXT_SIGALG_rsa_pss_pss_sha512,
1089e71b7053SJung-uk Kim      NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN,
1090b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1091e71b7053SJung-uk Kim     {"rsa_pkcs1_sha256", TLSEXT_SIGALG_rsa_pkcs1_sha256,
1092e71b7053SJung-uk Kim      NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
1093b077aed3SPierre Pronchery      NID_sha256WithRSAEncryption, NID_undef, 1},
1094e71b7053SJung-uk Kim     {"rsa_pkcs1_sha384", TLSEXT_SIGALG_rsa_pkcs1_sha384,
1095e71b7053SJung-uk Kim      NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
1096b077aed3SPierre Pronchery      NID_sha384WithRSAEncryption, NID_undef, 1},
1097e71b7053SJung-uk Kim     {"rsa_pkcs1_sha512", TLSEXT_SIGALG_rsa_pkcs1_sha512,
1098e71b7053SJung-uk Kim      NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
1099b077aed3SPierre Pronchery      NID_sha512WithRSAEncryption, NID_undef, 1},
1100e71b7053SJung-uk Kim     {"rsa_pkcs1_sha224", TLSEXT_SIGALG_rsa_pkcs1_sha224,
1101e71b7053SJung-uk Kim      NID_sha224, SSL_MD_SHA224_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
1102b077aed3SPierre Pronchery      NID_sha224WithRSAEncryption, NID_undef, 1},
1103e71b7053SJung-uk Kim     {"rsa_pkcs1_sha1", TLSEXT_SIGALG_rsa_pkcs1_sha1,
1104e71b7053SJung-uk Kim      NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
1105b077aed3SPierre Pronchery      NID_sha1WithRSAEncryption, NID_undef, 1},
1106e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_dsa_sha256,
1107e71b7053SJung-uk Kim      NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
1108b077aed3SPierre Pronchery      NID_dsa_with_SHA256, NID_undef, 1},
1109e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_dsa_sha384,
1110e71b7053SJung-uk Kim      NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
1111b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1112e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_dsa_sha512,
1113e71b7053SJung-uk Kim      NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
1114b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1115e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_dsa_sha224,
1116e71b7053SJung-uk Kim      NID_sha224, SSL_MD_SHA224_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
1117b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1118e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_dsa_sha1,
1119e71b7053SJung-uk Kim      NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
1120b077aed3SPierre Pronchery      NID_dsaWithSHA1, NID_undef, 1},
1121e71b7053SJung-uk Kim #ifndef OPENSSL_NO_GOST
1122b077aed3SPierre Pronchery     {NULL, TLSEXT_SIGALG_gostr34102012_256_intrinsic,
1123b077aed3SPierre Pronchery      NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX,
1124b077aed3SPierre Pronchery      NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256,
1125b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1126b077aed3SPierre Pronchery     {NULL, TLSEXT_SIGALG_gostr34102012_512_intrinsic,
1127b077aed3SPierre Pronchery      NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX,
1128b077aed3SPierre Pronchery      NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512,
1129b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1130e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256,
1131e71b7053SJung-uk Kim      NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX,
1132e71b7053SJung-uk Kim      NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256,
1133b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1134e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512,
1135e71b7053SJung-uk Kim      NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX,
1136e71b7053SJung-uk Kim      NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512,
1137b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1138e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_gostr34102001_gostr3411,
1139e71b7053SJung-uk Kim      NID_id_GostR3411_94, SSL_MD_GOST94_IDX,
1140e71b7053SJung-uk Kim      NID_id_GostR3410_2001, SSL_PKEY_GOST01,
1141b077aed3SPierre Pronchery      NID_undef, NID_undef, 1}
1142e71b7053SJung-uk Kim #endif
1143e71b7053SJung-uk Kim };
1144e71b7053SJung-uk Kim /* Legacy sigalgs for TLS < 1.2 RSA TLS signatures */
1145e71b7053SJung-uk Kim static const SIGALG_LOOKUP legacy_rsa_sigalg = {
1146e71b7053SJung-uk Kim     "rsa_pkcs1_md5_sha1", 0,
1147e71b7053SJung-uk Kim      NID_md5_sha1, SSL_MD_MD5_SHA1_IDX,
1148e71b7053SJung-uk Kim      EVP_PKEY_RSA, SSL_PKEY_RSA,
1149b077aed3SPierre Pronchery      NID_undef, NID_undef, 1
1150e71b7053SJung-uk Kim };
11511f13597dSJung-uk Kim 
11526f9291ceSJung-uk Kim /*
1153e71b7053SJung-uk Kim  * Default signature algorithm values used if signature algorithms not present.
1154e71b7053SJung-uk Kim  * From RFC5246. Note: order must match certificate index order.
11551f13597dSJung-uk Kim  */
1156e71b7053SJung-uk Kim static const uint16_t tls_default_sigalg[] = {
1157e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pkcs1_sha1, /* SSL_PKEY_RSA */
1158e71b7053SJung-uk Kim     0, /* SSL_PKEY_RSA_PSS_SIGN */
1159e71b7053SJung-uk Kim     TLSEXT_SIGALG_dsa_sha1, /* SSL_PKEY_DSA_SIGN */
1160e71b7053SJung-uk Kim     TLSEXT_SIGALG_ecdsa_sha1, /* SSL_PKEY_ECC */
1161e71b7053SJung-uk Kim     TLSEXT_SIGALG_gostr34102001_gostr3411, /* SSL_PKEY_GOST01 */
1162b077aed3SPierre Pronchery     TLSEXT_SIGALG_gostr34102012_256_intrinsic, /* SSL_PKEY_GOST12_256 */
1163b077aed3SPierre Pronchery     TLSEXT_SIGALG_gostr34102012_512_intrinsic, /* SSL_PKEY_GOST12_512 */
1164e71b7053SJung-uk Kim     0, /* SSL_PKEY_ED25519 */
1165e71b7053SJung-uk Kim     0, /* SSL_PKEY_ED448 */
11661f13597dSJung-uk Kim };
11671f13597dSJung-uk Kim 
ssl_setup_sig_algs(SSL_CTX * ctx)1168b077aed3SPierre Pronchery int ssl_setup_sig_algs(SSL_CTX *ctx)
1169e71b7053SJung-uk Kim {
1170e71b7053SJung-uk Kim     size_t i;
1171b077aed3SPierre Pronchery     const SIGALG_LOOKUP *lu;
1172b077aed3SPierre Pronchery     SIGALG_LOOKUP *cache
1173b077aed3SPierre Pronchery         = OPENSSL_malloc(sizeof(*lu) * OSSL_NELEM(sigalg_lookup_tbl));
1174b077aed3SPierre Pronchery     EVP_PKEY *tmpkey = EVP_PKEY_new();
1175b077aed3SPierre Pronchery     int ret = 0;
1176e71b7053SJung-uk Kim 
1177b077aed3SPierre Pronchery     if (cache == NULL || tmpkey == NULL)
1178b077aed3SPierre Pronchery         goto err;
1179b077aed3SPierre Pronchery 
1180b077aed3SPierre Pronchery     ERR_set_mark();
1181b077aed3SPierre Pronchery     for (i = 0, lu = sigalg_lookup_tbl;
1182b077aed3SPierre Pronchery          i < OSSL_NELEM(sigalg_lookup_tbl); lu++, i++) {
1183b077aed3SPierre Pronchery         EVP_PKEY_CTX *pctx;
1184b077aed3SPierre Pronchery 
1185b077aed3SPierre Pronchery         cache[i] = *lu;
1186b077aed3SPierre Pronchery 
1187b077aed3SPierre Pronchery         /*
1188b077aed3SPierre Pronchery          * Check hash is available.
1189b077aed3SPierre Pronchery          * This test is not perfect. A provider could have support
1190b077aed3SPierre Pronchery          * for a signature scheme, but not a particular hash. However the hash
1191b077aed3SPierre Pronchery          * could be available from some other loaded provider. In that case it
1192b077aed3SPierre Pronchery          * could be that the signature is available, and the hash is available
1193b077aed3SPierre Pronchery          * independently - but not as a combination. We ignore this for now.
1194b077aed3SPierre Pronchery          */
1195b077aed3SPierre Pronchery         if (lu->hash != NID_undef
1196b077aed3SPierre Pronchery                 && ctx->ssl_digest_methods[lu->hash_idx] == NULL) {
1197b077aed3SPierre Pronchery             cache[i].enabled = 0;
1198b077aed3SPierre Pronchery             continue;
1199b077aed3SPierre Pronchery         }
1200b077aed3SPierre Pronchery 
1201b077aed3SPierre Pronchery         if (!EVP_PKEY_set_type(tmpkey, lu->sig)) {
1202b077aed3SPierre Pronchery             cache[i].enabled = 0;
1203b077aed3SPierre Pronchery             continue;
1204b077aed3SPierre Pronchery         }
1205b077aed3SPierre Pronchery         pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, tmpkey, ctx->propq);
1206b077aed3SPierre Pronchery         /* If unable to create pctx we assume the sig algorithm is unavailable */
1207b077aed3SPierre Pronchery         if (pctx == NULL)
1208b077aed3SPierre Pronchery             cache[i].enabled = 0;
1209b077aed3SPierre Pronchery         EVP_PKEY_CTX_free(pctx);
1210b077aed3SPierre Pronchery     }
1211b077aed3SPierre Pronchery     ERR_pop_to_mark();
1212b077aed3SPierre Pronchery     ctx->sigalg_lookup_cache = cache;
1213b077aed3SPierre Pronchery     cache = NULL;
1214b077aed3SPierre Pronchery 
1215b077aed3SPierre Pronchery     ret = 1;
1216b077aed3SPierre Pronchery  err:
1217b077aed3SPierre Pronchery     OPENSSL_free(cache);
1218b077aed3SPierre Pronchery     EVP_PKEY_free(tmpkey);
1219b077aed3SPierre Pronchery     return ret;
1220b077aed3SPierre Pronchery }
1221b077aed3SPierre Pronchery 
1222b077aed3SPierre Pronchery /* Lookup TLS signature algorithm */
tls1_lookup_sigalg(const SSL * s,uint16_t sigalg)1223b077aed3SPierre Pronchery static const SIGALG_LOOKUP *tls1_lookup_sigalg(const SSL *s, uint16_t sigalg)
1224b077aed3SPierre Pronchery {
1225b077aed3SPierre Pronchery     size_t i;
1226b077aed3SPierre Pronchery     const SIGALG_LOOKUP *lu;
1227b077aed3SPierre Pronchery 
1228b077aed3SPierre Pronchery     for (i = 0, lu = s->ctx->sigalg_lookup_cache;
1229b077aed3SPierre Pronchery          /* cache should have the same number of elements as sigalg_lookup_tbl */
1230b077aed3SPierre Pronchery          i < OSSL_NELEM(sigalg_lookup_tbl);
1231b077aed3SPierre Pronchery          lu++, i++) {
1232b077aed3SPierre Pronchery         if (lu->sigalg == sigalg) {
1233b077aed3SPierre Pronchery             if (!lu->enabled)
1234b077aed3SPierre Pronchery                 return NULL;
1235b077aed3SPierre Pronchery             return lu;
1236b077aed3SPierre Pronchery         }
1237e71b7053SJung-uk Kim     }
1238e71b7053SJung-uk Kim     return NULL;
1239e71b7053SJung-uk Kim }
1240e71b7053SJung-uk Kim /* Lookup hash: return 0 if invalid or not enabled */
tls1_lookup_md(SSL_CTX * ctx,const SIGALG_LOOKUP * lu,const EVP_MD ** pmd)1241b077aed3SPierre Pronchery int tls1_lookup_md(SSL_CTX *ctx, const SIGALG_LOOKUP *lu, const EVP_MD **pmd)
1242e71b7053SJung-uk Kim {
1243e71b7053SJung-uk Kim     const EVP_MD *md;
1244e71b7053SJung-uk Kim     if (lu == NULL)
1245e71b7053SJung-uk Kim         return 0;
1246e71b7053SJung-uk Kim     /* lu->hash == NID_undef means no associated digest */
1247e71b7053SJung-uk Kim     if (lu->hash == NID_undef) {
1248e71b7053SJung-uk Kim         md = NULL;
1249e71b7053SJung-uk Kim     } else {
1250b077aed3SPierre Pronchery         md = ssl_md(ctx, lu->hash_idx);
1251e71b7053SJung-uk Kim         if (md == NULL)
1252e71b7053SJung-uk Kim             return 0;
1253e71b7053SJung-uk Kim     }
1254e71b7053SJung-uk Kim     if (pmd)
1255e71b7053SJung-uk Kim         *pmd = md;
1256e71b7053SJung-uk Kim     return 1;
1257e71b7053SJung-uk Kim }
1258e71b7053SJung-uk Kim 
1259e71b7053SJung-uk Kim /*
1260e71b7053SJung-uk Kim  * Check if key is large enough to generate RSA-PSS signature.
1261e71b7053SJung-uk Kim  *
1262e71b7053SJung-uk Kim  * The key must greater than or equal to 2 * hash length + 2.
1263e71b7053SJung-uk Kim  * SHA512 has a hash length of 64 bytes, which is incompatible
1264e71b7053SJung-uk Kim  * with a 128 byte (1024 bit) key.
1265e71b7053SJung-uk Kim  */
1266b077aed3SPierre Pronchery #define RSA_PSS_MINIMUM_KEY_SIZE(md) (2 * EVP_MD_get_size(md) + 2)
rsa_pss_check_min_key_size(SSL_CTX * ctx,const EVP_PKEY * pkey,const SIGALG_LOOKUP * lu)1267b077aed3SPierre Pronchery static int rsa_pss_check_min_key_size(SSL_CTX *ctx, const EVP_PKEY *pkey,
1268b077aed3SPierre Pronchery                                       const SIGALG_LOOKUP *lu)
1269e71b7053SJung-uk Kim {
1270e71b7053SJung-uk Kim     const EVP_MD *md;
1271e71b7053SJung-uk Kim 
1272b077aed3SPierre Pronchery     if (pkey == NULL)
1273e71b7053SJung-uk Kim         return 0;
1274b077aed3SPierre Pronchery     if (!tls1_lookup_md(ctx, lu, &md) || md == NULL)
1275e71b7053SJung-uk Kim         return 0;
1276b077aed3SPierre Pronchery     if (EVP_PKEY_get_size(pkey) < RSA_PSS_MINIMUM_KEY_SIZE(md))
1277e71b7053SJung-uk Kim         return 0;
1278e71b7053SJung-uk Kim     return 1;
1279e71b7053SJung-uk Kim }
1280e71b7053SJung-uk Kim 
1281e71b7053SJung-uk Kim /*
128217f01e99SJung-uk Kim  * Returns a signature algorithm when the peer did not send a list of supported
128317f01e99SJung-uk Kim  * signature algorithms. The signature algorithm is fixed for the certificate
128417f01e99SJung-uk Kim  * type. |idx| is a certificate type index (SSL_PKEY_*). When |idx| is -1 the
128517f01e99SJung-uk Kim  * certificate type from |s| will be used.
128617f01e99SJung-uk Kim  * Returns the signature algorithm to use, or NULL on error.
1287e71b7053SJung-uk Kim  */
tls1_get_legacy_sigalg(const SSL * s,int idx)1288e71b7053SJung-uk Kim static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx)
1289e71b7053SJung-uk Kim {
1290e71b7053SJung-uk Kim     if (idx == -1) {
1291e71b7053SJung-uk Kim         if (s->server) {
1292e71b7053SJung-uk Kim             size_t i;
1293e71b7053SJung-uk Kim 
1294e71b7053SJung-uk Kim             /* Work out index corresponding to ciphersuite */
1295e71b7053SJung-uk Kim             for (i = 0; i < SSL_PKEY_NUM; i++) {
1296e71b7053SJung-uk Kim                 const SSL_CERT_LOOKUP *clu = ssl_cert_lookup_by_idx(i);
1297e71b7053SJung-uk Kim 
1298b077aed3SPierre Pronchery                 if (clu == NULL)
1299b077aed3SPierre Pronchery                     continue;
1300b077aed3SPierre Pronchery                 if (clu->amask & s->s3.tmp.new_cipher->algorithm_auth) {
1301e71b7053SJung-uk Kim                     idx = i;
1302e71b7053SJung-uk Kim                     break;
1303e71b7053SJung-uk Kim                 }
1304e71b7053SJung-uk Kim             }
1305e71b7053SJung-uk Kim 
1306e71b7053SJung-uk Kim             /*
1307e71b7053SJung-uk Kim              * Some GOST ciphersuites allow more than one signature algorithms
1308e71b7053SJung-uk Kim              * */
1309b077aed3SPierre Pronchery             if (idx == SSL_PKEY_GOST01 && s->s3.tmp.new_cipher->algorithm_auth != SSL_aGOST01) {
1310e71b7053SJung-uk Kim                 int real_idx;
1311e71b7053SJung-uk Kim 
1312e71b7053SJung-uk Kim                 for (real_idx = SSL_PKEY_GOST12_512; real_idx >= SSL_PKEY_GOST01;
1313e71b7053SJung-uk Kim                      real_idx--) {
1314e71b7053SJung-uk Kim                     if (s->cert->pkeys[real_idx].privatekey != NULL) {
1315e71b7053SJung-uk Kim                         idx = real_idx;
1316e71b7053SJung-uk Kim                         break;
1317e71b7053SJung-uk Kim                     }
1318e71b7053SJung-uk Kim                 }
1319e71b7053SJung-uk Kim             }
1320b077aed3SPierre Pronchery             /*
1321b077aed3SPierre Pronchery              * As both SSL_PKEY_GOST12_512 and SSL_PKEY_GOST12_256 indices can be used
1322b077aed3SPierre Pronchery              * with new (aGOST12-only) ciphersuites, we should find out which one is available really.
1323b077aed3SPierre Pronchery              */
1324b077aed3SPierre Pronchery             else if (idx == SSL_PKEY_GOST12_256) {
1325b077aed3SPierre Pronchery                 int real_idx;
1326b077aed3SPierre Pronchery 
1327b077aed3SPierre Pronchery                 for (real_idx = SSL_PKEY_GOST12_512; real_idx >= SSL_PKEY_GOST12_256;
1328b077aed3SPierre Pronchery                      real_idx--) {
1329b077aed3SPierre Pronchery                      if (s->cert->pkeys[real_idx].privatekey != NULL) {
1330b077aed3SPierre Pronchery                          idx = real_idx;
1331b077aed3SPierre Pronchery                          break;
1332b077aed3SPierre Pronchery                      }
1333b077aed3SPierre Pronchery                 }
1334b077aed3SPierre Pronchery             }
1335e71b7053SJung-uk Kim         } else {
1336e71b7053SJung-uk Kim             idx = s->cert->key - s->cert->pkeys;
1337e71b7053SJung-uk Kim         }
1338e71b7053SJung-uk Kim     }
1339e71b7053SJung-uk Kim     if (idx < 0 || idx >= (int)OSSL_NELEM(tls_default_sigalg))
1340e71b7053SJung-uk Kim         return NULL;
1341e71b7053SJung-uk Kim     if (SSL_USE_SIGALGS(s) || idx != SSL_PKEY_RSA) {
1342b077aed3SPierre Pronchery         const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, tls_default_sigalg[idx]);
1343e71b7053SJung-uk Kim 
1344b077aed3SPierre Pronchery         if (lu == NULL)
1345b077aed3SPierre Pronchery             return NULL;
1346b077aed3SPierre Pronchery         if (!tls1_lookup_md(s->ctx, lu, NULL))
1347e71b7053SJung-uk Kim             return NULL;
134817f01e99SJung-uk Kim         if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, lu))
134917f01e99SJung-uk Kim             return NULL;
1350e71b7053SJung-uk Kim         return lu;
1351e71b7053SJung-uk Kim     }
135217f01e99SJung-uk Kim     if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, &legacy_rsa_sigalg))
135317f01e99SJung-uk Kim         return NULL;
1354e71b7053SJung-uk Kim     return &legacy_rsa_sigalg;
1355e71b7053SJung-uk Kim }
1356e71b7053SJung-uk Kim /* Set peer sigalg based key type */
tls1_set_peer_legacy_sigalg(SSL * s,const EVP_PKEY * pkey)1357e71b7053SJung-uk Kim int tls1_set_peer_legacy_sigalg(SSL *s, const EVP_PKEY *pkey)
1358e71b7053SJung-uk Kim {
1359e71b7053SJung-uk Kim     size_t idx;
1360e71b7053SJung-uk Kim     const SIGALG_LOOKUP *lu;
1361e71b7053SJung-uk Kim 
1362e71b7053SJung-uk Kim     if (ssl_cert_lookup_by_pkey(pkey, &idx) == NULL)
1363e71b7053SJung-uk Kim         return 0;
1364e71b7053SJung-uk Kim     lu = tls1_get_legacy_sigalg(s, idx);
1365e71b7053SJung-uk Kim     if (lu == NULL)
1366e71b7053SJung-uk Kim         return 0;
1367b077aed3SPierre Pronchery     s->s3.tmp.peer_sigalg = lu;
1368e71b7053SJung-uk Kim     return 1;
1369e71b7053SJung-uk Kim }
1370e71b7053SJung-uk Kim 
tls12_get_psigalgs(SSL * s,int sent,const uint16_t ** psigs)1371e71b7053SJung-uk Kim size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs)
13721f13597dSJung-uk Kim {
13737bded2dbSJung-uk Kim     /*
13747bded2dbSJung-uk Kim      * If Suite B mode use Suite B sigalgs only, ignore any other
13757bded2dbSJung-uk Kim      * preferences.
13767bded2dbSJung-uk Kim      */
13777bded2dbSJung-uk Kim     switch (tls1_suiteb(s)) {
13787bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_128_LOS:
13797bded2dbSJung-uk Kim         *psigs = suiteb_sigalgs;
1380e71b7053SJung-uk Kim         return OSSL_NELEM(suiteb_sigalgs);
13817bded2dbSJung-uk Kim 
13827bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:
13837bded2dbSJung-uk Kim         *psigs = suiteb_sigalgs;
1384e71b7053SJung-uk Kim         return 1;
13857bded2dbSJung-uk Kim 
13867bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_192_LOS:
1387e71b7053SJung-uk Kim         *psigs = suiteb_sigalgs + 1;
1388e71b7053SJung-uk Kim         return 1;
13897bded2dbSJung-uk Kim     }
1390e71b7053SJung-uk Kim     /*
1391e71b7053SJung-uk Kim      *  We use client_sigalgs (if not NULL) if we're a server
1392e71b7053SJung-uk Kim      *  and sending a certificate request or if we're a client and
1393e71b7053SJung-uk Kim      *  determining which shared algorithm to use.
1394e71b7053SJung-uk Kim      */
1395e71b7053SJung-uk Kim     if ((s->server == sent) && s->cert->client_sigalgs != NULL) {
13967bded2dbSJung-uk Kim         *psigs = s->cert->client_sigalgs;
13977bded2dbSJung-uk Kim         return s->cert->client_sigalgslen;
13987bded2dbSJung-uk Kim     } else if (s->cert->conf_sigalgs) {
13997bded2dbSJung-uk Kim         *psigs = s->cert->conf_sigalgs;
14007bded2dbSJung-uk Kim         return s->cert->conf_sigalgslen;
14017bded2dbSJung-uk Kim     } else {
14027bded2dbSJung-uk Kim         *psigs = tls12_sigalgs;
1403e71b7053SJung-uk Kim         return OSSL_NELEM(tls12_sigalgs);
14047bded2dbSJung-uk Kim     }
14057bded2dbSJung-uk Kim }
14067bded2dbSJung-uk Kim 
1407c9cf7b5cSJung-uk Kim /*
1408c9cf7b5cSJung-uk Kim  * Called by servers only. Checks that we have a sig alg that supports the
1409c9cf7b5cSJung-uk Kim  * specified EC curve.
1410c9cf7b5cSJung-uk Kim  */
tls_check_sigalg_curve(const SSL * s,int curve)1411c9cf7b5cSJung-uk Kim int tls_check_sigalg_curve(const SSL *s, int curve)
1412c9cf7b5cSJung-uk Kim {
1413c9cf7b5cSJung-uk Kim    const uint16_t *sigs;
1414c9cf7b5cSJung-uk Kim    size_t siglen, i;
1415c9cf7b5cSJung-uk Kim 
1416c9cf7b5cSJung-uk Kim     if (s->cert->conf_sigalgs) {
1417c9cf7b5cSJung-uk Kim         sigs = s->cert->conf_sigalgs;
1418c9cf7b5cSJung-uk Kim         siglen = s->cert->conf_sigalgslen;
1419c9cf7b5cSJung-uk Kim     } else {
1420c9cf7b5cSJung-uk Kim         sigs = tls12_sigalgs;
1421c9cf7b5cSJung-uk Kim         siglen = OSSL_NELEM(tls12_sigalgs);
1422c9cf7b5cSJung-uk Kim     }
1423c9cf7b5cSJung-uk Kim 
1424c9cf7b5cSJung-uk Kim     for (i = 0; i < siglen; i++) {
1425b077aed3SPierre Pronchery         const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, sigs[i]);
1426c9cf7b5cSJung-uk Kim 
1427c9cf7b5cSJung-uk Kim         if (lu == NULL)
1428c9cf7b5cSJung-uk Kim             continue;
1429c9cf7b5cSJung-uk Kim         if (lu->sig == EVP_PKEY_EC
1430c9cf7b5cSJung-uk Kim                 && lu->curve != NID_undef
1431c9cf7b5cSJung-uk Kim                 && curve == lu->curve)
1432c9cf7b5cSJung-uk Kim             return 1;
1433c9cf7b5cSJung-uk Kim     }
1434c9cf7b5cSJung-uk Kim 
1435c9cf7b5cSJung-uk Kim     return 0;
1436c9cf7b5cSJung-uk Kim }
1437c9cf7b5cSJung-uk Kim 
14387bded2dbSJung-uk Kim /*
143917f01e99SJung-uk Kim  * Return the number of security bits for the signature algorithm, or 0 on
144017f01e99SJung-uk Kim  * error.
144117f01e99SJung-uk Kim  */
sigalg_security_bits(SSL_CTX * ctx,const SIGALG_LOOKUP * lu)1442b077aed3SPierre Pronchery static int sigalg_security_bits(SSL_CTX *ctx, const SIGALG_LOOKUP *lu)
144317f01e99SJung-uk Kim {
144417f01e99SJung-uk Kim     const EVP_MD *md = NULL;
144517f01e99SJung-uk Kim     int secbits = 0;
144617f01e99SJung-uk Kim 
1447b077aed3SPierre Pronchery     if (!tls1_lookup_md(ctx, lu, &md))
144817f01e99SJung-uk Kim         return 0;
144917f01e99SJung-uk Kim     if (md != NULL)
145017f01e99SJung-uk Kim     {
1451b077aed3SPierre Pronchery         int md_type = EVP_MD_get_type(md);
1452b077aed3SPierre Pronchery 
145317f01e99SJung-uk Kim         /* Security bits: half digest bits */
1454b077aed3SPierre Pronchery         secbits = EVP_MD_get_size(md) * 4;
1455b077aed3SPierre Pronchery         /*
1456b077aed3SPierre Pronchery          * SHA1 and MD5 are known to be broken. Reduce security bits so that
1457b077aed3SPierre Pronchery          * they're no longer accepted at security level 1. The real values don't
1458b077aed3SPierre Pronchery          * really matter as long as they're lower than 80, which is our
1459b077aed3SPierre Pronchery          * security level 1.
1460b077aed3SPierre Pronchery          * https://eprint.iacr.org/2020/014 puts a chosen-prefix attack for
1461b077aed3SPierre Pronchery          * SHA1 at 2^63.4 and MD5+SHA1 at 2^67.2
1462b077aed3SPierre Pronchery          * https://documents.epfl.ch/users/l/le/lenstra/public/papers/lat.pdf
1463b077aed3SPierre Pronchery          * puts a chosen-prefix attack for MD5 at 2^39.
1464b077aed3SPierre Pronchery          */
1465b077aed3SPierre Pronchery         if (md_type == NID_sha1)
1466b077aed3SPierre Pronchery             secbits = 64;
1467b077aed3SPierre Pronchery         else if (md_type == NID_md5_sha1)
1468b077aed3SPierre Pronchery             secbits = 67;
1469b077aed3SPierre Pronchery         else if (md_type == NID_md5)
1470b077aed3SPierre Pronchery             secbits = 39;
147117f01e99SJung-uk Kim     } else {
147217f01e99SJung-uk Kim         /* Values from https://tools.ietf.org/html/rfc8032#section-8.5 */
147317f01e99SJung-uk Kim         if (lu->sigalg == TLSEXT_SIGALG_ed25519)
147417f01e99SJung-uk Kim             secbits = 128;
147517f01e99SJung-uk Kim         else if (lu->sigalg == TLSEXT_SIGALG_ed448)
147617f01e99SJung-uk Kim             secbits = 224;
147717f01e99SJung-uk Kim     }
147817f01e99SJung-uk Kim     return secbits;
147917f01e99SJung-uk Kim }
148017f01e99SJung-uk Kim 
148117f01e99SJung-uk Kim /*
14827bded2dbSJung-uk Kim  * Check signature algorithm is consistent with sent supported signature
1483e71b7053SJung-uk Kim  * algorithms and if so set relevant digest and signature scheme in
1484e71b7053SJung-uk Kim  * s.
14857bded2dbSJung-uk Kim  */
tls12_check_peer_sigalg(SSL * s,uint16_t sig,EVP_PKEY * pkey)1486e71b7053SJung-uk Kim int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey)
14877bded2dbSJung-uk Kim {
1488e71b7053SJung-uk Kim     const uint16_t *sent_sigs;
1489e71b7053SJung-uk Kim     const EVP_MD *md = NULL;
1490e71b7053SJung-uk Kim     char sigalgstr[2];
1491e71b7053SJung-uk Kim     size_t sent_sigslen, i, cidx;
1492b077aed3SPierre Pronchery     int pkeyid = -1;
1493e71b7053SJung-uk Kim     const SIGALG_LOOKUP *lu;
149417f01e99SJung-uk Kim     int secbits = 0;
1495e71b7053SJung-uk Kim 
1496b077aed3SPierre Pronchery     pkeyid = EVP_PKEY_get_id(pkey);
14977bded2dbSJung-uk Kim     /* Should never happen */
1498e71b7053SJung-uk Kim     if (pkeyid == -1)
14997bded2dbSJung-uk Kim         return -1;
1500e71b7053SJung-uk Kim     if (SSL_IS_TLS13(s)) {
1501e71b7053SJung-uk Kim         /* Disallow DSA for TLS 1.3 */
1502e71b7053SJung-uk Kim         if (pkeyid == EVP_PKEY_DSA) {
1503b077aed3SPierre Pronchery             SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_SIGNATURE_TYPE);
15047bded2dbSJung-uk Kim             return 0;
15057bded2dbSJung-uk Kim         }
1506e71b7053SJung-uk Kim         /* Only allow PSS for TLS 1.3 */
1507e71b7053SJung-uk Kim         if (pkeyid == EVP_PKEY_RSA)
1508e71b7053SJung-uk Kim             pkeyid = EVP_PKEY_RSA_PSS;
1509e71b7053SJung-uk Kim     }
1510b077aed3SPierre Pronchery     lu = tls1_lookup_sigalg(s, sig);
1511e71b7053SJung-uk Kim     /*
1512e71b7053SJung-uk Kim      * Check sigalgs is known. Disallow SHA1/SHA224 with TLS 1.3. Check key type
1513e71b7053SJung-uk Kim      * is consistent with signature: RSA keys can be used for RSA-PSS
1514e71b7053SJung-uk Kim      */
1515e71b7053SJung-uk Kim     if (lu == NULL
1516e71b7053SJung-uk Kim         || (SSL_IS_TLS13(s) && (lu->hash == NID_sha1 || lu->hash == NID_sha224))
1517e71b7053SJung-uk Kim         || (pkeyid != lu->sig
1518e71b7053SJung-uk Kim         && (lu->sig != EVP_PKEY_RSA_PSS || pkeyid != EVP_PKEY_RSA))) {
1519b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_SIGNATURE_TYPE);
1520e71b7053SJung-uk Kim         return 0;
1521e71b7053SJung-uk Kim     }
1522e71b7053SJung-uk Kim     /* Check the sigalg is consistent with the key OID */
1523b077aed3SPierre Pronchery     if (!ssl_cert_lookup_by_nid(EVP_PKEY_get_id(pkey), &cidx)
1524e71b7053SJung-uk Kim             || lu->sig_idx != (int)cidx) {
1525b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_SIGNATURE_TYPE);
1526e71b7053SJung-uk Kim         return 0;
1527e71b7053SJung-uk Kim     }
1528e71b7053SJung-uk Kim 
1529e71b7053SJung-uk Kim     if (pkeyid == EVP_PKEY_EC) {
1530e71b7053SJung-uk Kim 
1531e71b7053SJung-uk Kim         /* Check point compression is permitted */
1532e71b7053SJung-uk Kim         if (!tls1_check_pkey_comp(s, pkey)) {
1533e71b7053SJung-uk Kim             SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
1534e71b7053SJung-uk Kim                      SSL_R_ILLEGAL_POINT_COMPRESSION);
15357bded2dbSJung-uk Kim             return 0;
15367bded2dbSJung-uk Kim         }
1537e71b7053SJung-uk Kim 
1538e71b7053SJung-uk Kim         /* For TLS 1.3 or Suite B check curve matches signature algorithm */
1539e71b7053SJung-uk Kim         if (SSL_IS_TLS13(s) || tls1_suiteb(s)) {
1540b077aed3SPierre Pronchery             int curve = ssl_get_EC_curve_nid(pkey);
1541e71b7053SJung-uk Kim 
1542e71b7053SJung-uk Kim             if (lu->curve != NID_undef && curve != lu->curve) {
1543b077aed3SPierre Pronchery                 SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CURVE);
1544e71b7053SJung-uk Kim                 return 0;
1545e71b7053SJung-uk Kim             }
1546e71b7053SJung-uk Kim         }
1547e71b7053SJung-uk Kim         if (!SSL_IS_TLS13(s)) {
1548e71b7053SJung-uk Kim             /* Check curve matches extensions */
1549e71b7053SJung-uk Kim             if (!tls1_check_group_id(s, tls1_get_group_id(pkey), 1)) {
1550b077aed3SPierre Pronchery                 SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CURVE);
1551e71b7053SJung-uk Kim                 return 0;
1552e71b7053SJung-uk Kim             }
15537bded2dbSJung-uk Kim             if (tls1_suiteb(s)) {
1554e71b7053SJung-uk Kim                 /* Check sigalg matches a permissible Suite B value */
1555e71b7053SJung-uk Kim                 if (sig != TLSEXT_SIGALG_ecdsa_secp256r1_sha256
1556e71b7053SJung-uk Kim                     && sig != TLSEXT_SIGALG_ecdsa_secp384r1_sha384) {
1557e71b7053SJung-uk Kim                     SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
1558e71b7053SJung-uk Kim                              SSL_R_WRONG_SIGNATURE_TYPE);
15597bded2dbSJung-uk Kim                     return 0;
15607bded2dbSJung-uk Kim                 }
1561e71b7053SJung-uk Kim             }
1562e71b7053SJung-uk Kim         }
1563e71b7053SJung-uk Kim     } else if (tls1_suiteb(s)) {
1564b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE);
15657bded2dbSJung-uk Kim         return 0;
15667bded2dbSJung-uk Kim     }
15677bded2dbSJung-uk Kim 
15687bded2dbSJung-uk Kim     /* Check signature matches a type we sent */
1569ed7112f0SJung-uk Kim     sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs);
1570e71b7053SJung-uk Kim     for (i = 0; i < sent_sigslen; i++, sent_sigs++) {
1571e71b7053SJung-uk Kim         if (sig == *sent_sigs)
15727bded2dbSJung-uk Kim             break;
15737bded2dbSJung-uk Kim     }
15747bded2dbSJung-uk Kim     /* Allow fallback to SHA1 if not strict mode */
1575e71b7053SJung-uk Kim     if (i == sent_sigslen && (lu->hash != NID_sha1
15767bded2dbSJung-uk Kim         || s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) {
1577b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE);
15787bded2dbSJung-uk Kim         return 0;
15797bded2dbSJung-uk Kim     }
1580b077aed3SPierre Pronchery     if (!tls1_lookup_md(s->ctx, lu, &md)) {
1581b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_UNKNOWN_DIGEST);
15827bded2dbSJung-uk Kim         return 0;
15837bded2dbSJung-uk Kim     }
15847bded2dbSJung-uk Kim     /*
1585e71b7053SJung-uk Kim      * Make sure security callback allows algorithm. For historical
1586e71b7053SJung-uk Kim      * reasons we have to pass the sigalg as a two byte char array.
15877bded2dbSJung-uk Kim      */
1588e71b7053SJung-uk Kim     sigalgstr[0] = (sig >> 8) & 0xff;
1589e71b7053SJung-uk Kim     sigalgstr[1] = sig & 0xff;
1590b077aed3SPierre Pronchery     secbits = sigalg_security_bits(s->ctx, lu);
159117f01e99SJung-uk Kim     if (secbits == 0 ||
159217f01e99SJung-uk Kim         !ssl_security(s, SSL_SECOP_SIGALG_CHECK, secbits,
1593b077aed3SPierre Pronchery                       md != NULL ? EVP_MD_get_type(md) : NID_undef,
1594e71b7053SJung-uk Kim                       (void *)sigalgstr)) {
1595b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE);
1596e71b7053SJung-uk Kim         return 0;
1597e71b7053SJung-uk Kim     }
1598e71b7053SJung-uk Kim     /* Store the sigalg the peer uses */
1599b077aed3SPierre Pronchery     s->s3.tmp.peer_sigalg = lu;
1600e71b7053SJung-uk Kim     return 1;
1601e71b7053SJung-uk Kim }
1602e71b7053SJung-uk Kim 
SSL_get_peer_signature_type_nid(const SSL * s,int * pnid)1603e71b7053SJung-uk Kim int SSL_get_peer_signature_type_nid(const SSL *s, int *pnid)
1604e71b7053SJung-uk Kim {
1605b077aed3SPierre Pronchery     if (s->s3.tmp.peer_sigalg == NULL)
1606e71b7053SJung-uk Kim         return 0;
1607b077aed3SPierre Pronchery     *pnid = s->s3.tmp.peer_sigalg->sig;
16087bded2dbSJung-uk Kim     return 1;
16097bded2dbSJung-uk Kim }
16107bded2dbSJung-uk Kim 
SSL_get_signature_type_nid(const SSL * s,int * pnid)1611c9cf7b5cSJung-uk Kim int SSL_get_signature_type_nid(const SSL *s, int *pnid)
1612c9cf7b5cSJung-uk Kim {
1613b077aed3SPierre Pronchery     if (s->s3.tmp.sigalg == NULL)
1614c9cf7b5cSJung-uk Kim         return 0;
1615b077aed3SPierre Pronchery     *pnid = s->s3.tmp.sigalg->sig;
1616c9cf7b5cSJung-uk Kim     return 1;
1617c9cf7b5cSJung-uk Kim }
1618c9cf7b5cSJung-uk Kim 
16197bded2dbSJung-uk Kim /*
1620e71b7053SJung-uk Kim  * Set a mask of disabled algorithms: an algorithm is disabled if it isn't
1621e71b7053SJung-uk Kim  * supported, doesn't appear in supported signature algorithms, isn't supported
1622e71b7053SJung-uk Kim  * by the enabled protocol versions or by the security level.
1623e71b7053SJung-uk Kim  *
1624e71b7053SJung-uk Kim  * This function should only be used for checking which ciphers are supported
1625e71b7053SJung-uk Kim  * by the client.
1626e71b7053SJung-uk Kim  *
1627e71b7053SJung-uk Kim  * Call ssl_cipher_disabled() to check that it's enabled or not.
16287bded2dbSJung-uk Kim  */
ssl_set_client_disabled(SSL * s)1629e71b7053SJung-uk Kim int ssl_set_client_disabled(SSL *s)
16307bded2dbSJung-uk Kim {
1631b077aed3SPierre Pronchery     s->s3.tmp.mask_a = 0;
1632b077aed3SPierre Pronchery     s->s3.tmp.mask_k = 0;
1633b077aed3SPierre Pronchery     ssl_set_sig_mask(&s->s3.tmp.mask_a, s, SSL_SECOP_SIGALG_MASK);
1634b077aed3SPierre Pronchery     if (ssl_get_min_max_version(s, &s->s3.tmp.min_ver,
1635b077aed3SPierre Pronchery                                 &s->s3.tmp.max_ver, NULL) != 0)
1636e71b7053SJung-uk Kim         return 0;
16377bded2dbSJung-uk Kim #ifndef OPENSSL_NO_PSK
16387bded2dbSJung-uk Kim     /* with PSK there must be client callback set */
16397bded2dbSJung-uk Kim     if (!s->psk_client_callback) {
1640b077aed3SPierre Pronchery         s->s3.tmp.mask_a |= SSL_aPSK;
1641b077aed3SPierre Pronchery         s->s3.tmp.mask_k |= SSL_PSK;
16427bded2dbSJung-uk Kim     }
16437bded2dbSJung-uk Kim #endif                          /* OPENSSL_NO_PSK */
16447bded2dbSJung-uk Kim #ifndef OPENSSL_NO_SRP
16457bded2dbSJung-uk Kim     if (!(s->srp_ctx.srp_Mask & SSL_kSRP)) {
1646b077aed3SPierre Pronchery         s->s3.tmp.mask_a |= SSL_aSRP;
1647b077aed3SPierre Pronchery         s->s3.tmp.mask_k |= SSL_kSRP;
16487bded2dbSJung-uk Kim     }
16497bded2dbSJung-uk Kim #endif
1650e71b7053SJung-uk Kim     return 1;
16511f13597dSJung-uk Kim }
16521f13597dSJung-uk Kim 
16536f9291ceSJung-uk Kim /*
1654e71b7053SJung-uk Kim  * ssl_cipher_disabled - check that a cipher is disabled or not
1655e71b7053SJung-uk Kim  * @s: SSL connection that you want to use the cipher on
1656e71b7053SJung-uk Kim  * @c: cipher to check
1657e71b7053SJung-uk Kim  * @op: Security check that you want to do
1658e71b7053SJung-uk Kim  * @ecdhe: If set to 1 then TLSv1 ECDHE ciphers are also allowed in SSLv3
16596cf8931aSJung-uk Kim  *
1660e71b7053SJung-uk Kim  * Returns 1 when it's disabled, 0 when enabled.
16616cf8931aSJung-uk Kim  */
ssl_cipher_disabled(const SSL * s,const SSL_CIPHER * c,int op,int ecdhe)166217f01e99SJung-uk Kim int ssl_cipher_disabled(const SSL *s, const SSL_CIPHER *c, int op, int ecdhe)
1663db522d3aSSimon L. B. Nielsen {
1664b077aed3SPierre Pronchery     if (c->algorithm_mkey & s->s3.tmp.mask_k
1665b077aed3SPierre Pronchery         || c->algorithm_auth & s->s3.tmp.mask_a)
1666e71b7053SJung-uk Kim         return 1;
1667b077aed3SPierre Pronchery     if (s->s3.tmp.max_ver == 0)
1668e71b7053SJung-uk Kim         return 1;
1669e71b7053SJung-uk Kim     if (!SSL_IS_DTLS(s)) {
1670e71b7053SJung-uk Kim         int min_tls = c->min_tls;
1671de78d5d8SJung-uk Kim 
16727bded2dbSJung-uk Kim         /*
1673e71b7053SJung-uk Kim          * For historical reasons we will allow ECHDE to be selected by a server
1674e71b7053SJung-uk Kim          * in SSLv3 if we are a client
16757bded2dbSJung-uk Kim          */
1676e71b7053SJung-uk Kim         if (min_tls == TLS1_VERSION && ecdhe
1677e71b7053SJung-uk Kim                 && (c->algorithm_mkey & (SSL_kECDHE | SSL_kECDHEPSK)) != 0)
1678e71b7053SJung-uk Kim             min_tls = SSL3_VERSION;
16797bded2dbSJung-uk Kim 
1680b077aed3SPierre Pronchery         if ((min_tls > s->s3.tmp.max_ver) || (c->max_tls < s->s3.tmp.min_ver))
1681b8721c16SJung-uk Kim             return 1;
1682b8721c16SJung-uk Kim     }
1683b077aed3SPierre Pronchery     if (SSL_IS_DTLS(s) && (DTLS_VERSION_GT(c->min_dtls, s->s3.tmp.max_ver)
1684b077aed3SPierre Pronchery                            || DTLS_VERSION_LT(c->max_dtls, s->s3.tmp.min_ver)))
16857bded2dbSJung-uk Kim         return 1;
16867bded2dbSJung-uk Kim 
1687e71b7053SJung-uk Kim     return !ssl_security(s, op, c->strength_bits, 0, (void *)c);
16887bded2dbSJung-uk Kim }
16897bded2dbSJung-uk Kim 
tls_use_ticket(SSL * s)1690e71b7053SJung-uk Kim int tls_use_ticket(SSL *s)
16917bded2dbSJung-uk Kim {
1692e71b7053SJung-uk Kim     if ((s->options & SSL_OP_NO_TICKET))
16937bded2dbSJung-uk Kim         return 0;
1694e71b7053SJung-uk Kim     return ssl_security(s, SSL_SECOP_TICKET, 0, 0, NULL);
1695db522d3aSSimon L. B. Nielsen }
1696db522d3aSSimon L. B. Nielsen 
tls1_set_server_sigalgs(SSL * s)16977bded2dbSJung-uk Kim int tls1_set_server_sigalgs(SSL *s)
16987bded2dbSJung-uk Kim {
16997bded2dbSJung-uk Kim     size_t i;
1700e71b7053SJung-uk Kim 
1701e71b7053SJung-uk Kim     /* Clear any shared signature algorithms */
1702da327cd2SJung-uk Kim     OPENSSL_free(s->shared_sigalgs);
1703da327cd2SJung-uk Kim     s->shared_sigalgs = NULL;
1704da327cd2SJung-uk Kim     s->shared_sigalgslen = 0;
1705e71b7053SJung-uk Kim     /* Clear certificate validity flags */
1706e71b7053SJung-uk Kim     for (i = 0; i < SSL_PKEY_NUM; i++)
1707b077aed3SPierre Pronchery         s->s3.tmp.valid_flags[i] = 0;
1708e71b7053SJung-uk Kim     /*
1709e71b7053SJung-uk Kim      * If peer sent no signature algorithms check to see if we support
1710e71b7053SJung-uk Kim      * the default algorithm for each certificate type
1711e71b7053SJung-uk Kim      */
1712b077aed3SPierre Pronchery     if (s->s3.tmp.peer_cert_sigalgs == NULL
1713b077aed3SPierre Pronchery             && s->s3.tmp.peer_sigalgs == NULL) {
1714e71b7053SJung-uk Kim         const uint16_t *sent_sigs;
1715e71b7053SJung-uk Kim         size_t sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs);
1716e71b7053SJung-uk Kim 
17177bded2dbSJung-uk Kim         for (i = 0; i < SSL_PKEY_NUM; i++) {
1718e71b7053SJung-uk Kim             const SIGALG_LOOKUP *lu = tls1_get_legacy_sigalg(s, i);
1719e71b7053SJung-uk Kim             size_t j;
1720e71b7053SJung-uk Kim 
1721e71b7053SJung-uk Kim             if (lu == NULL)
1722e71b7053SJung-uk Kim                 continue;
1723e71b7053SJung-uk Kim             /* Check default matches a type we sent */
1724e71b7053SJung-uk Kim             for (j = 0; j < sent_sigslen; j++) {
1725e71b7053SJung-uk Kim                 if (lu->sigalg == sent_sigs[j]) {
1726b077aed3SPierre Pronchery                         s->s3.tmp.valid_flags[i] = CERT_PKEY_SIGN;
1727e71b7053SJung-uk Kim                         break;
1728e71b7053SJung-uk Kim                 }
1729e71b7053SJung-uk Kim             }
1730e71b7053SJung-uk Kim         }
1731e71b7053SJung-uk Kim         return 1;
17327bded2dbSJung-uk Kim     }
17337bded2dbSJung-uk Kim 
17347bded2dbSJung-uk Kim     if (!tls1_process_sigalgs(s)) {
1735b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
17367bded2dbSJung-uk Kim         return 0;
17377bded2dbSJung-uk Kim     }
1738da327cd2SJung-uk Kim     if (s->shared_sigalgs != NULL)
1739e71b7053SJung-uk Kim         return 1;
17407bded2dbSJung-uk Kim 
1741e71b7053SJung-uk Kim     /* Fatal error if no shared signature algorithms */
1742b077aed3SPierre Pronchery     SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
1743e71b7053SJung-uk Kim              SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS);
17446cf8931aSJung-uk Kim     return 0;
174509286989SJung-uk Kim }
17467bded2dbSJung-uk Kim 
17476f9291ceSJung-uk Kim /*-
1748e71b7053SJung-uk Kim  * Gets the ticket information supplied by the client if any.
17491f13597dSJung-uk Kim  *
1750e71b7053SJung-uk Kim  *   hello: The parsed ClientHello data
17511f13597dSJung-uk Kim  *   ret: (output) on return, if a ticket was decrypted, then this is set to
17521f13597dSJung-uk Kim  *       point to the resulting session.
1753e71b7053SJung-uk Kim  */
tls_get_ticket_from_client(SSL * s,CLIENTHELLO_MSG * hello,SSL_SESSION ** ret)1754e71b7053SJung-uk Kim SSL_TICKET_STATUS tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello,
1755e71b7053SJung-uk Kim                                              SSL_SESSION **ret)
1756e71b7053SJung-uk Kim {
1757e71b7053SJung-uk Kim     size_t size;
1758e71b7053SJung-uk Kim     RAW_EXTENSION *ticketext;
1759e71b7053SJung-uk Kim 
1760e71b7053SJung-uk Kim     *ret = NULL;
1761e71b7053SJung-uk Kim     s->ext.ticket_expected = 0;
1762e71b7053SJung-uk Kim 
1763e71b7053SJung-uk Kim     /*
1764e71b7053SJung-uk Kim      * If tickets disabled or not supported by the protocol version
1765e71b7053SJung-uk Kim      * (e.g. TLSv1.3) behave as if no ticket present to permit stateful
1766e71b7053SJung-uk Kim      * resumption.
1767e71b7053SJung-uk Kim      */
1768e71b7053SJung-uk Kim     if (s->version <= SSL3_VERSION || !tls_use_ticket(s))
1769e71b7053SJung-uk Kim         return SSL_TICKET_NONE;
1770e71b7053SJung-uk Kim 
1771e71b7053SJung-uk Kim     ticketext = &hello->pre_proc_exts[TLSEXT_IDX_session_ticket];
1772e71b7053SJung-uk Kim     if (!ticketext->present)
1773e71b7053SJung-uk Kim         return SSL_TICKET_NONE;
1774e71b7053SJung-uk Kim 
1775e71b7053SJung-uk Kim     size = PACKET_remaining(&ticketext->data);
1776e71b7053SJung-uk Kim 
1777e71b7053SJung-uk Kim     return tls_decrypt_ticket(s, PACKET_data(&ticketext->data), size,
1778e71b7053SJung-uk Kim                               hello->session_id, hello->session_id_len, ret);
1779e71b7053SJung-uk Kim }
1780e71b7053SJung-uk Kim 
1781e71b7053SJung-uk Kim /*-
1782e71b7053SJung-uk Kim  * tls_decrypt_ticket attempts to decrypt a session ticket.
17831f13597dSJung-uk Kim  *
1784e71b7053SJung-uk Kim  * If s->tls_session_secret_cb is set and we're not doing TLSv1.3 then we are
1785e71b7053SJung-uk Kim  * expecting a pre-shared key ciphersuite, in which case we have no use for
1786e71b7053SJung-uk Kim  * session tickets and one will never be decrypted, nor will
1787e71b7053SJung-uk Kim  * s->ext.ticket_expected be set to 1.
17881f13597dSJung-uk Kim  *
17891f13597dSJung-uk Kim  * Side effects:
1790e71b7053SJung-uk Kim  *   Sets s->ext.ticket_expected to 1 if the server will have to issue
17911f13597dSJung-uk Kim  *   a new session ticket to the client because the client indicated support
17921f13597dSJung-uk Kim  *   (and s->tls_session_secret_cb is NULL) but the client either doesn't have
17931f13597dSJung-uk Kim  *   a session ticket or we couldn't use the one it gave us, or if
1794e71b7053SJung-uk Kim  *   s->ctx->ext.ticket_key_cb asked to renew the client's ticket.
1795e71b7053SJung-uk Kim  *   Otherwise, s->ext.ticket_expected is set to 0.
1796e71b7053SJung-uk Kim  *
1797e71b7053SJung-uk Kim  *   etick: points to the body of the session ticket extension.
1798e71b7053SJung-uk Kim  *   eticklen: the length of the session tickets extension.
1799e71b7053SJung-uk Kim  *   sess_id: points at the session ID.
1800e71b7053SJung-uk Kim  *   sesslen: the length of the session ID.
1801e71b7053SJung-uk Kim  *   psess: (output) on return, if a ticket was decrypted, then this is set to
1802e71b7053SJung-uk Kim  *       point to the resulting session.
1803db522d3aSSimon L. B. Nielsen  */
tls_decrypt_ticket(SSL * s,const unsigned char * etick,size_t eticklen,const unsigned char * sess_id,size_t sesslen,SSL_SESSION ** psess)1804e71b7053SJung-uk Kim SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick,
1805e71b7053SJung-uk Kim                                      size_t eticklen, const unsigned char *sess_id,
1806e71b7053SJung-uk Kim                                      size_t sesslen, SSL_SESSION **psess)
1807db522d3aSSimon L. B. Nielsen {
1808e71b7053SJung-uk Kim     SSL_SESSION *sess = NULL;
1809e71b7053SJung-uk Kim     unsigned char *sdec;
1810e71b7053SJung-uk Kim     const unsigned char *p;
1811b077aed3SPierre Pronchery     int slen, ivlen, renew_ticket = 0, declen;
1812e71b7053SJung-uk Kim     SSL_TICKET_STATUS ret = SSL_TICKET_FATAL_ERR_OTHER;
1813e71b7053SJung-uk Kim     size_t mlen;
1814e71b7053SJung-uk Kim     unsigned char tick_hmac[EVP_MAX_MD_SIZE];
1815b077aed3SPierre Pronchery     SSL_HMAC *hctx = NULL;
1816e71b7053SJung-uk Kim     EVP_CIPHER_CTX *ctx = NULL;
1817e71b7053SJung-uk Kim     SSL_CTX *tctx = s->session_ctx;
1818db522d3aSSimon L. B. Nielsen 
1819e71b7053SJung-uk Kim     if (eticklen == 0) {
18206f9291ceSJung-uk Kim         /*
18216f9291ceSJung-uk Kim          * The client will accept a ticket but doesn't currently have
1822e71b7053SJung-uk Kim          * one (TLSv1.2 and below), or treated as a fatal error in TLSv1.3
18236f9291ceSJung-uk Kim          */
1824e71b7053SJung-uk Kim         ret = SSL_TICKET_EMPTY;
1825e71b7053SJung-uk Kim         goto end;
1826db522d3aSSimon L. B. Nielsen     }
1827e71b7053SJung-uk Kim     if (!SSL_IS_TLS13(s) && s->ext.session_secret_cb) {
18286f9291ceSJung-uk Kim         /*
18296f9291ceSJung-uk Kim          * Indicate that the ticket couldn't be decrypted rather than
18306f9291ceSJung-uk Kim          * generating the session from ticket now, trigger
18316f9291ceSJung-uk Kim          * abbreviated handshake based on external mechanism to
18326f9291ceSJung-uk Kim          * calculate the master secret later.
18336f9291ceSJung-uk Kim          */
1834e71b7053SJung-uk Kim         ret = SSL_TICKET_NO_DECRYPT;
1835e71b7053SJung-uk Kim         goto end;
18361f13597dSJung-uk Kim     }
1837aeb5019cSJung-uk Kim 
1838dee36b4fSJung-uk Kim     /* Need at least keyname + iv */
1839e71b7053SJung-uk Kim     if (eticklen < TLSEXT_KEYNAME_LENGTH + EVP_MAX_IV_LENGTH) {
1840e71b7053SJung-uk Kim         ret = SSL_TICKET_NO_DECRYPT;
1841e71b7053SJung-uk Kim         goto end;
1842e71b7053SJung-uk Kim     }
1843dee36b4fSJung-uk Kim 
1844db522d3aSSimon L. B. Nielsen     /* Initialize session ticket encryption and HMAC contexts */
1845b077aed3SPierre Pronchery     hctx = ssl_hmac_new(tctx);
1846e71b7053SJung-uk Kim     if (hctx == NULL) {
1847e71b7053SJung-uk Kim         ret = SSL_TICKET_FATAL_ERR_MALLOC;
1848e71b7053SJung-uk Kim         goto end;
1849e71b7053SJung-uk Kim     }
1850e71b7053SJung-uk Kim     ctx = EVP_CIPHER_CTX_new();
1851e71b7053SJung-uk Kim     if (ctx == NULL) {
1852e71b7053SJung-uk Kim         ret = SSL_TICKET_FATAL_ERR_MALLOC;
1853e71b7053SJung-uk Kim         goto end;
1854e71b7053SJung-uk Kim     }
1855b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DEPRECATED_3_0
1856b077aed3SPierre Pronchery     if (tctx->ext.ticket_key_evp_cb != NULL || tctx->ext.ticket_key_cb != NULL)
1857b077aed3SPierre Pronchery #else
1858b077aed3SPierre Pronchery     if (tctx->ext.ticket_key_evp_cb != NULL)
1859b077aed3SPierre Pronchery #endif
1860b077aed3SPierre Pronchery     {
1861db522d3aSSimon L. B. Nielsen         unsigned char *nctick = (unsigned char *)etick;
1862b077aed3SPierre Pronchery         int rv = 0;
1863b077aed3SPierre Pronchery 
1864b077aed3SPierre Pronchery         if (tctx->ext.ticket_key_evp_cb != NULL)
1865b077aed3SPierre Pronchery             rv = tctx->ext.ticket_key_evp_cb(s, nctick,
1866e71b7053SJung-uk Kim                                              nctick + TLSEXT_KEYNAME_LENGTH,
1867b077aed3SPierre Pronchery                                              ctx,
1868b077aed3SPierre Pronchery                                              ssl_hmac_get0_EVP_MAC_CTX(hctx),
1869b077aed3SPierre Pronchery                                              0);
1870b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DEPRECATED_3_0
1871b077aed3SPierre Pronchery         else if (tctx->ext.ticket_key_cb != NULL)
1872b077aed3SPierre Pronchery             /* if 0 is returned, write an empty ticket */
1873b077aed3SPierre Pronchery             rv = tctx->ext.ticket_key_cb(s, nctick,
1874b077aed3SPierre Pronchery                                          nctick + TLSEXT_KEYNAME_LENGTH,
1875b077aed3SPierre Pronchery                                          ctx, ssl_hmac_get0_HMAC_CTX(hctx), 0);
1876b077aed3SPierre Pronchery #endif
1877e71b7053SJung-uk Kim         if (rv < 0) {
1878e71b7053SJung-uk Kim             ret = SSL_TICKET_FATAL_ERR_OTHER;
1879e71b7053SJung-uk Kim             goto end;
1880e71b7053SJung-uk Kim         }
1881dee36b4fSJung-uk Kim         if (rv == 0) {
1882e71b7053SJung-uk Kim             ret = SSL_TICKET_NO_DECRYPT;
1883e71b7053SJung-uk Kim             goto end;
1884dee36b4fSJung-uk Kim         }
1885db522d3aSSimon L. B. Nielsen         if (rv == 2)
1886db522d3aSSimon L. B. Nielsen             renew_ticket = 1;
18876f9291ceSJung-uk Kim     } else {
1888b077aed3SPierre Pronchery         EVP_CIPHER *aes256cbc = NULL;
1889b077aed3SPierre Pronchery 
1890db522d3aSSimon L. B. Nielsen         /* Check key name matches */
1891e71b7053SJung-uk Kim         if (memcmp(etick, tctx->ext.tick_key_name,
1892e71b7053SJung-uk Kim                    TLSEXT_KEYNAME_LENGTH) != 0) {
1893e71b7053SJung-uk Kim             ret = SSL_TICKET_NO_DECRYPT;
1894e71b7053SJung-uk Kim             goto end;
189580815a77SJung-uk Kim         }
1896b077aed3SPierre Pronchery 
1897b077aed3SPierre Pronchery         aes256cbc = EVP_CIPHER_fetch(s->ctx->libctx, "AES-256-CBC",
1898b077aed3SPierre Pronchery                                      s->ctx->propq);
1899b077aed3SPierre Pronchery         if (aes256cbc == NULL
1900b077aed3SPierre Pronchery             || ssl_hmac_init(hctx, tctx->ext.secure->tick_hmac_key,
1901e71b7053SJung-uk Kim                              sizeof(tctx->ext.secure->tick_hmac_key),
1902b077aed3SPierre Pronchery                              "SHA256") <= 0
1903b077aed3SPierre Pronchery             || EVP_DecryptInit_ex(ctx, aes256cbc, NULL,
1904e71b7053SJung-uk Kim                                   tctx->ext.secure->tick_aes_key,
1905e71b7053SJung-uk Kim                                   etick + TLSEXT_KEYNAME_LENGTH) <= 0) {
1906b077aed3SPierre Pronchery             EVP_CIPHER_free(aes256cbc);
1907e71b7053SJung-uk Kim             ret = SSL_TICKET_FATAL_ERR_OTHER;
1908e71b7053SJung-uk Kim             goto end;
1909e71b7053SJung-uk Kim         }
1910b077aed3SPierre Pronchery         EVP_CIPHER_free(aes256cbc);
1911e71b7053SJung-uk Kim         if (SSL_IS_TLS13(s))
1912e71b7053SJung-uk Kim             renew_ticket = 1;
1913db522d3aSSimon L. B. Nielsen     }
19146f9291ceSJung-uk Kim     /*
19156f9291ceSJung-uk Kim      * Attempt to process session ticket, first conduct sanity and integrity
19166f9291ceSJung-uk Kim      * checks on ticket.
1917db522d3aSSimon L. B. Nielsen      */
1918b077aed3SPierre Pronchery     mlen = ssl_hmac_size(hctx);
1919e71b7053SJung-uk Kim     if (mlen == 0) {
1920e71b7053SJung-uk Kim         ret = SSL_TICKET_FATAL_ERR_OTHER;
1921e71b7053SJung-uk Kim         goto end;
1922aeb5019cSJung-uk Kim     }
1923aeb5019cSJung-uk Kim 
1924b077aed3SPierre Pronchery     ivlen = EVP_CIPHER_CTX_get_iv_length(ctx);
1925b077aed3SPierre Pronchery     if (ivlen < 0) {
1926b077aed3SPierre Pronchery         ret = SSL_TICKET_FATAL_ERR_OTHER;
1927b077aed3SPierre Pronchery         goto end;
1928b077aed3SPierre Pronchery     }
1929b077aed3SPierre Pronchery 
1930e71b7053SJung-uk Kim     /* Sanity check ticket length: must exceed keyname + IV + HMAC */
1931b077aed3SPierre Pronchery     if (eticklen <= TLSEXT_KEYNAME_LENGTH + ivlen + mlen) {
1932e71b7053SJung-uk Kim         ret = SSL_TICKET_NO_DECRYPT;
1933e71b7053SJung-uk Kim         goto end;
1934e71b7053SJung-uk Kim     }
1935db522d3aSSimon L. B. Nielsen     eticklen -= mlen;
1936db522d3aSSimon L. B. Nielsen     /* Check HMAC of encrypted ticket */
1937b077aed3SPierre Pronchery     if (ssl_hmac_update(hctx, etick, eticklen) <= 0
1938b077aed3SPierre Pronchery         || ssl_hmac_final(hctx, tick_hmac, NULL, sizeof(tick_hmac)) <= 0) {
1939e71b7053SJung-uk Kim         ret = SSL_TICKET_FATAL_ERR_OTHER;
1940e71b7053SJung-uk Kim         goto end;
194180815a77SJung-uk Kim     }
1942e71b7053SJung-uk Kim 
19436f9291ceSJung-uk Kim     if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) {
1944e71b7053SJung-uk Kim         ret = SSL_TICKET_NO_DECRYPT;
1945e71b7053SJung-uk Kim         goto end;
1946fa5fddf1SJung-uk Kim     }
1947db522d3aSSimon L. B. Nielsen     /* Attempt to decrypt session data */
1948db522d3aSSimon L. B. Nielsen     /* Move p after IV to start of encrypted ticket, update length */
1949b077aed3SPierre Pronchery     p = etick + TLSEXT_KEYNAME_LENGTH + ivlen;
1950b077aed3SPierre Pronchery     eticklen -= TLSEXT_KEYNAME_LENGTH + ivlen;
1951db522d3aSSimon L. B. Nielsen     sdec = OPENSSL_malloc(eticklen);
1952e71b7053SJung-uk Kim     if (sdec == NULL || EVP_DecryptUpdate(ctx, sdec, &slen, p,
1953e71b7053SJung-uk Kim                                           (int)eticklen) <= 0) {
1954b8721c16SJung-uk Kim         OPENSSL_free(sdec);
1955e71b7053SJung-uk Kim         ret = SSL_TICKET_FATAL_ERR_OTHER;
1956e71b7053SJung-uk Kim         goto end;
1957db522d3aSSimon L. B. Nielsen     }
1958e71b7053SJung-uk Kim     if (EVP_DecryptFinal(ctx, sdec + slen, &declen) <= 0) {
1959a93cbc2bSJung-uk Kim         OPENSSL_free(sdec);
1960e71b7053SJung-uk Kim         ret = SSL_TICKET_NO_DECRYPT;
1961e71b7053SJung-uk Kim         goto end;
1962a93cbc2bSJung-uk Kim     }
1963e71b7053SJung-uk Kim     slen += declen;
1964db522d3aSSimon L. B. Nielsen     p = sdec;
1965db522d3aSSimon L. B. Nielsen 
1966db522d3aSSimon L. B. Nielsen     sess = d2i_SSL_SESSION(NULL, &p, slen);
1967ed7112f0SJung-uk Kim     slen -= p - sdec;
1968db522d3aSSimon L. B. Nielsen     OPENSSL_free(sdec);
19696f9291ceSJung-uk Kim     if (sess) {
1970ed7112f0SJung-uk Kim         /* Some additional consistency checks */
1971e71b7053SJung-uk Kim         if (slen != 0) {
1972ed7112f0SJung-uk Kim             SSL_SESSION_free(sess);
1973e71b7053SJung-uk Kim             sess = NULL;
1974e71b7053SJung-uk Kim             ret = SSL_TICKET_NO_DECRYPT;
1975e71b7053SJung-uk Kim             goto end;
1976ed7112f0SJung-uk Kim         }
19776f9291ceSJung-uk Kim         /*
19786f9291ceSJung-uk Kim          * The session ID, if non-empty, is used by some clients to detect
19796f9291ceSJung-uk Kim          * that the ticket has been accepted. So we copy it to the session
19806f9291ceSJung-uk Kim          * structure. If it is empty set length to zero as required by
19816f9291ceSJung-uk Kim          * standard.
1982db522d3aSSimon L. B. Nielsen          */
1983e71b7053SJung-uk Kim         if (sesslen) {
1984db522d3aSSimon L. B. Nielsen             memcpy(sess->session_id, sess_id, sesslen);
1985db522d3aSSimon L. B. Nielsen             sess->session_id_length = sesslen;
1986e71b7053SJung-uk Kim         }
19871f13597dSJung-uk Kim         if (renew_ticket)
1988e71b7053SJung-uk Kim             ret = SSL_TICKET_SUCCESS_RENEW;
19891f13597dSJung-uk Kim         else
1990e71b7053SJung-uk Kim             ret = SSL_TICKET_SUCCESS;
1991e71b7053SJung-uk Kim         goto end;
19921f13597dSJung-uk Kim     }
19931f13597dSJung-uk Kim     ERR_clear_error();
19946f9291ceSJung-uk Kim     /*
19956f9291ceSJung-uk Kim      * For session parse failure, indicate that we need to send a new ticket.
19966f9291ceSJung-uk Kim      */
1997e71b7053SJung-uk Kim     ret = SSL_TICKET_NO_DECRYPT;
19981f13597dSJung-uk Kim 
1999e71b7053SJung-uk Kim  end:
2000e71b7053SJung-uk Kim     EVP_CIPHER_CTX_free(ctx);
2001b077aed3SPierre Pronchery     ssl_hmac_free(hctx);
20021f13597dSJung-uk Kim 
2003e71b7053SJung-uk Kim     /*
2004e71b7053SJung-uk Kim      * If set, the decrypt_ticket_cb() is called unless a fatal error was
2005e71b7053SJung-uk Kim      * detected above. The callback is responsible for checking |ret| before it
2006e71b7053SJung-uk Kim      * performs any action
2007e71b7053SJung-uk Kim      */
2008e71b7053SJung-uk Kim     if (s->session_ctx->decrypt_ticket_cb != NULL
2009e71b7053SJung-uk Kim             && (ret == SSL_TICKET_EMPTY
2010e71b7053SJung-uk Kim                 || ret == SSL_TICKET_NO_DECRYPT
2011e71b7053SJung-uk Kim                 || ret == SSL_TICKET_SUCCESS
2012e71b7053SJung-uk Kim                 || ret == SSL_TICKET_SUCCESS_RENEW)) {
2013e71b7053SJung-uk Kim         size_t keyname_len = eticklen;
2014e71b7053SJung-uk Kim         int retcb;
20151f13597dSJung-uk Kim 
2016e71b7053SJung-uk Kim         if (keyname_len > TLSEXT_KEYNAME_LENGTH)
2017e71b7053SJung-uk Kim             keyname_len = TLSEXT_KEYNAME_LENGTH;
2018e71b7053SJung-uk Kim         retcb = s->session_ctx->decrypt_ticket_cb(s, sess, etick, keyname_len,
2019e71b7053SJung-uk Kim                                                   ret,
2020e71b7053SJung-uk Kim                                                   s->session_ctx->ticket_cb_data);
2021e71b7053SJung-uk Kim         switch (retcb) {
2022e71b7053SJung-uk Kim         case SSL_TICKET_RETURN_ABORT:
2023e71b7053SJung-uk Kim             ret = SSL_TICKET_FATAL_ERR_OTHER;
2024e71b7053SJung-uk Kim             break;
20251f13597dSJung-uk Kim 
2026e71b7053SJung-uk Kim         case SSL_TICKET_RETURN_IGNORE:
2027e71b7053SJung-uk Kim             ret = SSL_TICKET_NONE;
2028e71b7053SJung-uk Kim             SSL_SESSION_free(sess);
2029e71b7053SJung-uk Kim             sess = NULL;
2030e71b7053SJung-uk Kim             break;
20311f13597dSJung-uk Kim 
2032e71b7053SJung-uk Kim         case SSL_TICKET_RETURN_IGNORE_RENEW:
2033e71b7053SJung-uk Kim             if (ret != SSL_TICKET_EMPTY && ret != SSL_TICKET_NO_DECRYPT)
2034e71b7053SJung-uk Kim                 ret = SSL_TICKET_NO_DECRYPT;
2035e71b7053SJung-uk Kim             /* else the value of |ret| will already do the right thing */
2036e71b7053SJung-uk Kim             SSL_SESSION_free(sess);
2037e71b7053SJung-uk Kim             sess = NULL;
2038e71b7053SJung-uk Kim             break;
20396f9291ceSJung-uk Kim 
2040e71b7053SJung-uk Kim         case SSL_TICKET_RETURN_USE:
2041e71b7053SJung-uk Kim         case SSL_TICKET_RETURN_USE_RENEW:
2042e71b7053SJung-uk Kim             if (ret != SSL_TICKET_SUCCESS
2043e71b7053SJung-uk Kim                     && ret != SSL_TICKET_SUCCESS_RENEW)
2044e71b7053SJung-uk Kim                 ret = SSL_TICKET_FATAL_ERR_OTHER;
2045e71b7053SJung-uk Kim             else if (retcb == SSL_TICKET_RETURN_USE)
2046e71b7053SJung-uk Kim                 ret = SSL_TICKET_SUCCESS;
2047e71b7053SJung-uk Kim             else
2048e71b7053SJung-uk Kim                 ret = SSL_TICKET_SUCCESS_RENEW;
2049e71b7053SJung-uk Kim             break;
20501f13597dSJung-uk Kim 
20511f13597dSJung-uk Kim         default:
2052e71b7053SJung-uk Kim             ret = SSL_TICKET_FATAL_ERR_OTHER;
20531f13597dSJung-uk Kim         }
20541f13597dSJung-uk Kim     }
20551f13597dSJung-uk Kim 
2056e71b7053SJung-uk Kim     if (s->ext.session_secret_cb == NULL || SSL_IS_TLS13(s)) {
2057e71b7053SJung-uk Kim         switch (ret) {
2058e71b7053SJung-uk Kim         case SSL_TICKET_NO_DECRYPT:
2059e71b7053SJung-uk Kim         case SSL_TICKET_SUCCESS_RENEW:
2060e71b7053SJung-uk Kim         case SSL_TICKET_EMPTY:
2061e71b7053SJung-uk Kim             s->ext.ticket_expected = 1;
2062e71b7053SJung-uk Kim         }
2063e71b7053SJung-uk Kim     }
2064e71b7053SJung-uk Kim 
2065e71b7053SJung-uk Kim     *psess = sess;
2066e71b7053SJung-uk Kim 
2067e71b7053SJung-uk Kim     return ret;
2068e71b7053SJung-uk Kim }
2069e71b7053SJung-uk Kim 
2070e71b7053SJung-uk Kim /* Check to see if a signature algorithm is allowed */
tls12_sigalg_allowed(const SSL * s,int op,const SIGALG_LOOKUP * lu)207117f01e99SJung-uk Kim static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu)
20727bded2dbSJung-uk Kim {
2073e71b7053SJung-uk Kim     unsigned char sigalgstr[2];
2074e71b7053SJung-uk Kim     int secbits;
2075e71b7053SJung-uk Kim 
2076b077aed3SPierre Pronchery     if (lu == NULL || !lu->enabled)
2077e71b7053SJung-uk Kim         return 0;
2078e71b7053SJung-uk Kim     /* DSA is not allowed in TLS 1.3 */
2079e71b7053SJung-uk Kim     if (SSL_IS_TLS13(s) && lu->sig == EVP_PKEY_DSA)
2080e71b7053SJung-uk Kim         return 0;
2081b077aed3SPierre Pronchery     /*
2082b077aed3SPierre Pronchery      * At some point we should fully axe DSA/etc. in ClientHello as per TLS 1.3
2083b077aed3SPierre Pronchery      * spec
2084b077aed3SPierre Pronchery      */
2085b077aed3SPierre Pronchery     if (!s->server && !SSL_IS_DTLS(s) && s->s3.tmp.min_ver >= TLS1_3_VERSION
2086e71b7053SJung-uk Kim         && (lu->sig == EVP_PKEY_DSA || lu->hash_idx == SSL_MD_SHA1_IDX
2087e71b7053SJung-uk Kim             || lu->hash_idx == SSL_MD_MD5_IDX
2088e71b7053SJung-uk Kim             || lu->hash_idx == SSL_MD_SHA224_IDX))
2089e71b7053SJung-uk Kim         return 0;
2090e71b7053SJung-uk Kim 
2091e71b7053SJung-uk Kim     /* See if public key algorithm allowed */
2092b077aed3SPierre Pronchery     if (ssl_cert_is_disabled(s->ctx, lu->sig_idx))
2093e71b7053SJung-uk Kim         return 0;
2094e71b7053SJung-uk Kim 
2095e71b7053SJung-uk Kim     if (lu->sig == NID_id_GostR3410_2012_256
2096e71b7053SJung-uk Kim             || lu->sig == NID_id_GostR3410_2012_512
2097e71b7053SJung-uk Kim             || lu->sig == NID_id_GostR3410_2001) {
2098e71b7053SJung-uk Kim         /* We never allow GOST sig algs on the server with TLSv1.3 */
2099e71b7053SJung-uk Kim         if (s->server && SSL_IS_TLS13(s))
2100e71b7053SJung-uk Kim             return 0;
2101e71b7053SJung-uk Kim         if (!s->server
2102e71b7053SJung-uk Kim                 && s->method->version == TLS_ANY_VERSION
2103b077aed3SPierre Pronchery                 && s->s3.tmp.max_ver >= TLS1_3_VERSION) {
2104e71b7053SJung-uk Kim             int i, num;
2105e71b7053SJung-uk Kim             STACK_OF(SSL_CIPHER) *sk;
2106e71b7053SJung-uk Kim 
2107e71b7053SJung-uk Kim             /*
2108e71b7053SJung-uk Kim              * We're a client that could negotiate TLSv1.3. We only allow GOST
2109e71b7053SJung-uk Kim              * sig algs if we could negotiate TLSv1.2 or below and we have GOST
2110e71b7053SJung-uk Kim              * ciphersuites enabled.
2111e71b7053SJung-uk Kim              */
2112e71b7053SJung-uk Kim 
2113b077aed3SPierre Pronchery             if (s->s3.tmp.min_ver >= TLS1_3_VERSION)
2114e71b7053SJung-uk Kim                 return 0;
2115e71b7053SJung-uk Kim 
2116e71b7053SJung-uk Kim             sk = SSL_get_ciphers(s);
2117e71b7053SJung-uk Kim             num = sk != NULL ? sk_SSL_CIPHER_num(sk) : 0;
2118e71b7053SJung-uk Kim             for (i = 0; i < num; i++) {
2119e71b7053SJung-uk Kim                 const SSL_CIPHER *c;
2120e71b7053SJung-uk Kim 
2121e71b7053SJung-uk Kim                 c = sk_SSL_CIPHER_value(sk, i);
2122e71b7053SJung-uk Kim                 /* Skip disabled ciphers */
2123e71b7053SJung-uk Kim                 if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED, 0))
2124e71b7053SJung-uk Kim                     continue;
2125e71b7053SJung-uk Kim 
2126b077aed3SPierre Pronchery                 if ((c->algorithm_mkey & (SSL_kGOST | SSL_kGOST18)) != 0)
2127e71b7053SJung-uk Kim                     break;
21287bded2dbSJung-uk Kim             }
2129e71b7053SJung-uk Kim             if (i == num)
2130e71b7053SJung-uk Kim                 return 0;
2131e71b7053SJung-uk Kim         }
21327bded2dbSJung-uk Kim     }
21337bded2dbSJung-uk Kim 
2134e71b7053SJung-uk Kim     /* Finally see if security callback allows it */
2135b077aed3SPierre Pronchery     secbits = sigalg_security_bits(s->ctx, lu);
2136e71b7053SJung-uk Kim     sigalgstr[0] = (lu->sigalg >> 8) & 0xff;
2137e71b7053SJung-uk Kim     sigalgstr[1] = lu->sigalg & 0xff;
2138e71b7053SJung-uk Kim     return ssl_security(s, op, secbits, lu->hash, (void *)sigalgstr);
2139e71b7053SJung-uk Kim }
2140e71b7053SJung-uk Kim 
2141e71b7053SJung-uk Kim /*
2142e71b7053SJung-uk Kim  * Get a mask of disabled public key algorithms based on supported signature
2143e71b7053SJung-uk Kim  * algorithms. For example if no signature algorithm supports RSA then RSA is
2144e71b7053SJung-uk Kim  * disabled.
2145e71b7053SJung-uk Kim  */
2146e71b7053SJung-uk Kim 
ssl_set_sig_mask(uint32_t * pmask_a,SSL * s,int op)2147e71b7053SJung-uk Kim void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op)
21487bded2dbSJung-uk Kim {
2149e71b7053SJung-uk Kim     const uint16_t *sigalgs;
2150e71b7053SJung-uk Kim     size_t i, sigalgslen;
2151e71b7053SJung-uk Kim     uint32_t disabled_mask = SSL_aRSA | SSL_aDSS | SSL_aECDSA;
2152e71b7053SJung-uk Kim     /*
2153e71b7053SJung-uk Kim      * Go through all signature algorithms seeing if we support any
2154e71b7053SJung-uk Kim      * in disabled_mask.
2155e71b7053SJung-uk Kim      */
2156e71b7053SJung-uk Kim     sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs);
2157e71b7053SJung-uk Kim     for (i = 0; i < sigalgslen; i++, sigalgs++) {
2158b077aed3SPierre Pronchery         const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *sigalgs);
2159e71b7053SJung-uk Kim         const SSL_CERT_LOOKUP *clu;
2160e71b7053SJung-uk Kim 
2161e71b7053SJung-uk Kim         if (lu == NULL)
2162e71b7053SJung-uk Kim             continue;
2163e71b7053SJung-uk Kim 
2164e71b7053SJung-uk Kim         clu = ssl_cert_lookup_by_idx(lu->sig_idx);
2165e71b7053SJung-uk Kim         if (clu == NULL)
2166e71b7053SJung-uk Kim                 continue;
2167e71b7053SJung-uk Kim 
2168e71b7053SJung-uk Kim         /* If algorithm is disabled see if we can enable it */
2169e71b7053SJung-uk Kim         if ((clu->amask & disabled_mask) != 0
2170e71b7053SJung-uk Kim                 && tls12_sigalg_allowed(s, op, lu))
2171e71b7053SJung-uk Kim             disabled_mask &= ~clu->amask;
21727bded2dbSJung-uk Kim     }
2173e71b7053SJung-uk Kim     *pmask_a |= disabled_mask;
21747bded2dbSJung-uk Kim }
2175e71b7053SJung-uk Kim 
tls12_copy_sigalgs(SSL * s,WPACKET * pkt,const uint16_t * psig,size_t psiglen)2176e71b7053SJung-uk Kim int tls12_copy_sigalgs(SSL *s, WPACKET *pkt,
2177e71b7053SJung-uk Kim                        const uint16_t *psig, size_t psiglen)
2178e71b7053SJung-uk Kim {
2179e71b7053SJung-uk Kim     size_t i;
2180e71b7053SJung-uk Kim     int rv = 0;
2181e71b7053SJung-uk Kim 
2182e71b7053SJung-uk Kim     for (i = 0; i < psiglen; i++, psig++) {
2183b077aed3SPierre Pronchery         const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *psig);
2184e71b7053SJung-uk Kim 
2185b077aed3SPierre Pronchery         if (lu == NULL
2186b077aed3SPierre Pronchery                 || !tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, lu))
2187e71b7053SJung-uk Kim             continue;
2188e71b7053SJung-uk Kim         if (!WPACKET_put_bytes_u16(pkt, *psig))
2189e71b7053SJung-uk Kim             return 0;
2190e71b7053SJung-uk Kim         /*
2191e71b7053SJung-uk Kim          * If TLS 1.3 must have at least one valid TLS 1.3 message
2192e71b7053SJung-uk Kim          * signing algorithm: i.e. neither RSA nor SHA1/SHA224
2193e71b7053SJung-uk Kim          */
2194e71b7053SJung-uk Kim         if (rv == 0 && (!SSL_IS_TLS13(s)
2195e71b7053SJung-uk Kim             || (lu->sig != EVP_PKEY_RSA
2196e71b7053SJung-uk Kim                 && lu->hash != NID_sha1
2197e71b7053SJung-uk Kim                 && lu->hash != NID_sha224)))
2198e71b7053SJung-uk Kim             rv = 1;
21997bded2dbSJung-uk Kim     }
2200e71b7053SJung-uk Kim     if (rv == 0)
2201b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM);
2202e71b7053SJung-uk Kim     return rv;
22037bded2dbSJung-uk Kim }
22047bded2dbSJung-uk Kim 
22057bded2dbSJung-uk Kim /* Given preference and allowed sigalgs set shared sigalgs */
tls12_shared_sigalgs(SSL * s,const SIGALG_LOOKUP ** shsig,const uint16_t * pref,size_t preflen,const uint16_t * allow,size_t allowlen)2206e71b7053SJung-uk Kim static size_t tls12_shared_sigalgs(SSL *s, const SIGALG_LOOKUP **shsig,
2207e71b7053SJung-uk Kim                                    const uint16_t *pref, size_t preflen,
2208e71b7053SJung-uk Kim                                    const uint16_t *allow, size_t allowlen)
22097bded2dbSJung-uk Kim {
2210e71b7053SJung-uk Kim     const uint16_t *ptmp, *atmp;
22117bded2dbSJung-uk Kim     size_t i, j, nmatch = 0;
2212e71b7053SJung-uk Kim     for (i = 0, ptmp = pref; i < preflen; i++, ptmp++) {
2213b077aed3SPierre Pronchery         const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *ptmp);
2214e71b7053SJung-uk Kim 
22157bded2dbSJung-uk Kim         /* Skip disabled hashes or signature algorithms */
2216b077aed3SPierre Pronchery         if (lu == NULL
2217b077aed3SPierre Pronchery                 || !tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SHARED, lu))
22187bded2dbSJung-uk Kim             continue;
2219e71b7053SJung-uk Kim         for (j = 0, atmp = allow; j < allowlen; j++, atmp++) {
2220e71b7053SJung-uk Kim             if (*ptmp == *atmp) {
22217bded2dbSJung-uk Kim                 nmatch++;
2222e71b7053SJung-uk Kim                 if (shsig)
2223e71b7053SJung-uk Kim                     *shsig++ = lu;
22247bded2dbSJung-uk Kim                 break;
22257bded2dbSJung-uk Kim             }
22267bded2dbSJung-uk Kim         }
22277bded2dbSJung-uk Kim     }
22287bded2dbSJung-uk Kim     return nmatch;
22297bded2dbSJung-uk Kim }
22307bded2dbSJung-uk Kim 
22317bded2dbSJung-uk Kim /* Set shared signature algorithms for SSL structures */
tls1_set_shared_sigalgs(SSL * s)22327bded2dbSJung-uk Kim static int tls1_set_shared_sigalgs(SSL *s)
22337bded2dbSJung-uk Kim {
2234e71b7053SJung-uk Kim     const uint16_t *pref, *allow, *conf;
22357bded2dbSJung-uk Kim     size_t preflen, allowlen, conflen;
22367bded2dbSJung-uk Kim     size_t nmatch;
2237e71b7053SJung-uk Kim     const SIGALG_LOOKUP **salgs = NULL;
22387bded2dbSJung-uk Kim     CERT *c = s->cert;
22397bded2dbSJung-uk Kim     unsigned int is_suiteb = tls1_suiteb(s);
2240e71b7053SJung-uk Kim 
2241da327cd2SJung-uk Kim     OPENSSL_free(s->shared_sigalgs);
2242da327cd2SJung-uk Kim     s->shared_sigalgs = NULL;
2243da327cd2SJung-uk Kim     s->shared_sigalgslen = 0;
22447bded2dbSJung-uk Kim     /* If client use client signature algorithms if not NULL */
22457bded2dbSJung-uk Kim     if (!s->server && c->client_sigalgs && !is_suiteb) {
22467bded2dbSJung-uk Kim         conf = c->client_sigalgs;
22477bded2dbSJung-uk Kim         conflen = c->client_sigalgslen;
22487bded2dbSJung-uk Kim     } else if (c->conf_sigalgs && !is_suiteb) {
22497bded2dbSJung-uk Kim         conf = c->conf_sigalgs;
22507bded2dbSJung-uk Kim         conflen = c->conf_sigalgslen;
22517bded2dbSJung-uk Kim     } else
2252ed7112f0SJung-uk Kim         conflen = tls12_get_psigalgs(s, 0, &conf);
22537bded2dbSJung-uk Kim     if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) {
22547bded2dbSJung-uk Kim         pref = conf;
22557bded2dbSJung-uk Kim         preflen = conflen;
2256b077aed3SPierre Pronchery         allow = s->s3.tmp.peer_sigalgs;
2257b077aed3SPierre Pronchery         allowlen = s->s3.tmp.peer_sigalgslen;
22587bded2dbSJung-uk Kim     } else {
22597bded2dbSJung-uk Kim         allow = conf;
22607bded2dbSJung-uk Kim         allowlen = conflen;
2261b077aed3SPierre Pronchery         pref = s->s3.tmp.peer_sigalgs;
2262b077aed3SPierre Pronchery         preflen = s->s3.tmp.peer_sigalgslen;
22637bded2dbSJung-uk Kim     }
2264e71b7053SJung-uk Kim     nmatch = tls12_shared_sigalgs(s, NULL, pref, preflen, allow, allowlen);
22657bded2dbSJung-uk Kim     if (nmatch) {
2266e71b7053SJung-uk Kim         if ((salgs = OPENSSL_malloc(nmatch * sizeof(*salgs))) == NULL) {
2267b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
22687bded2dbSJung-uk Kim             return 0;
2269e71b7053SJung-uk Kim         }
2270e71b7053SJung-uk Kim         nmatch = tls12_shared_sigalgs(s, salgs, pref, preflen, allow, allowlen);
22717bded2dbSJung-uk Kim     } else {
22727bded2dbSJung-uk Kim         salgs = NULL;
22737bded2dbSJung-uk Kim     }
2274da327cd2SJung-uk Kim     s->shared_sigalgs = salgs;
2275da327cd2SJung-uk Kim     s->shared_sigalgslen = nmatch;
22767bded2dbSJung-uk Kim     return 1;
22777bded2dbSJung-uk Kim }
22787bded2dbSJung-uk Kim 
tls1_save_u16(PACKET * pkt,uint16_t ** pdest,size_t * pdestlen)2279e71b7053SJung-uk Kim int tls1_save_u16(PACKET *pkt, uint16_t **pdest, size_t *pdestlen)
22801f13597dSJung-uk Kim {
2281e71b7053SJung-uk Kim     unsigned int stmp;
2282e71b7053SJung-uk Kim     size_t size, i;
2283e71b7053SJung-uk Kim     uint16_t *buf;
2284e71b7053SJung-uk Kim 
2285e71b7053SJung-uk Kim     size = PACKET_remaining(pkt);
2286e71b7053SJung-uk Kim 
2287e71b7053SJung-uk Kim     /* Invalid data length */
2288e71b7053SJung-uk Kim     if (size == 0 || (size & 1) != 0)
2289e71b7053SJung-uk Kim         return 0;
2290e71b7053SJung-uk Kim 
2291e71b7053SJung-uk Kim     size >>= 1;
2292e71b7053SJung-uk Kim 
2293e71b7053SJung-uk Kim     if ((buf = OPENSSL_malloc(size * sizeof(*buf))) == NULL)  {
2294b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
2295e71b7053SJung-uk Kim         return 0;
2296e71b7053SJung-uk Kim     }
2297e71b7053SJung-uk Kim     for (i = 0; i < size && PACKET_get_net_2(pkt, &stmp); i++)
2298e71b7053SJung-uk Kim         buf[i] = stmp;
2299e71b7053SJung-uk Kim 
2300e71b7053SJung-uk Kim     if (i != size) {
2301e71b7053SJung-uk Kim         OPENSSL_free(buf);
2302e71b7053SJung-uk Kim         return 0;
2303e71b7053SJung-uk Kim     }
2304e71b7053SJung-uk Kim 
2305e71b7053SJung-uk Kim     OPENSSL_free(*pdest);
2306e71b7053SJung-uk Kim     *pdest = buf;
2307e71b7053SJung-uk Kim     *pdestlen = size;
2308e71b7053SJung-uk Kim 
2309e71b7053SJung-uk Kim     return 1;
2310e71b7053SJung-uk Kim }
2311e71b7053SJung-uk Kim 
tls1_save_sigalgs(SSL * s,PACKET * pkt,int cert)2312e71b7053SJung-uk Kim int tls1_save_sigalgs(SSL *s, PACKET *pkt, int cert)
2313e71b7053SJung-uk Kim {
23147bded2dbSJung-uk Kim     /* Extension ignored for inappropriate versions */
23157bded2dbSJung-uk Kim     if (!SSL_USE_SIGALGS(s))
23161f13597dSJung-uk Kim         return 1;
23171f13597dSJung-uk Kim     /* Should never happen */
2318e71b7053SJung-uk Kim     if (s->cert == NULL)
23191f13597dSJung-uk Kim         return 0;
23201f13597dSJung-uk Kim 
2321e71b7053SJung-uk Kim     if (cert)
2322b077aed3SPierre Pronchery         return tls1_save_u16(pkt, &s->s3.tmp.peer_cert_sigalgs,
2323b077aed3SPierre Pronchery                              &s->s3.tmp.peer_cert_sigalgslen);
2324e71b7053SJung-uk Kim     else
2325b077aed3SPierre Pronchery         return tls1_save_u16(pkt, &s->s3.tmp.peer_sigalgs,
2326b077aed3SPierre Pronchery                              &s->s3.tmp.peer_sigalgslen);
2327e71b7053SJung-uk Kim 
23281f13597dSJung-uk Kim }
23291f13597dSJung-uk Kim 
2330e71b7053SJung-uk Kim /* Set preferred digest for each key type */
2331e71b7053SJung-uk Kim 
tls1_process_sigalgs(SSL * s)23327bded2dbSJung-uk Kim int tls1_process_sigalgs(SSL *s)
23337bded2dbSJung-uk Kim {
23347bded2dbSJung-uk Kim     size_t i;
2335b077aed3SPierre Pronchery     uint32_t *pvalid = s->s3.tmp.valid_flags;
2336e71b7053SJung-uk Kim 
23377bded2dbSJung-uk Kim     if (!tls1_set_shared_sigalgs(s))
23387bded2dbSJung-uk Kim         return 0;
23397bded2dbSJung-uk Kim 
2340e71b7053SJung-uk Kim     for (i = 0; i < SSL_PKEY_NUM; i++)
2341e71b7053SJung-uk Kim         pvalid[i] = 0;
23427bded2dbSJung-uk Kim 
2343da327cd2SJung-uk Kim     for (i = 0; i < s->shared_sigalgslen; i++) {
2344da327cd2SJung-uk Kim         const SIGALG_LOOKUP *sigptr = s->shared_sigalgs[i];
2345e71b7053SJung-uk Kim         int idx = sigptr->sig_idx;
23461f13597dSJung-uk Kim 
2347e71b7053SJung-uk Kim         /* Ignore PKCS1 based sig algs in TLSv1.3 */
2348e71b7053SJung-uk Kim         if (SSL_IS_TLS13(s) && sigptr->sig == EVP_PKEY_RSA)
2349e71b7053SJung-uk Kim             continue;
2350e71b7053SJung-uk Kim         /* If not disabled indicate we can explicitly sign */
2351b077aed3SPierre Pronchery         if (pvalid[idx] == 0 && !ssl_cert_is_disabled(s->ctx, idx))
2352e71b7053SJung-uk Kim             pvalid[idx] = CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN;
23537bded2dbSJung-uk Kim     }
23541f13597dSJung-uk Kim     return 1;
23551f13597dSJung-uk Kim }
23561f13597dSJung-uk Kim 
SSL_get_sigalgs(SSL * s,int idx,int * psign,int * phash,int * psignhash,unsigned char * rsig,unsigned char * rhash)23577bded2dbSJung-uk Kim int SSL_get_sigalgs(SSL *s, int idx,
23587bded2dbSJung-uk Kim                     int *psign, int *phash, int *psignhash,
23597bded2dbSJung-uk Kim                     unsigned char *rsig, unsigned char *rhash)
23607bded2dbSJung-uk Kim {
2361b077aed3SPierre Pronchery     uint16_t *psig = s->s3.tmp.peer_sigalgs;
2362b077aed3SPierre Pronchery     size_t numsigalgs = s->s3.tmp.peer_sigalgslen;
2363e71b7053SJung-uk Kim     if (psig == NULL || numsigalgs > INT_MAX)
23647bded2dbSJung-uk Kim         return 0;
23657bded2dbSJung-uk Kim     if (idx >= 0) {
2366e71b7053SJung-uk Kim         const SIGALG_LOOKUP *lu;
2367e71b7053SJung-uk Kim 
2368e71b7053SJung-uk Kim         if (idx >= (int)numsigalgs)
23697bded2dbSJung-uk Kim             return 0;
23707bded2dbSJung-uk Kim         psig += idx;
2371e71b7053SJung-uk Kim         if (rhash != NULL)
2372e71b7053SJung-uk Kim             *rhash = (unsigned char)((*psig >> 8) & 0xff);
2373e71b7053SJung-uk Kim         if (rsig != NULL)
2374e71b7053SJung-uk Kim             *rsig = (unsigned char)(*psig & 0xff);
2375b077aed3SPierre Pronchery         lu = tls1_lookup_sigalg(s, *psig);
2376e71b7053SJung-uk Kim         if (psign != NULL)
2377e71b7053SJung-uk Kim             *psign = lu != NULL ? lu->sig : NID_undef;
2378e71b7053SJung-uk Kim         if (phash != NULL)
2379e71b7053SJung-uk Kim             *phash = lu != NULL ? lu->hash : NID_undef;
2380e71b7053SJung-uk Kim         if (psignhash != NULL)
2381e71b7053SJung-uk Kim             *psignhash = lu != NULL ? lu->sigandhash : NID_undef;
23827bded2dbSJung-uk Kim     }
2383e71b7053SJung-uk Kim     return (int)numsigalgs;
23847bded2dbSJung-uk Kim }
23857bded2dbSJung-uk Kim 
SSL_get_shared_sigalgs(SSL * s,int idx,int * psign,int * phash,int * psignhash,unsigned char * rsig,unsigned char * rhash)23867bded2dbSJung-uk Kim int SSL_get_shared_sigalgs(SSL *s, int idx,
23877bded2dbSJung-uk Kim                            int *psign, int *phash, int *psignhash,
23887bded2dbSJung-uk Kim                            unsigned char *rsig, unsigned char *rhash)
23897bded2dbSJung-uk Kim {
2390e71b7053SJung-uk Kim     const SIGALG_LOOKUP *shsigalgs;
2391da327cd2SJung-uk Kim     if (s->shared_sigalgs == NULL
2392e71b7053SJung-uk Kim         || idx < 0
2393da327cd2SJung-uk Kim         || idx >= (int)s->shared_sigalgslen
2394da327cd2SJung-uk Kim         || s->shared_sigalgslen > INT_MAX)
23957bded2dbSJung-uk Kim         return 0;
2396da327cd2SJung-uk Kim     shsigalgs = s->shared_sigalgs[idx];
2397e71b7053SJung-uk Kim     if (phash != NULL)
2398e71b7053SJung-uk Kim         *phash = shsigalgs->hash;
2399e71b7053SJung-uk Kim     if (psign != NULL)
2400e71b7053SJung-uk Kim         *psign = shsigalgs->sig;
2401e71b7053SJung-uk Kim     if (psignhash != NULL)
2402e71b7053SJung-uk Kim         *psignhash = shsigalgs->sigandhash;
2403e71b7053SJung-uk Kim     if (rsig != NULL)
2404e71b7053SJung-uk Kim         *rsig = (unsigned char)(shsigalgs->sigalg & 0xff);
2405e71b7053SJung-uk Kim     if (rhash != NULL)
2406e71b7053SJung-uk Kim         *rhash = (unsigned char)((shsigalgs->sigalg >> 8) & 0xff);
2407da327cd2SJung-uk Kim     return (int)s->shared_sigalgslen;
24087bded2dbSJung-uk Kim }
24091f13597dSJung-uk Kim 
2410e71b7053SJung-uk Kim /* Maximum possible number of unique entries in sigalgs array */
2411e71b7053SJung-uk Kim #define TLS_MAX_SIGALGCNT (OSSL_NELEM(sigalg_lookup_tbl) * 2)
24127bded2dbSJung-uk Kim 
24137bded2dbSJung-uk Kim typedef struct {
24147bded2dbSJung-uk Kim     size_t sigalgcnt;
2415e71b7053SJung-uk Kim     /* TLSEXT_SIGALG_XXX values */
2416e71b7053SJung-uk Kim     uint16_t sigalgs[TLS_MAX_SIGALGCNT];
24177bded2dbSJung-uk Kim } sig_cb_st;
24187bded2dbSJung-uk Kim 
get_sigorhash(int * psig,int * phash,const char * str)2419e71b7053SJung-uk Kim static void get_sigorhash(int *psig, int *phash, const char *str)
2420e71b7053SJung-uk Kim {
2421e71b7053SJung-uk Kim     if (strcmp(str, "RSA") == 0) {
2422e71b7053SJung-uk Kim         *psig = EVP_PKEY_RSA;
2423e71b7053SJung-uk Kim     } else if (strcmp(str, "RSA-PSS") == 0 || strcmp(str, "PSS") == 0) {
2424e71b7053SJung-uk Kim         *psig = EVP_PKEY_RSA_PSS;
2425e71b7053SJung-uk Kim     } else if (strcmp(str, "DSA") == 0) {
2426e71b7053SJung-uk Kim         *psig = EVP_PKEY_DSA;
2427e71b7053SJung-uk Kim     } else if (strcmp(str, "ECDSA") == 0) {
2428e71b7053SJung-uk Kim         *psig = EVP_PKEY_EC;
2429e71b7053SJung-uk Kim     } else {
2430e71b7053SJung-uk Kim         *phash = OBJ_sn2nid(str);
2431e71b7053SJung-uk Kim         if (*phash == NID_undef)
2432e71b7053SJung-uk Kim             *phash = OBJ_ln2nid(str);
2433e71b7053SJung-uk Kim     }
2434e71b7053SJung-uk Kim }
2435e71b7053SJung-uk Kim /* Maximum length of a signature algorithm string component */
2436e71b7053SJung-uk Kim #define TLS_MAX_SIGSTRING_LEN   40
2437e71b7053SJung-uk Kim 
sig_cb(const char * elem,int len,void * arg)24387bded2dbSJung-uk Kim static int sig_cb(const char *elem, int len, void *arg)
24397bded2dbSJung-uk Kim {
24407bded2dbSJung-uk Kim     sig_cb_st *sarg = arg;
24417bded2dbSJung-uk Kim     size_t i;
2442e71b7053SJung-uk Kim     const SIGALG_LOOKUP *s;
2443e71b7053SJung-uk Kim     char etmp[TLS_MAX_SIGSTRING_LEN], *p;
2444e71b7053SJung-uk Kim     int sig_alg = NID_undef, hash_alg = NID_undef;
24457bded2dbSJung-uk Kim     if (elem == NULL)
24467bded2dbSJung-uk Kim         return 0;
2447e71b7053SJung-uk Kim     if (sarg->sigalgcnt == TLS_MAX_SIGALGCNT)
24487bded2dbSJung-uk Kim         return 0;
24497bded2dbSJung-uk Kim     if (len > (int)(sizeof(etmp) - 1))
24507bded2dbSJung-uk Kim         return 0;
24517bded2dbSJung-uk Kim     memcpy(etmp, elem, len);
24527bded2dbSJung-uk Kim     etmp[len] = 0;
24537bded2dbSJung-uk Kim     p = strchr(etmp, '+');
2454e71b7053SJung-uk Kim     /*
2455e71b7053SJung-uk Kim      * We only allow SignatureSchemes listed in the sigalg_lookup_tbl;
2456e71b7053SJung-uk Kim      * if there's no '+' in the provided name, look for the new-style combined
2457e71b7053SJung-uk Kim      * name.  If not, match both sig+hash to find the needed SIGALG_LOOKUP.
2458e71b7053SJung-uk Kim      * Just sig+hash is not unique since TLS 1.3 adds rsa_pss_pss_* and
2459e71b7053SJung-uk Kim      * rsa_pss_rsae_* that differ only by public key OID; in such cases
2460e71b7053SJung-uk Kim      * we will pick the _rsae_ variant, by virtue of them appearing earlier
2461e71b7053SJung-uk Kim      * in the table.
2462e71b7053SJung-uk Kim      */
2463e71b7053SJung-uk Kim     if (p == NULL) {
2464e71b7053SJung-uk Kim         for (i = 0, s = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl);
2465e71b7053SJung-uk Kim              i++, s++) {
2466e71b7053SJung-uk Kim             if (s->name != NULL && strcmp(etmp, s->name) == 0) {
2467e71b7053SJung-uk Kim                 sarg->sigalgs[sarg->sigalgcnt++] = s->sigalg;
2468e71b7053SJung-uk Kim                 break;
2469e71b7053SJung-uk Kim             }
2470e71b7053SJung-uk Kim         }
2471e71b7053SJung-uk Kim         if (i == OSSL_NELEM(sigalg_lookup_tbl))
24727bded2dbSJung-uk Kim             return 0;
2473e71b7053SJung-uk Kim     } else {
24747bded2dbSJung-uk Kim         *p = 0;
24757bded2dbSJung-uk Kim         p++;
2476e71b7053SJung-uk Kim         if (*p == 0)
24777bded2dbSJung-uk Kim             return 0;
2478e71b7053SJung-uk Kim         get_sigorhash(&sig_alg, &hash_alg, etmp);
2479e71b7053SJung-uk Kim         get_sigorhash(&sig_alg, &hash_alg, p);
2480e71b7053SJung-uk Kim         if (sig_alg == NID_undef || hash_alg == NID_undef)
24817bded2dbSJung-uk Kim             return 0;
2482e71b7053SJung-uk Kim         for (i = 0, s = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl);
2483e71b7053SJung-uk Kim              i++, s++) {
2484e71b7053SJung-uk Kim             if (s->hash == hash_alg && s->sig == sig_alg) {
2485e71b7053SJung-uk Kim                 sarg->sigalgs[sarg->sigalgcnt++] = s->sigalg;
2486e71b7053SJung-uk Kim                 break;
2487e71b7053SJung-uk Kim             }
2488e71b7053SJung-uk Kim         }
2489e71b7053SJung-uk Kim         if (i == OSSL_NELEM(sigalg_lookup_tbl))
24907bded2dbSJung-uk Kim             return 0;
24917bded2dbSJung-uk Kim     }
2492e71b7053SJung-uk Kim 
2493e71b7053SJung-uk Kim     /* Reject duplicates */
2494e71b7053SJung-uk Kim     for (i = 0; i < sarg->sigalgcnt - 1; i++) {
2495e71b7053SJung-uk Kim         if (sarg->sigalgs[i] == sarg->sigalgs[sarg->sigalgcnt - 1]) {
2496e71b7053SJung-uk Kim             sarg->sigalgcnt--;
2497e71b7053SJung-uk Kim             return 0;
2498e71b7053SJung-uk Kim         }
2499e71b7053SJung-uk Kim     }
25007bded2dbSJung-uk Kim     return 1;
25017bded2dbSJung-uk Kim }
25027bded2dbSJung-uk Kim 
25037bded2dbSJung-uk Kim /*
2504e71b7053SJung-uk Kim  * Set supported signature algorithms based on a colon separated list of the
25057bded2dbSJung-uk Kim  * form sig+hash e.g. RSA+SHA512:DSA+SHA512
25067bded2dbSJung-uk Kim  */
tls1_set_sigalgs_list(CERT * c,const char * str,int client)25077bded2dbSJung-uk Kim int tls1_set_sigalgs_list(CERT *c, const char *str, int client)
25087bded2dbSJung-uk Kim {
25097bded2dbSJung-uk Kim     sig_cb_st sig;
25107bded2dbSJung-uk Kim     sig.sigalgcnt = 0;
25117bded2dbSJung-uk Kim     if (!CONF_parse_list(str, ':', 1, sig_cb, &sig))
25127bded2dbSJung-uk Kim         return 0;
25137bded2dbSJung-uk Kim     if (c == NULL)
25147bded2dbSJung-uk Kim         return 1;
2515e71b7053SJung-uk Kim     return tls1_set_raw_sigalgs(c, sig.sigalgs, sig.sigalgcnt, client);
25167bded2dbSJung-uk Kim }
25177bded2dbSJung-uk Kim 
tls1_set_raw_sigalgs(CERT * c,const uint16_t * psigs,size_t salglen,int client)2518e71b7053SJung-uk Kim int tls1_set_raw_sigalgs(CERT *c, const uint16_t *psigs, size_t salglen,
25197bded2dbSJung-uk Kim                      int client)
25207bded2dbSJung-uk Kim {
2521e71b7053SJung-uk Kim     uint16_t *sigalgs;
25227bded2dbSJung-uk Kim 
2523e71b7053SJung-uk Kim     if ((sigalgs = OPENSSL_malloc(salglen * sizeof(*sigalgs))) == NULL) {
2524b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
2525e71b7053SJung-uk Kim         return 0;
25267bded2dbSJung-uk Kim     }
2527e71b7053SJung-uk Kim     memcpy(sigalgs, psigs, salglen * sizeof(*sigalgs));
25287bded2dbSJung-uk Kim 
25297bded2dbSJung-uk Kim     if (client) {
25307bded2dbSJung-uk Kim         OPENSSL_free(c->client_sigalgs);
25317bded2dbSJung-uk Kim         c->client_sigalgs = sigalgs;
25327bded2dbSJung-uk Kim         c->client_sigalgslen = salglen;
25337bded2dbSJung-uk Kim     } else {
25347bded2dbSJung-uk Kim         OPENSSL_free(c->conf_sigalgs);
25357bded2dbSJung-uk Kim         c->conf_sigalgs = sigalgs;
25367bded2dbSJung-uk Kim         c->conf_sigalgslen = salglen;
25377bded2dbSJung-uk Kim     }
25387bded2dbSJung-uk Kim 
25397bded2dbSJung-uk Kim     return 1;
2540e71b7053SJung-uk Kim }
2541e71b7053SJung-uk Kim 
tls1_set_sigalgs(CERT * c,const int * psig_nids,size_t salglen,int client)2542e71b7053SJung-uk Kim int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client)
2543e71b7053SJung-uk Kim {
2544e71b7053SJung-uk Kim     uint16_t *sigalgs, *sptr;
2545e71b7053SJung-uk Kim     size_t i;
2546e71b7053SJung-uk Kim 
2547e71b7053SJung-uk Kim     if (salglen & 1)
2548e71b7053SJung-uk Kim         return 0;
2549e71b7053SJung-uk Kim     if ((sigalgs = OPENSSL_malloc((salglen / 2) * sizeof(*sigalgs))) == NULL) {
2550b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
2551e71b7053SJung-uk Kim         return 0;
2552e71b7053SJung-uk Kim     }
2553e71b7053SJung-uk Kim     for (i = 0, sptr = sigalgs; i < salglen; i += 2) {
2554e71b7053SJung-uk Kim         size_t j;
2555e71b7053SJung-uk Kim         const SIGALG_LOOKUP *curr;
2556e71b7053SJung-uk Kim         int md_id = *psig_nids++;
2557e71b7053SJung-uk Kim         int sig_id = *psig_nids++;
2558e71b7053SJung-uk Kim 
2559e71b7053SJung-uk Kim         for (j = 0, curr = sigalg_lookup_tbl; j < OSSL_NELEM(sigalg_lookup_tbl);
2560e71b7053SJung-uk Kim              j++, curr++) {
2561e71b7053SJung-uk Kim             if (curr->hash == md_id && curr->sig == sig_id) {
2562e71b7053SJung-uk Kim                 *sptr++ = curr->sigalg;
2563e71b7053SJung-uk Kim                 break;
2564e71b7053SJung-uk Kim             }
2565e71b7053SJung-uk Kim         }
2566e71b7053SJung-uk Kim 
2567e71b7053SJung-uk Kim         if (j == OSSL_NELEM(sigalg_lookup_tbl))
2568e71b7053SJung-uk Kim             goto err;
2569e71b7053SJung-uk Kim     }
2570e71b7053SJung-uk Kim 
2571e71b7053SJung-uk Kim     if (client) {
2572e71b7053SJung-uk Kim         OPENSSL_free(c->client_sigalgs);
2573e71b7053SJung-uk Kim         c->client_sigalgs = sigalgs;
2574e71b7053SJung-uk Kim         c->client_sigalgslen = salglen / 2;
2575e71b7053SJung-uk Kim     } else {
2576e71b7053SJung-uk Kim         OPENSSL_free(c->conf_sigalgs);
2577e71b7053SJung-uk Kim         c->conf_sigalgs = sigalgs;
2578e71b7053SJung-uk Kim         c->conf_sigalgslen = salglen / 2;
2579e71b7053SJung-uk Kim     }
2580e71b7053SJung-uk Kim 
2581e71b7053SJung-uk Kim     return 1;
25827bded2dbSJung-uk Kim 
25837bded2dbSJung-uk Kim  err:
25847bded2dbSJung-uk Kim     OPENSSL_free(sigalgs);
25857bded2dbSJung-uk Kim     return 0;
25867bded2dbSJung-uk Kim }
25877bded2dbSJung-uk Kim 
tls1_check_sig_alg(SSL * s,X509 * x,int default_nid)2588da327cd2SJung-uk Kim static int tls1_check_sig_alg(SSL *s, X509 *x, int default_nid)
25897bded2dbSJung-uk Kim {
2590da327cd2SJung-uk Kim     int sig_nid, use_pc_sigalgs = 0;
25917bded2dbSJung-uk Kim     size_t i;
2592da327cd2SJung-uk Kim     const SIGALG_LOOKUP *sigalg;
2593da327cd2SJung-uk Kim     size_t sigalgslen;
25947bded2dbSJung-uk Kim     if (default_nid == -1)
25957bded2dbSJung-uk Kim         return 1;
25967bded2dbSJung-uk Kim     sig_nid = X509_get_signature_nid(x);
25977bded2dbSJung-uk Kim     if (default_nid)
25987bded2dbSJung-uk Kim         return sig_nid == default_nid ? 1 : 0;
2599da327cd2SJung-uk Kim 
2600b077aed3SPierre Pronchery     if (SSL_IS_TLS13(s) && s->s3.tmp.peer_cert_sigalgs != NULL) {
2601da327cd2SJung-uk Kim         /*
2602da327cd2SJung-uk Kim          * If we're in TLSv1.3 then we only get here if we're checking the
2603da327cd2SJung-uk Kim          * chain. If the peer has specified peer_cert_sigalgs then we use them
2604da327cd2SJung-uk Kim          * otherwise we default to normal sigalgs.
2605da327cd2SJung-uk Kim          */
2606b077aed3SPierre Pronchery         sigalgslen = s->s3.tmp.peer_cert_sigalgslen;
2607da327cd2SJung-uk Kim         use_pc_sigalgs = 1;
2608da327cd2SJung-uk Kim     } else {
2609da327cd2SJung-uk Kim         sigalgslen = s->shared_sigalgslen;
2610da327cd2SJung-uk Kim     }
2611da327cd2SJung-uk Kim     for (i = 0; i < sigalgslen; i++) {
2612da327cd2SJung-uk Kim         sigalg = use_pc_sigalgs
2613b077aed3SPierre Pronchery                  ? tls1_lookup_sigalg(s, s->s3.tmp.peer_cert_sigalgs[i])
2614da327cd2SJung-uk Kim                  : s->shared_sigalgs[i];
2615c79d631aSGordon Tetlow         if (sigalg != NULL && sig_nid == sigalg->sigandhash)
26167bded2dbSJung-uk Kim             return 1;
2617da327cd2SJung-uk Kim     }
26187bded2dbSJung-uk Kim     return 0;
26197bded2dbSJung-uk Kim }
26207bded2dbSJung-uk Kim 
26217bded2dbSJung-uk Kim /* Check to see if a certificate issuer name matches list of CA names */
ssl_check_ca_name(STACK_OF (X509_NAME)* names,X509 * x)26227bded2dbSJung-uk Kim static int ssl_check_ca_name(STACK_OF(X509_NAME) *names, X509 *x)
26237bded2dbSJung-uk Kim {
2624b077aed3SPierre Pronchery     const X509_NAME *nm;
26257bded2dbSJung-uk Kim     int i;
26267bded2dbSJung-uk Kim     nm = X509_get_issuer_name(x);
26277bded2dbSJung-uk Kim     for (i = 0; i < sk_X509_NAME_num(names); i++) {
26287bded2dbSJung-uk Kim         if (!X509_NAME_cmp(nm, sk_X509_NAME_value(names, i)))
26297bded2dbSJung-uk Kim             return 1;
26307bded2dbSJung-uk Kim     }
26317bded2dbSJung-uk Kim     return 0;
26327bded2dbSJung-uk Kim }
26337bded2dbSJung-uk Kim 
26347bded2dbSJung-uk Kim /*
26357bded2dbSJung-uk Kim  * Check certificate chain is consistent with TLS extensions and is usable by
26367bded2dbSJung-uk Kim  * server. This servers two purposes: it allows users to check chains before
26377bded2dbSJung-uk Kim  * passing them to the server and it allows the server to check chains before
26387bded2dbSJung-uk Kim  * attempting to use them.
26397bded2dbSJung-uk Kim  */
26407bded2dbSJung-uk Kim 
2641e71b7053SJung-uk Kim /* Flags which need to be set for a certificate when strict mode not set */
26427bded2dbSJung-uk Kim 
26437bded2dbSJung-uk Kim #define CERT_PKEY_VALID_FLAGS \
26447bded2dbSJung-uk Kim         (CERT_PKEY_EE_SIGNATURE|CERT_PKEY_EE_PARAM)
26457bded2dbSJung-uk Kim /* Strict mode flags */
26467bded2dbSJung-uk Kim #define CERT_PKEY_STRICT_FLAGS \
26477bded2dbSJung-uk Kim          (CERT_PKEY_VALID_FLAGS|CERT_PKEY_CA_SIGNATURE|CERT_PKEY_CA_PARAM \
26487bded2dbSJung-uk Kim          | CERT_PKEY_ISSUER_NAME|CERT_PKEY_CERT_TYPE)
26497bded2dbSJung-uk Kim 
tls1_check_chain(SSL * s,X509 * x,EVP_PKEY * pk,STACK_OF (X509)* chain,int idx)26507bded2dbSJung-uk Kim int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
26517bded2dbSJung-uk Kim                      int idx)
26527bded2dbSJung-uk Kim {
26537bded2dbSJung-uk Kim     int i;
26547bded2dbSJung-uk Kim     int rv = 0;
26557bded2dbSJung-uk Kim     int check_flags = 0, strict_mode;
26567bded2dbSJung-uk Kim     CERT_PKEY *cpk = NULL;
26577bded2dbSJung-uk Kim     CERT *c = s->cert;
2658e71b7053SJung-uk Kim     uint32_t *pvalid;
26597bded2dbSJung-uk Kim     unsigned int suiteb_flags = tls1_suiteb(s);
26607bded2dbSJung-uk Kim     /* idx == -1 means checking server chains */
26617bded2dbSJung-uk Kim     if (idx != -1) {
26627bded2dbSJung-uk Kim         /* idx == -2 means checking client certificate chains */
26637bded2dbSJung-uk Kim         if (idx == -2) {
26647bded2dbSJung-uk Kim             cpk = c->key;
2665e71b7053SJung-uk Kim             idx = (int)(cpk - c->pkeys);
26667bded2dbSJung-uk Kim         } else
26677bded2dbSJung-uk Kim             cpk = c->pkeys + idx;
2668b077aed3SPierre Pronchery         pvalid = s->s3.tmp.valid_flags + idx;
26697bded2dbSJung-uk Kim         x = cpk->x509;
26707bded2dbSJung-uk Kim         pk = cpk->privatekey;
26717bded2dbSJung-uk Kim         chain = cpk->chain;
26727bded2dbSJung-uk Kim         strict_mode = c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT;
26737bded2dbSJung-uk Kim         /* If no cert or key, forget it */
26747bded2dbSJung-uk Kim         if (!x || !pk)
26757bded2dbSJung-uk Kim             goto end;
26767bded2dbSJung-uk Kim     } else {
2677e71b7053SJung-uk Kim         size_t certidx;
2678e71b7053SJung-uk Kim 
26797bded2dbSJung-uk Kim         if (!x || !pk)
26807bded2dbSJung-uk Kim             return 0;
2681e71b7053SJung-uk Kim 
2682e71b7053SJung-uk Kim         if (ssl_cert_lookup_by_pkey(pk, &certidx) == NULL)
26837bded2dbSJung-uk Kim             return 0;
2684e71b7053SJung-uk Kim         idx = certidx;
2685b077aed3SPierre Pronchery         pvalid = s->s3.tmp.valid_flags + idx;
2686e71b7053SJung-uk Kim 
26877bded2dbSJung-uk Kim         if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)
26887bded2dbSJung-uk Kim             check_flags = CERT_PKEY_STRICT_FLAGS;
26897bded2dbSJung-uk Kim         else
26907bded2dbSJung-uk Kim             check_flags = CERT_PKEY_VALID_FLAGS;
26917bded2dbSJung-uk Kim         strict_mode = 1;
26927bded2dbSJung-uk Kim     }
26937bded2dbSJung-uk Kim 
26947bded2dbSJung-uk Kim     if (suiteb_flags) {
26957bded2dbSJung-uk Kim         int ok;
26967bded2dbSJung-uk Kim         if (check_flags)
26977bded2dbSJung-uk Kim             check_flags |= CERT_PKEY_SUITEB;
26987bded2dbSJung-uk Kim         ok = X509_chain_check_suiteb(NULL, x, chain, suiteb_flags);
26997bded2dbSJung-uk Kim         if (ok == X509_V_OK)
27007bded2dbSJung-uk Kim             rv |= CERT_PKEY_SUITEB;
27017bded2dbSJung-uk Kim         else if (!check_flags)
27027bded2dbSJung-uk Kim             goto end;
27037bded2dbSJung-uk Kim     }
27047bded2dbSJung-uk Kim 
27057bded2dbSJung-uk Kim     /*
27067bded2dbSJung-uk Kim      * Check all signature algorithms are consistent with signature
27077bded2dbSJung-uk Kim      * algorithms extension if TLS 1.2 or later and strict mode.
27087bded2dbSJung-uk Kim      */
27097bded2dbSJung-uk Kim     if (TLS1_get_version(s) >= TLS1_2_VERSION && strict_mode) {
27107bded2dbSJung-uk Kim         int default_nid;
2711e71b7053SJung-uk Kim         int rsign = 0;
2712b077aed3SPierre Pronchery         if (s->s3.tmp.peer_cert_sigalgs != NULL
2713b077aed3SPierre Pronchery                 || s->s3.tmp.peer_sigalgs != NULL) {
27147bded2dbSJung-uk Kim             default_nid = 0;
27157bded2dbSJung-uk Kim         /* If no sigalgs extension use defaults from RFC5246 */
2716e71b7053SJung-uk Kim         } else {
27177bded2dbSJung-uk Kim             switch (idx) {
2718e71b7053SJung-uk Kim             case SSL_PKEY_RSA:
2719e71b7053SJung-uk Kim                 rsign = EVP_PKEY_RSA;
27207bded2dbSJung-uk Kim                 default_nid = NID_sha1WithRSAEncryption;
27217bded2dbSJung-uk Kim                 break;
27227bded2dbSJung-uk Kim 
27237bded2dbSJung-uk Kim             case SSL_PKEY_DSA_SIGN:
2724e71b7053SJung-uk Kim                 rsign = EVP_PKEY_DSA;
27257bded2dbSJung-uk Kim                 default_nid = NID_dsaWithSHA1;
27267bded2dbSJung-uk Kim                 break;
27277bded2dbSJung-uk Kim 
27287bded2dbSJung-uk Kim             case SSL_PKEY_ECC:
2729e71b7053SJung-uk Kim                 rsign = EVP_PKEY_EC;
27307bded2dbSJung-uk Kim                 default_nid = NID_ecdsa_with_SHA1;
27317bded2dbSJung-uk Kim                 break;
27327bded2dbSJung-uk Kim 
2733e71b7053SJung-uk Kim             case SSL_PKEY_GOST01:
2734e71b7053SJung-uk Kim                 rsign = NID_id_GostR3410_2001;
2735e71b7053SJung-uk Kim                 default_nid = NID_id_GostR3411_94_with_GostR3410_2001;
2736e71b7053SJung-uk Kim                 break;
2737e71b7053SJung-uk Kim 
2738e71b7053SJung-uk Kim             case SSL_PKEY_GOST12_256:
2739e71b7053SJung-uk Kim                 rsign = NID_id_GostR3410_2012_256;
2740e71b7053SJung-uk Kim                 default_nid = NID_id_tc26_signwithdigest_gost3410_2012_256;
2741e71b7053SJung-uk Kim                 break;
2742e71b7053SJung-uk Kim 
2743e71b7053SJung-uk Kim             case SSL_PKEY_GOST12_512:
2744e71b7053SJung-uk Kim                 rsign = NID_id_GostR3410_2012_512;
2745e71b7053SJung-uk Kim                 default_nid = NID_id_tc26_signwithdigest_gost3410_2012_512;
2746e71b7053SJung-uk Kim                 break;
2747e71b7053SJung-uk Kim 
27487bded2dbSJung-uk Kim             default:
27497bded2dbSJung-uk Kim                 default_nid = -1;
27507bded2dbSJung-uk Kim                 break;
27517bded2dbSJung-uk Kim             }
27527bded2dbSJung-uk Kim         }
27537bded2dbSJung-uk Kim         /*
27547bded2dbSJung-uk Kim          * If peer sent no signature algorithms extension and we have set
27557bded2dbSJung-uk Kim          * preferred signature algorithms check we support sha1.
27567bded2dbSJung-uk Kim          */
27577bded2dbSJung-uk Kim         if (default_nid > 0 && c->conf_sigalgs) {
27587bded2dbSJung-uk Kim             size_t j;
2759e71b7053SJung-uk Kim             const uint16_t *p = c->conf_sigalgs;
2760e71b7053SJung-uk Kim             for (j = 0; j < c->conf_sigalgslen; j++, p++) {
2761b077aed3SPierre Pronchery                 const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *p);
2762e71b7053SJung-uk Kim 
2763e71b7053SJung-uk Kim                 if (lu != NULL && lu->hash == NID_sha1 && lu->sig == rsign)
27647bded2dbSJung-uk Kim                     break;
27657bded2dbSJung-uk Kim             }
27667bded2dbSJung-uk Kim             if (j == c->conf_sigalgslen) {
27677bded2dbSJung-uk Kim                 if (check_flags)
27687bded2dbSJung-uk Kim                     goto skip_sigs;
27697bded2dbSJung-uk Kim                 else
27707bded2dbSJung-uk Kim                     goto end;
27717bded2dbSJung-uk Kim             }
27727bded2dbSJung-uk Kim         }
27737bded2dbSJung-uk Kim         /* Check signature algorithm of each cert in chain */
2774da327cd2SJung-uk Kim         if (SSL_IS_TLS13(s)) {
2775da327cd2SJung-uk Kim             /*
2776da327cd2SJung-uk Kim              * We only get here if the application has called SSL_check_chain(),
2777da327cd2SJung-uk Kim              * so check_flags is always set.
2778da327cd2SJung-uk Kim              */
2779da327cd2SJung-uk Kim             if (find_sig_alg(s, x, pk) != NULL)
2780da327cd2SJung-uk Kim                 rv |= CERT_PKEY_EE_SIGNATURE;
2781da327cd2SJung-uk Kim         } else if (!tls1_check_sig_alg(s, x, default_nid)) {
27827bded2dbSJung-uk Kim             if (!check_flags)
27837bded2dbSJung-uk Kim                 goto end;
27847bded2dbSJung-uk Kim         } else
27857bded2dbSJung-uk Kim             rv |= CERT_PKEY_EE_SIGNATURE;
27867bded2dbSJung-uk Kim         rv |= CERT_PKEY_CA_SIGNATURE;
27877bded2dbSJung-uk Kim         for (i = 0; i < sk_X509_num(chain); i++) {
2788da327cd2SJung-uk Kim             if (!tls1_check_sig_alg(s, sk_X509_value(chain, i), default_nid)) {
27897bded2dbSJung-uk Kim                 if (check_flags) {
27907bded2dbSJung-uk Kim                     rv &= ~CERT_PKEY_CA_SIGNATURE;
27917bded2dbSJung-uk Kim                     break;
27927bded2dbSJung-uk Kim                 } else
27937bded2dbSJung-uk Kim                     goto end;
27947bded2dbSJung-uk Kim             }
27957bded2dbSJung-uk Kim         }
27967bded2dbSJung-uk Kim     }
27977bded2dbSJung-uk Kim     /* Else not TLS 1.2, so mark EE and CA signing algorithms OK */
27987bded2dbSJung-uk Kim     else if (check_flags)
27997bded2dbSJung-uk Kim         rv |= CERT_PKEY_EE_SIGNATURE | CERT_PKEY_CA_SIGNATURE;
28007bded2dbSJung-uk Kim  skip_sigs:
28017bded2dbSJung-uk Kim     /* Check cert parameters are consistent */
2802e71b7053SJung-uk Kim     if (tls1_check_cert_param(s, x, 1))
28037bded2dbSJung-uk Kim         rv |= CERT_PKEY_EE_PARAM;
28047bded2dbSJung-uk Kim     else if (!check_flags)
28057bded2dbSJung-uk Kim         goto end;
28067bded2dbSJung-uk Kim     if (!s->server)
28077bded2dbSJung-uk Kim         rv |= CERT_PKEY_CA_PARAM;
28087bded2dbSJung-uk Kim     /* In strict mode check rest of chain too */
28097bded2dbSJung-uk Kim     else if (strict_mode) {
28107bded2dbSJung-uk Kim         rv |= CERT_PKEY_CA_PARAM;
28117bded2dbSJung-uk Kim         for (i = 0; i < sk_X509_num(chain); i++) {
28127bded2dbSJung-uk Kim             X509 *ca = sk_X509_value(chain, i);
28137bded2dbSJung-uk Kim             if (!tls1_check_cert_param(s, ca, 0)) {
28147bded2dbSJung-uk Kim                 if (check_flags) {
28157bded2dbSJung-uk Kim                     rv &= ~CERT_PKEY_CA_PARAM;
28167bded2dbSJung-uk Kim                     break;
28177bded2dbSJung-uk Kim                 } else
28187bded2dbSJung-uk Kim                     goto end;
28197bded2dbSJung-uk Kim             }
28207bded2dbSJung-uk Kim         }
28217bded2dbSJung-uk Kim     }
28227bded2dbSJung-uk Kim     if (!s->server && strict_mode) {
28237bded2dbSJung-uk Kim         STACK_OF(X509_NAME) *ca_dn;
28247bded2dbSJung-uk Kim         int check_type = 0;
2825b077aed3SPierre Pronchery 
2826b077aed3SPierre Pronchery         if (EVP_PKEY_is_a(pk, "RSA"))
28277bded2dbSJung-uk Kim             check_type = TLS_CT_RSA_SIGN;
2828b077aed3SPierre Pronchery         else if (EVP_PKEY_is_a(pk, "DSA"))
28297bded2dbSJung-uk Kim             check_type = TLS_CT_DSS_SIGN;
2830b077aed3SPierre Pronchery         else if (EVP_PKEY_is_a(pk, "EC"))
28317bded2dbSJung-uk Kim             check_type = TLS_CT_ECDSA_SIGN;
2832b077aed3SPierre Pronchery 
28337bded2dbSJung-uk Kim         if (check_type) {
2834b077aed3SPierre Pronchery             const uint8_t *ctypes = s->s3.tmp.ctype;
2835e71b7053SJung-uk Kim             size_t j;
2836e71b7053SJung-uk Kim 
2837b077aed3SPierre Pronchery             for (j = 0; j < s->s3.tmp.ctype_len; j++, ctypes++) {
2838e71b7053SJung-uk Kim                 if (*ctypes == check_type) {
28397bded2dbSJung-uk Kim                     rv |= CERT_PKEY_CERT_TYPE;
28407bded2dbSJung-uk Kim                     break;
28417bded2dbSJung-uk Kim                 }
28427bded2dbSJung-uk Kim             }
28437bded2dbSJung-uk Kim             if (!(rv & CERT_PKEY_CERT_TYPE) && !check_flags)
28447bded2dbSJung-uk Kim                 goto end;
2845e71b7053SJung-uk Kim         } else {
28467bded2dbSJung-uk Kim             rv |= CERT_PKEY_CERT_TYPE;
2847e71b7053SJung-uk Kim         }
28487bded2dbSJung-uk Kim 
2849b077aed3SPierre Pronchery         ca_dn = s->s3.tmp.peer_ca_names;
28507bded2dbSJung-uk Kim 
285183eaf7aeSJung-uk Kim         if (ca_dn == NULL
285283eaf7aeSJung-uk Kim             || sk_X509_NAME_num(ca_dn) == 0
285383eaf7aeSJung-uk Kim             || ssl_check_ca_name(ca_dn, x))
28547bded2dbSJung-uk Kim             rv |= CERT_PKEY_ISSUER_NAME;
285583eaf7aeSJung-uk Kim         else
28567bded2dbSJung-uk Kim             for (i = 0; i < sk_X509_num(chain); i++) {
28577bded2dbSJung-uk Kim                 X509 *xtmp = sk_X509_value(chain, i);
285883eaf7aeSJung-uk Kim 
28597bded2dbSJung-uk Kim                 if (ssl_check_ca_name(ca_dn, xtmp)) {
28607bded2dbSJung-uk Kim                     rv |= CERT_PKEY_ISSUER_NAME;
28617bded2dbSJung-uk Kim                     break;
28627bded2dbSJung-uk Kim                 }
28637bded2dbSJung-uk Kim             }
286483eaf7aeSJung-uk Kim 
28657bded2dbSJung-uk Kim         if (!check_flags && !(rv & CERT_PKEY_ISSUER_NAME))
28667bded2dbSJung-uk Kim             goto end;
28677bded2dbSJung-uk Kim     } else
28687bded2dbSJung-uk Kim         rv |= CERT_PKEY_ISSUER_NAME | CERT_PKEY_CERT_TYPE;
28697bded2dbSJung-uk Kim 
28707bded2dbSJung-uk Kim     if (!check_flags || (rv & check_flags) == check_flags)
28717bded2dbSJung-uk Kim         rv |= CERT_PKEY_VALID;
28727bded2dbSJung-uk Kim 
28737bded2dbSJung-uk Kim  end:
28747bded2dbSJung-uk Kim 
2875e71b7053SJung-uk Kim     if (TLS1_get_version(s) >= TLS1_2_VERSION)
2876e71b7053SJung-uk Kim         rv |= *pvalid & (CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN);
2877e71b7053SJung-uk Kim     else
28787bded2dbSJung-uk Kim         rv |= CERT_PKEY_SIGN | CERT_PKEY_EXPLICIT_SIGN;
28797bded2dbSJung-uk Kim 
28807bded2dbSJung-uk Kim     /*
28817bded2dbSJung-uk Kim      * When checking a CERT_PKEY structure all flags are irrelevant if the
28827bded2dbSJung-uk Kim      * chain is invalid.
28837bded2dbSJung-uk Kim      */
28847bded2dbSJung-uk Kim     if (!check_flags) {
2885e71b7053SJung-uk Kim         if (rv & CERT_PKEY_VALID) {
2886e71b7053SJung-uk Kim             *pvalid = rv;
2887e71b7053SJung-uk Kim         } else {
2888e71b7053SJung-uk Kim             /* Preserve sign and explicit sign flag, clear rest */
2889e71b7053SJung-uk Kim             *pvalid &= CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN;
28907bded2dbSJung-uk Kim             return 0;
28917bded2dbSJung-uk Kim         }
28927bded2dbSJung-uk Kim     }
28937bded2dbSJung-uk Kim     return rv;
28947bded2dbSJung-uk Kim }
28957bded2dbSJung-uk Kim 
28967bded2dbSJung-uk Kim /* Set validity of certificates in an SSL structure */
tls1_set_cert_validity(SSL * s)28977bded2dbSJung-uk Kim void tls1_set_cert_validity(SSL *s)
28987bded2dbSJung-uk Kim {
2899e71b7053SJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA);
2900e71b7053SJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_PSS_SIGN);
29017bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DSA_SIGN);
29027bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ECC);
2903e71b7053SJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_GOST01);
2904e71b7053SJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_GOST12_256);
2905e71b7053SJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_GOST12_512);
2906e71b7053SJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ED25519);
2907e71b7053SJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ED448);
29087bded2dbSJung-uk Kim }
29097bded2dbSJung-uk Kim 
2910e71b7053SJung-uk Kim /* User level utility function to check a chain is suitable */
SSL_check_chain(SSL * s,X509 * x,EVP_PKEY * pk,STACK_OF (X509)* chain)29117bded2dbSJung-uk Kim int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
29127bded2dbSJung-uk Kim {
29137bded2dbSJung-uk Kim     return tls1_check_chain(s, x, pk, chain, -1);
29147bded2dbSJung-uk Kim }
29157bded2dbSJung-uk Kim 
ssl_get_auto_dh(SSL * s)2916b077aed3SPierre Pronchery EVP_PKEY *ssl_get_auto_dh(SSL *s)
2917e71b7053SJung-uk Kim {
2918b077aed3SPierre Pronchery     EVP_PKEY *dhp = NULL;
2919b077aed3SPierre Pronchery     BIGNUM *p;
29209a3ae0cdSJung-uk Kim     int dh_secbits = 80, sec_level_bits;
2921b077aed3SPierre Pronchery     EVP_PKEY_CTX *pctx = NULL;
2922b077aed3SPierre Pronchery     OSSL_PARAM_BLD *tmpl = NULL;
2923b077aed3SPierre Pronchery     OSSL_PARAM *params = NULL;
29249a3ae0cdSJung-uk Kim 
292558f35182SJung-uk Kim     if (s->cert->dh_tmp_auto != 2) {
2926b077aed3SPierre Pronchery         if (s->s3.tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aPSK)) {
2927b077aed3SPierre Pronchery             if (s->s3.tmp.new_cipher->strength_bits == 256)
2928e71b7053SJung-uk Kim                 dh_secbits = 128;
2929e71b7053SJung-uk Kim             else
2930e71b7053SJung-uk Kim                 dh_secbits = 80;
2931e71b7053SJung-uk Kim         } else {
2932b077aed3SPierre Pronchery             if (s->s3.tmp.cert == NULL)
2933e71b7053SJung-uk Kim                 return NULL;
2934b077aed3SPierre Pronchery             dh_secbits = EVP_PKEY_get_security_bits(s->s3.tmp.cert->privatekey);
2935e71b7053SJung-uk Kim         }
293658f35182SJung-uk Kim     }
2937e71b7053SJung-uk Kim 
29389a3ae0cdSJung-uk Kim     /* Do not pick a prime that is too weak for the current security level */
29399a3ae0cdSJung-uk Kim     sec_level_bits = ssl_get_security_level_bits(s, NULL, NULL);
29409a3ae0cdSJung-uk Kim     if (dh_secbits < sec_level_bits)
29419a3ae0cdSJung-uk Kim         dh_secbits = sec_level_bits;
29429a3ae0cdSJung-uk Kim 
2943e71b7053SJung-uk Kim     if (dh_secbits >= 192)
2944e71b7053SJung-uk Kim         p = BN_get_rfc3526_prime_8192(NULL);
294558f35182SJung-uk Kim     else if (dh_secbits >= 152)
294658f35182SJung-uk Kim         p = BN_get_rfc3526_prime_4096(NULL);
294758f35182SJung-uk Kim     else if (dh_secbits >= 128)
2948e71b7053SJung-uk Kim         p = BN_get_rfc3526_prime_3072(NULL);
294958f35182SJung-uk Kim     else if (dh_secbits >= 112)
295058f35182SJung-uk Kim         p = BN_get_rfc3526_prime_2048(NULL);
295158f35182SJung-uk Kim     else
295258f35182SJung-uk Kim         p = BN_get_rfc2409_prime_1024(NULL);
2953b077aed3SPierre Pronchery     if (p == NULL)
2954b077aed3SPierre Pronchery         goto err;
2955b077aed3SPierre Pronchery 
2956b077aed3SPierre Pronchery     pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, "DH", s->ctx->propq);
2957b077aed3SPierre Pronchery     if (pctx == NULL
2958b077aed3SPierre Pronchery             || EVP_PKEY_fromdata_init(pctx) != 1)
2959b077aed3SPierre Pronchery         goto err;
2960b077aed3SPierre Pronchery 
2961b077aed3SPierre Pronchery     tmpl = OSSL_PARAM_BLD_new();
2962b077aed3SPierre Pronchery     if (tmpl == NULL
2963b077aed3SPierre Pronchery             || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p)
2964b077aed3SPierre Pronchery             || !OSSL_PARAM_BLD_push_uint(tmpl, OSSL_PKEY_PARAM_FFC_G, 2))
2965b077aed3SPierre Pronchery         goto err;
2966b077aed3SPierre Pronchery 
2967b077aed3SPierre Pronchery     params = OSSL_PARAM_BLD_to_param(tmpl);
2968b077aed3SPierre Pronchery     if (params == NULL
2969b077aed3SPierre Pronchery             || EVP_PKEY_fromdata(pctx, &dhp, EVP_PKEY_KEY_PARAMETERS, params) != 1)
2970b077aed3SPierre Pronchery         goto err;
2971b077aed3SPierre Pronchery 
2972b077aed3SPierre Pronchery err:
2973b077aed3SPierre Pronchery     OSSL_PARAM_free(params);
2974b077aed3SPierre Pronchery     OSSL_PARAM_BLD_free(tmpl);
2975b077aed3SPierre Pronchery     EVP_PKEY_CTX_free(pctx);
2976e71b7053SJung-uk Kim     BN_free(p);
2977e71b7053SJung-uk Kim     return dhp;
2978e71b7053SJung-uk Kim }
2979e71b7053SJung-uk Kim 
ssl_security_cert_key(SSL * s,SSL_CTX * ctx,X509 * x,int op)2980e71b7053SJung-uk Kim static int ssl_security_cert_key(SSL *s, SSL_CTX *ctx, X509 *x, int op)
2981e71b7053SJung-uk Kim {
2982e71b7053SJung-uk Kim     int secbits = -1;
2983e71b7053SJung-uk Kim     EVP_PKEY *pkey = X509_get0_pubkey(x);
2984e71b7053SJung-uk Kim     if (pkey) {
2985e71b7053SJung-uk Kim         /*
2986e71b7053SJung-uk Kim          * If no parameters this will return -1 and fail using the default
2987e71b7053SJung-uk Kim          * security callback for any non-zero security level. This will
2988e71b7053SJung-uk Kim          * reject keys which omit parameters but this only affects DSA and
2989e71b7053SJung-uk Kim          * omission of parameters is never (?) done in practice.
2990e71b7053SJung-uk Kim          */
2991b077aed3SPierre Pronchery         secbits = EVP_PKEY_get_security_bits(pkey);
2992e71b7053SJung-uk Kim     }
2993e71b7053SJung-uk Kim     if (s)
2994e71b7053SJung-uk Kim         return ssl_security(s, op, secbits, 0, x);
2995e71b7053SJung-uk Kim     else
2996e71b7053SJung-uk Kim         return ssl_ctx_security(ctx, op, secbits, 0, x);
2997e71b7053SJung-uk Kim }
2998e71b7053SJung-uk Kim 
ssl_security_cert_sig(SSL * s,SSL_CTX * ctx,X509 * x,int op)2999e71b7053SJung-uk Kim static int ssl_security_cert_sig(SSL *s, SSL_CTX *ctx, X509 *x, int op)
3000e71b7053SJung-uk Kim {
3001e71b7053SJung-uk Kim     /* Lookup signature algorithm digest */
3002e71b7053SJung-uk Kim     int secbits, nid, pknid;
3003e71b7053SJung-uk Kim     /* Don't check signature if self signed */
3004e71b7053SJung-uk Kim     if ((X509_get_extension_flags(x) & EXFLAG_SS) != 0)
3005e71b7053SJung-uk Kim         return 1;
3006e71b7053SJung-uk Kim     if (!X509_get_signature_info(x, &nid, &pknid, &secbits, NULL))
3007e71b7053SJung-uk Kim         secbits = -1;
3008e71b7053SJung-uk Kim     /* If digest NID not defined use signature NID */
3009e71b7053SJung-uk Kim     if (nid == NID_undef)
3010e71b7053SJung-uk Kim         nid = pknid;
3011e71b7053SJung-uk Kim     if (s)
3012e71b7053SJung-uk Kim         return ssl_security(s, op, secbits, nid, x);
3013e71b7053SJung-uk Kim     else
3014e71b7053SJung-uk Kim         return ssl_ctx_security(ctx, op, secbits, nid, x);
3015e71b7053SJung-uk Kim }
3016e71b7053SJung-uk Kim 
ssl_security_cert(SSL * s,SSL_CTX * ctx,X509 * x,int vfy,int is_ee)3017e71b7053SJung-uk Kim int ssl_security_cert(SSL *s, SSL_CTX *ctx, X509 *x, int vfy, int is_ee)
3018e71b7053SJung-uk Kim {
3019e71b7053SJung-uk Kim     if (vfy)
3020e71b7053SJung-uk Kim         vfy = SSL_SECOP_PEER;
3021e71b7053SJung-uk Kim     if (is_ee) {
3022e71b7053SJung-uk Kim         if (!ssl_security_cert_key(s, ctx, x, SSL_SECOP_EE_KEY | vfy))
3023e71b7053SJung-uk Kim             return SSL_R_EE_KEY_TOO_SMALL;
3024e71b7053SJung-uk Kim     } else {
3025e71b7053SJung-uk Kim         if (!ssl_security_cert_key(s, ctx, x, SSL_SECOP_CA_KEY | vfy))
3026e71b7053SJung-uk Kim             return SSL_R_CA_KEY_TOO_SMALL;
3027e71b7053SJung-uk Kim     }
3028e71b7053SJung-uk Kim     if (!ssl_security_cert_sig(s, ctx, x, SSL_SECOP_CA_MD | vfy))
3029e71b7053SJung-uk Kim         return SSL_R_CA_MD_TOO_WEAK;
3030e71b7053SJung-uk Kim     return 1;
3031e71b7053SJung-uk Kim }
3032e71b7053SJung-uk Kim 
3033e71b7053SJung-uk Kim /*
3034e71b7053SJung-uk Kim  * Check security of a chain, if |sk| includes the end entity certificate then
3035e71b7053SJung-uk Kim  * |x| is NULL. If |vfy| is 1 then we are verifying a peer chain and not sending
3036e71b7053SJung-uk Kim  * one to the peer. Return values: 1 if ok otherwise error code to use
3037e71b7053SJung-uk Kim  */
3038e71b7053SJung-uk Kim 
ssl_security_cert_chain(SSL * s,STACK_OF (X509)* sk,X509 * x,int vfy)3039e71b7053SJung-uk Kim int ssl_security_cert_chain(SSL *s, STACK_OF(X509) *sk, X509 *x, int vfy)
3040e71b7053SJung-uk Kim {
3041e71b7053SJung-uk Kim     int rv, start_idx, i;
3042e71b7053SJung-uk Kim     if (x == NULL) {
3043e71b7053SJung-uk Kim         x = sk_X509_value(sk, 0);
304483eaf7aeSJung-uk Kim         if (x == NULL)
304583eaf7aeSJung-uk Kim             return ERR_R_INTERNAL_ERROR;
3046e71b7053SJung-uk Kim         start_idx = 1;
3047e71b7053SJung-uk Kim     } else
3048e71b7053SJung-uk Kim         start_idx = 0;
3049e71b7053SJung-uk Kim 
3050e71b7053SJung-uk Kim     rv = ssl_security_cert(s, NULL, x, vfy, 1);
3051e71b7053SJung-uk Kim     if (rv != 1)
3052e71b7053SJung-uk Kim         return rv;
3053e71b7053SJung-uk Kim 
3054e71b7053SJung-uk Kim     for (i = start_idx; i < sk_X509_num(sk); i++) {
3055e71b7053SJung-uk Kim         x = sk_X509_value(sk, i);
3056e71b7053SJung-uk Kim         rv = ssl_security_cert(s, NULL, x, vfy, 0);
3057e71b7053SJung-uk Kim         if (rv != 1)
3058e71b7053SJung-uk Kim             return rv;
3059e71b7053SJung-uk Kim     }
3060e71b7053SJung-uk Kim     return 1;
3061e71b7053SJung-uk Kim }
3062e71b7053SJung-uk Kim 
3063e71b7053SJung-uk Kim /*
3064e71b7053SJung-uk Kim  * For TLS 1.2 servers check if we have a certificate which can be used
3065e71b7053SJung-uk Kim  * with the signature algorithm "lu" and return index of certificate.
3066e71b7053SJung-uk Kim  */
3067e71b7053SJung-uk Kim 
tls12_get_cert_sigalg_idx(const SSL * s,const SIGALG_LOOKUP * lu)3068e71b7053SJung-uk Kim static int tls12_get_cert_sigalg_idx(const SSL *s, const SIGALG_LOOKUP *lu)
3069e71b7053SJung-uk Kim {
3070e71b7053SJung-uk Kim     int sig_idx = lu->sig_idx;
3071e71b7053SJung-uk Kim     const SSL_CERT_LOOKUP *clu = ssl_cert_lookup_by_idx(sig_idx);
3072e71b7053SJung-uk Kim 
3073e71b7053SJung-uk Kim     /* If not recognised or not supported by cipher mask it is not suitable */
3074e71b7053SJung-uk Kim     if (clu == NULL
3075b077aed3SPierre Pronchery             || (clu->amask & s->s3.tmp.new_cipher->algorithm_auth) == 0
3076e71b7053SJung-uk Kim             || (clu->nid == EVP_PKEY_RSA_PSS
3077b077aed3SPierre Pronchery                 && (s->s3.tmp.new_cipher->algorithm_mkey & SSL_kRSA) != 0))
3078e71b7053SJung-uk Kim         return -1;
3079e71b7053SJung-uk Kim 
3080b077aed3SPierre Pronchery     return s->s3.tmp.valid_flags[sig_idx] & CERT_PKEY_VALID ? sig_idx : -1;
3081e71b7053SJung-uk Kim }
3082e71b7053SJung-uk Kim 
3083e71b7053SJung-uk Kim /*
3084da327cd2SJung-uk Kim  * Checks the given cert against signature_algorithm_cert restrictions sent by
3085da327cd2SJung-uk Kim  * the peer (if any) as well as whether the hash from the sigalg is usable with
3086da327cd2SJung-uk Kim  * the key.
3087da327cd2SJung-uk Kim  * Returns true if the cert is usable and false otherwise.
3088e71b7053SJung-uk Kim  */
check_cert_usable(SSL * s,const SIGALG_LOOKUP * sig,X509 * x,EVP_PKEY * pkey)3089da327cd2SJung-uk Kim static int check_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x,
3090da327cd2SJung-uk Kim                              EVP_PKEY *pkey)
3091e71b7053SJung-uk Kim {
3092e71b7053SJung-uk Kim     const SIGALG_LOOKUP *lu;
3093b077aed3SPierre Pronchery     int mdnid, pknid, supported;
3094e71b7053SJung-uk Kim     size_t i;
3095b077aed3SPierre Pronchery     const char *mdname = NULL;
3096e71b7053SJung-uk Kim 
3097b077aed3SPierre Pronchery     /*
3098b077aed3SPierre Pronchery      * If the given EVP_PKEY cannot support signing with this digest,
3099b077aed3SPierre Pronchery      * the answer is simply 'no'.
3100b077aed3SPierre Pronchery      */
3101b077aed3SPierre Pronchery     if (sig->hash != NID_undef)
3102b077aed3SPierre Pronchery         mdname = OBJ_nid2sn(sig->hash);
3103b077aed3SPierre Pronchery     supported = EVP_PKEY_digestsign_supports_digest(pkey, s->ctx->libctx,
3104b077aed3SPierre Pronchery                                                     mdname,
3105b077aed3SPierre Pronchery                                                     s->ctx->propq);
3106b077aed3SPierre Pronchery     if (supported <= 0)
3107da327cd2SJung-uk Kim         return 0;
3108da327cd2SJung-uk Kim 
3109e71b7053SJung-uk Kim     /*
3110b077aed3SPierre Pronchery      * The TLS 1.3 signature_algorithms_cert extension places restrictions
3111b077aed3SPierre Pronchery      * on the sigalg with which the certificate was signed (by its issuer).
3112b077aed3SPierre Pronchery      */
3113b077aed3SPierre Pronchery     if (s->s3.tmp.peer_cert_sigalgs != NULL) {
3114b077aed3SPierre Pronchery         if (!X509_get_signature_info(x, &mdnid, &pknid, NULL, NULL))
3115b077aed3SPierre Pronchery             return 0;
3116b077aed3SPierre Pronchery         for (i = 0; i < s->s3.tmp.peer_cert_sigalgslen; i++) {
3117b077aed3SPierre Pronchery             lu = tls1_lookup_sigalg(s, s->s3.tmp.peer_cert_sigalgs[i]);
3118b077aed3SPierre Pronchery             if (lu == NULL)
3119b077aed3SPierre Pronchery                 continue;
3120b077aed3SPierre Pronchery 
3121b077aed3SPierre Pronchery             /*
3122b077aed3SPierre Pronchery              * This does not differentiate between the
3123e71b7053SJung-uk Kim              * rsa_pss_pss_* and rsa_pss_rsae_* schemes since we do not
3124e71b7053SJung-uk Kim              * have a chain here that lets us look at the key OID in the
3125e71b7053SJung-uk Kim              * signing certificate.
3126e71b7053SJung-uk Kim              */
3127e71b7053SJung-uk Kim             if (mdnid == lu->hash && pknid == lu->sig)
3128e71b7053SJung-uk Kim                 return 1;
3129e71b7053SJung-uk Kim         }
3130e71b7053SJung-uk Kim         return 0;
3131e71b7053SJung-uk Kim     }
3132b077aed3SPierre Pronchery 
3133b077aed3SPierre Pronchery     /*
3134b077aed3SPierre Pronchery      * Without signat_algorithms_cert, any certificate for which we have
3135b077aed3SPierre Pronchery      * a viable public key is permitted.
3136b077aed3SPierre Pronchery      */
3137da327cd2SJung-uk Kim     return 1;
3138da327cd2SJung-uk Kim }
3139da327cd2SJung-uk Kim 
3140da327cd2SJung-uk Kim /*
3141da327cd2SJung-uk Kim  * Returns true if |s| has a usable certificate configured for use
3142da327cd2SJung-uk Kim  * with signature scheme |sig|.
3143da327cd2SJung-uk Kim  * "Usable" includes a check for presence as well as applying
3144da327cd2SJung-uk Kim  * the signature_algorithm_cert restrictions sent by the peer (if any).
3145da327cd2SJung-uk Kim  * Returns false if no usable certificate is found.
3146da327cd2SJung-uk Kim  */
has_usable_cert(SSL * s,const SIGALG_LOOKUP * sig,int idx)3147da327cd2SJung-uk Kim static int has_usable_cert(SSL *s, const SIGALG_LOOKUP *sig, int idx)
3148da327cd2SJung-uk Kim {
3149da327cd2SJung-uk Kim     /* TLS 1.2 callers can override sig->sig_idx, but not TLS 1.3 callers. */
3150da327cd2SJung-uk Kim     if (idx == -1)
3151da327cd2SJung-uk Kim         idx = sig->sig_idx;
3152da327cd2SJung-uk Kim     if (!ssl_has_cert(s, idx))
3153da327cd2SJung-uk Kim         return 0;
3154da327cd2SJung-uk Kim 
3155da327cd2SJung-uk Kim     return check_cert_usable(s, sig, s->cert->pkeys[idx].x509,
3156da327cd2SJung-uk Kim                              s->cert->pkeys[idx].privatekey);
3157da327cd2SJung-uk Kim }
3158da327cd2SJung-uk Kim 
3159da327cd2SJung-uk Kim /*
3160da327cd2SJung-uk Kim  * Returns true if the supplied cert |x| and key |pkey| is usable with the
3161da327cd2SJung-uk Kim  * specified signature scheme |sig|, or false otherwise.
3162da327cd2SJung-uk Kim  */
is_cert_usable(SSL * s,const SIGALG_LOOKUP * sig,X509 * x,EVP_PKEY * pkey)3163da327cd2SJung-uk Kim static int is_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x,
3164da327cd2SJung-uk Kim                           EVP_PKEY *pkey)
3165da327cd2SJung-uk Kim {
3166da327cd2SJung-uk Kim     size_t idx;
3167da327cd2SJung-uk Kim 
3168da327cd2SJung-uk Kim     if (ssl_cert_lookup_by_pkey(pkey, &idx) == NULL)
3169da327cd2SJung-uk Kim         return 0;
3170da327cd2SJung-uk Kim 
3171da327cd2SJung-uk Kim     /* Check the key is consistent with the sig alg */
3172da327cd2SJung-uk Kim     if ((int)idx != sig->sig_idx)
3173da327cd2SJung-uk Kim         return 0;
3174da327cd2SJung-uk Kim 
3175da327cd2SJung-uk Kim     return check_cert_usable(s, sig, x, pkey);
3176da327cd2SJung-uk Kim }
3177da327cd2SJung-uk Kim 
3178da327cd2SJung-uk Kim /*
3179da327cd2SJung-uk Kim  * Find a signature scheme that works with the supplied certificate |x| and key
3180da327cd2SJung-uk Kim  * |pkey|. |x| and |pkey| may be NULL in which case we additionally look at our
3181da327cd2SJung-uk Kim  * available certs/keys to find one that works.
3182da327cd2SJung-uk Kim  */
find_sig_alg(SSL * s,X509 * x,EVP_PKEY * pkey)3183da327cd2SJung-uk Kim static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey)
3184da327cd2SJung-uk Kim {
3185da327cd2SJung-uk Kim     const SIGALG_LOOKUP *lu = NULL;
3186da327cd2SJung-uk Kim     size_t i;
3187da327cd2SJung-uk Kim     int curve = -1;
3188da327cd2SJung-uk Kim     EVP_PKEY *tmppkey;
3189da327cd2SJung-uk Kim 
3190da327cd2SJung-uk Kim     /* Look for a shared sigalgs matching possible certificates */
3191da327cd2SJung-uk Kim     for (i = 0; i < s->shared_sigalgslen; i++) {
3192da327cd2SJung-uk Kim         lu = s->shared_sigalgs[i];
3193da327cd2SJung-uk Kim 
3194da327cd2SJung-uk Kim         /* Skip SHA1, SHA224, DSA and RSA if not PSS */
3195da327cd2SJung-uk Kim         if (lu->hash == NID_sha1
3196da327cd2SJung-uk Kim             || lu->hash == NID_sha224
3197da327cd2SJung-uk Kim             || lu->sig == EVP_PKEY_DSA
3198da327cd2SJung-uk Kim             || lu->sig == EVP_PKEY_RSA)
3199da327cd2SJung-uk Kim             continue;
3200da327cd2SJung-uk Kim         /* Check that we have a cert, and signature_algorithms_cert */
3201b077aed3SPierre Pronchery         if (!tls1_lookup_md(s->ctx, lu, NULL))
3202da327cd2SJung-uk Kim             continue;
3203da327cd2SJung-uk Kim         if ((pkey == NULL && !has_usable_cert(s, lu, -1))
3204da327cd2SJung-uk Kim                 || (pkey != NULL && !is_cert_usable(s, lu, x, pkey)))
3205da327cd2SJung-uk Kim             continue;
3206da327cd2SJung-uk Kim 
3207da327cd2SJung-uk Kim         tmppkey = (pkey != NULL) ? pkey
3208da327cd2SJung-uk Kim                                  : s->cert->pkeys[lu->sig_idx].privatekey;
3209da327cd2SJung-uk Kim 
3210da327cd2SJung-uk Kim         if (lu->sig == EVP_PKEY_EC) {
3211b077aed3SPierre Pronchery             if (curve == -1)
3212b077aed3SPierre Pronchery                 curve = ssl_get_EC_curve_nid(tmppkey);
3213da327cd2SJung-uk Kim             if (lu->curve != NID_undef && curve != lu->curve)
3214da327cd2SJung-uk Kim                 continue;
3215da327cd2SJung-uk Kim         } else if (lu->sig == EVP_PKEY_RSA_PSS) {
3216da327cd2SJung-uk Kim             /* validate that key is large enough for the signature algorithm */
3217b077aed3SPierre Pronchery             if (!rsa_pss_check_min_key_size(s->ctx, tmppkey, lu))
3218da327cd2SJung-uk Kim                 continue;
3219da327cd2SJung-uk Kim         }
3220da327cd2SJung-uk Kim         break;
3221da327cd2SJung-uk Kim     }
3222da327cd2SJung-uk Kim 
3223da327cd2SJung-uk Kim     if (i == s->shared_sigalgslen)
3224da327cd2SJung-uk Kim         return NULL;
3225da327cd2SJung-uk Kim 
3226da327cd2SJung-uk Kim     return lu;
3227e71b7053SJung-uk Kim }
3228e71b7053SJung-uk Kim 
3229e71b7053SJung-uk Kim /*
3230e71b7053SJung-uk Kim  * Choose an appropriate signature algorithm based on available certificates
3231e71b7053SJung-uk Kim  * Sets chosen certificate and signature algorithm.
3232e71b7053SJung-uk Kim  *
3233e71b7053SJung-uk Kim  * For servers if we fail to find a required certificate it is a fatal error,
3234e71b7053SJung-uk Kim  * an appropriate error code is set and a TLS alert is sent.
3235e71b7053SJung-uk Kim  *
3236e71b7053SJung-uk Kim  * For clients fatalerrs is set to 0. If a certificate is not suitable it is not
3237e71b7053SJung-uk Kim  * a fatal error: we will either try another certificate or not present one
3238e71b7053SJung-uk Kim  * to the server. In this case no error is set.
3239e71b7053SJung-uk Kim  */
tls_choose_sigalg(SSL * s,int fatalerrs)3240e71b7053SJung-uk Kim int tls_choose_sigalg(SSL *s, int fatalerrs)
3241e71b7053SJung-uk Kim {
3242e71b7053SJung-uk Kim     const SIGALG_LOOKUP *lu = NULL;
3243e71b7053SJung-uk Kim     int sig_idx = -1;
3244e71b7053SJung-uk Kim 
3245b077aed3SPierre Pronchery     s->s3.tmp.cert = NULL;
3246b077aed3SPierre Pronchery     s->s3.tmp.sigalg = NULL;
3247e71b7053SJung-uk Kim 
3248e71b7053SJung-uk Kim     if (SSL_IS_TLS13(s)) {
3249da327cd2SJung-uk Kim         lu = find_sig_alg(s, NULL, NULL);
3250da327cd2SJung-uk Kim         if (lu == NULL) {
3251e71b7053SJung-uk Kim             if (!fatalerrs)
3252e71b7053SJung-uk Kim                 return 1;
3253b077aed3SPierre Pronchery             SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
3254e71b7053SJung-uk Kim                      SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM);
3255e71b7053SJung-uk Kim             return 0;
3256e71b7053SJung-uk Kim         }
3257e71b7053SJung-uk Kim     } else {
3258e71b7053SJung-uk Kim         /* If ciphersuite doesn't require a cert nothing to do */
3259b077aed3SPierre Pronchery         if (!(s->s3.tmp.new_cipher->algorithm_auth & SSL_aCERT))
3260e71b7053SJung-uk Kim             return 1;
3261e71b7053SJung-uk Kim         if (!s->server && !ssl_has_cert(s, s->cert->key - s->cert->pkeys))
3262e71b7053SJung-uk Kim                 return 1;
3263e71b7053SJung-uk Kim 
3264e71b7053SJung-uk Kim         if (SSL_USE_SIGALGS(s)) {
3265e71b7053SJung-uk Kim             size_t i;
3266b077aed3SPierre Pronchery             if (s->s3.tmp.peer_sigalgs != NULL) {
3267b077aed3SPierre Pronchery                 int curve = -1;
3268e71b7053SJung-uk Kim 
3269e71b7053SJung-uk Kim                 /* For Suite B need to match signature algorithm to curve */
3270b077aed3SPierre Pronchery                 if (tls1_suiteb(s))
3271b077aed3SPierre Pronchery                     curve = ssl_get_EC_curve_nid(s->cert->pkeys[SSL_PKEY_ECC]
3272b077aed3SPierre Pronchery                                                  .privatekey);
3273e71b7053SJung-uk Kim 
3274e71b7053SJung-uk Kim                 /*
3275e71b7053SJung-uk Kim                  * Find highest preference signature algorithm matching
3276e71b7053SJung-uk Kim                  * cert type
3277e71b7053SJung-uk Kim                  */
3278da327cd2SJung-uk Kim                 for (i = 0; i < s->shared_sigalgslen; i++) {
3279da327cd2SJung-uk Kim                     lu = s->shared_sigalgs[i];
3280e71b7053SJung-uk Kim 
3281e71b7053SJung-uk Kim                     if (s->server) {
3282e71b7053SJung-uk Kim                         if ((sig_idx = tls12_get_cert_sigalg_idx(s, lu)) == -1)
3283e71b7053SJung-uk Kim                             continue;
3284e71b7053SJung-uk Kim                     } else {
3285e71b7053SJung-uk Kim                         int cc_idx = s->cert->key - s->cert->pkeys;
3286e71b7053SJung-uk Kim 
3287e71b7053SJung-uk Kim                         sig_idx = lu->sig_idx;
3288e71b7053SJung-uk Kim                         if (cc_idx != sig_idx)
3289e71b7053SJung-uk Kim                             continue;
3290e71b7053SJung-uk Kim                     }
3291e71b7053SJung-uk Kim                     /* Check that we have a cert, and sig_algs_cert */
3292e71b7053SJung-uk Kim                     if (!has_usable_cert(s, lu, sig_idx))
3293e71b7053SJung-uk Kim                         continue;
3294e71b7053SJung-uk Kim                     if (lu->sig == EVP_PKEY_RSA_PSS) {
3295e71b7053SJung-uk Kim                         /* validate that key is large enough for the signature algorithm */
3296e71b7053SJung-uk Kim                         EVP_PKEY *pkey = s->cert->pkeys[sig_idx].privatekey;
3297e71b7053SJung-uk Kim 
3298b077aed3SPierre Pronchery                         if (!rsa_pss_check_min_key_size(s->ctx, pkey, lu))
3299e71b7053SJung-uk Kim                             continue;
3300e71b7053SJung-uk Kim                     }
3301e71b7053SJung-uk Kim                     if (curve == -1 || lu->curve == curve)
3302e71b7053SJung-uk Kim                         break;
3303e71b7053SJung-uk Kim                 }
330417f01e99SJung-uk Kim #ifndef OPENSSL_NO_GOST
330517f01e99SJung-uk Kim                 /*
330617f01e99SJung-uk Kim                  * Some Windows-based implementations do not send GOST algorithms indication
330717f01e99SJung-uk Kim                  * in supported_algorithms extension, so when we have GOST-based ciphersuite,
330817f01e99SJung-uk Kim                  * we have to assume GOST support.
330917f01e99SJung-uk Kim                  */
3310b077aed3SPierre Pronchery                 if (i == s->shared_sigalgslen && s->s3.tmp.new_cipher->algorithm_auth & (SSL_aGOST01 | SSL_aGOST12)) {
331117f01e99SJung-uk Kim                   if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) {
331217f01e99SJung-uk Kim                     if (!fatalerrs)
331317f01e99SJung-uk Kim                       return 1;
331417f01e99SJung-uk Kim                     SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
331517f01e99SJung-uk Kim                              SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM);
331617f01e99SJung-uk Kim                     return 0;
331717f01e99SJung-uk Kim                   } else {
331817f01e99SJung-uk Kim                     i = 0;
331917f01e99SJung-uk Kim                     sig_idx = lu->sig_idx;
332017f01e99SJung-uk Kim                   }
332117f01e99SJung-uk Kim                 }
332217f01e99SJung-uk Kim #endif
3323da327cd2SJung-uk Kim                 if (i == s->shared_sigalgslen) {
3324e71b7053SJung-uk Kim                     if (!fatalerrs)
3325e71b7053SJung-uk Kim                         return 1;
3326e71b7053SJung-uk Kim                     SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
3327e71b7053SJung-uk Kim                              SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM);
3328e71b7053SJung-uk Kim                     return 0;
3329e71b7053SJung-uk Kim                 }
3330e71b7053SJung-uk Kim             } else {
3331e71b7053SJung-uk Kim                 /*
3332e71b7053SJung-uk Kim                  * If we have no sigalg use defaults
3333e71b7053SJung-uk Kim                  */
3334e71b7053SJung-uk Kim                 const uint16_t *sent_sigs;
3335e71b7053SJung-uk Kim                 size_t sent_sigslen;
3336e71b7053SJung-uk Kim 
3337e71b7053SJung-uk Kim                 if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) {
3338e71b7053SJung-uk Kim                     if (!fatalerrs)
3339e71b7053SJung-uk Kim                         return 1;
3340b077aed3SPierre Pronchery                     SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
3341b077aed3SPierre Pronchery                              SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM);
3342e71b7053SJung-uk Kim                     return 0;
3343e71b7053SJung-uk Kim                 }
3344e71b7053SJung-uk Kim 
3345e71b7053SJung-uk Kim                 /* Check signature matches a type we sent */
3346e71b7053SJung-uk Kim                 sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs);
3347e71b7053SJung-uk Kim                 for (i = 0; i < sent_sigslen; i++, sent_sigs++) {
3348e71b7053SJung-uk Kim                     if (lu->sigalg == *sent_sigs
3349e71b7053SJung-uk Kim                             && has_usable_cert(s, lu, lu->sig_idx))
3350e71b7053SJung-uk Kim                         break;
3351e71b7053SJung-uk Kim                 }
3352e71b7053SJung-uk Kim                 if (i == sent_sigslen) {
3353e71b7053SJung-uk Kim                     if (!fatalerrs)
3354e71b7053SJung-uk Kim                         return 1;
3355b077aed3SPierre Pronchery                     SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
3356e71b7053SJung-uk Kim                              SSL_R_WRONG_SIGNATURE_TYPE);
3357e71b7053SJung-uk Kim                     return 0;
3358e71b7053SJung-uk Kim                 }
3359e71b7053SJung-uk Kim             }
3360e71b7053SJung-uk Kim         } else {
3361e71b7053SJung-uk Kim             if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) {
3362e71b7053SJung-uk Kim                 if (!fatalerrs)
3363e71b7053SJung-uk Kim                     return 1;
3364b077aed3SPierre Pronchery                 SSLfatal(s, SSL_AD_INTERNAL_ERROR,
3365b077aed3SPierre Pronchery                          SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM);
3366e71b7053SJung-uk Kim                 return 0;
3367e71b7053SJung-uk Kim             }
3368e71b7053SJung-uk Kim         }
3369e71b7053SJung-uk Kim     }
3370e71b7053SJung-uk Kim     if (sig_idx == -1)
3371e71b7053SJung-uk Kim         sig_idx = lu->sig_idx;
3372b077aed3SPierre Pronchery     s->s3.tmp.cert = &s->cert->pkeys[sig_idx];
3373b077aed3SPierre Pronchery     s->cert->key = s->s3.tmp.cert;
3374b077aed3SPierre Pronchery     s->s3.tmp.sigalg = lu;
3375e71b7053SJung-uk Kim     return 1;
3376e71b7053SJung-uk Kim }
3377e71b7053SJung-uk Kim 
SSL_CTX_set_tlsext_max_fragment_length(SSL_CTX * ctx,uint8_t mode)3378e71b7053SJung-uk Kim int SSL_CTX_set_tlsext_max_fragment_length(SSL_CTX *ctx, uint8_t mode)
3379e71b7053SJung-uk Kim {
3380e71b7053SJung-uk Kim     if (mode != TLSEXT_max_fragment_length_DISABLED
3381e71b7053SJung-uk Kim             && !IS_MAX_FRAGMENT_LENGTH_EXT_VALID(mode)) {
3382b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH);
3383e71b7053SJung-uk Kim         return 0;
3384e71b7053SJung-uk Kim     }
3385e71b7053SJung-uk Kim 
3386e71b7053SJung-uk Kim     ctx->ext.max_fragment_len_mode = mode;
3387e71b7053SJung-uk Kim     return 1;
3388e71b7053SJung-uk Kim }
3389e71b7053SJung-uk Kim 
SSL_set_tlsext_max_fragment_length(SSL * ssl,uint8_t mode)3390e71b7053SJung-uk Kim int SSL_set_tlsext_max_fragment_length(SSL *ssl, uint8_t mode)
3391e71b7053SJung-uk Kim {
3392e71b7053SJung-uk Kim     if (mode != TLSEXT_max_fragment_length_DISABLED
3393e71b7053SJung-uk Kim             && !IS_MAX_FRAGMENT_LENGTH_EXT_VALID(mode)) {
3394b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH);
3395e71b7053SJung-uk Kim         return 0;
3396e71b7053SJung-uk Kim     }
3397e71b7053SJung-uk Kim 
3398e71b7053SJung-uk Kim     ssl->ext.max_fragment_len_mode = mode;
3399e71b7053SJung-uk Kim     return 1;
3400e71b7053SJung-uk Kim }
3401e71b7053SJung-uk Kim 
SSL_SESSION_get_max_fragment_length(const SSL_SESSION * session)3402e71b7053SJung-uk Kim uint8_t SSL_SESSION_get_max_fragment_length(const SSL_SESSION *session)
3403e71b7053SJung-uk Kim {
3404*a7148ab3SEnji Cooper     if (session->ext.max_fragment_len_mode == TLSEXT_max_fragment_length_UNSPECIFIED)
3405*a7148ab3SEnji Cooper         return TLSEXT_max_fragment_length_DISABLED;
3406e71b7053SJung-uk Kim     return session->ext.max_fragment_len_mode;
3407e71b7053SJung-uk Kim }
3408b077aed3SPierre Pronchery 
3409b077aed3SPierre Pronchery /*
3410b077aed3SPierre Pronchery  * Helper functions for HMAC access with legacy support included.
3411b077aed3SPierre Pronchery  */
ssl_hmac_new(const SSL_CTX * ctx)3412b077aed3SPierre Pronchery SSL_HMAC *ssl_hmac_new(const SSL_CTX *ctx)
3413b077aed3SPierre Pronchery {
3414b077aed3SPierre Pronchery     SSL_HMAC *ret = OPENSSL_zalloc(sizeof(*ret));
3415b077aed3SPierre Pronchery     EVP_MAC *mac = NULL;
3416b077aed3SPierre Pronchery 
3417b077aed3SPierre Pronchery     if (ret == NULL)
3418b077aed3SPierre Pronchery         return NULL;
3419b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DEPRECATED_3_0
3420b077aed3SPierre Pronchery     if (ctx->ext.ticket_key_evp_cb == NULL
3421b077aed3SPierre Pronchery             && ctx->ext.ticket_key_cb != NULL) {
3422b077aed3SPierre Pronchery         if (!ssl_hmac_old_new(ret))
3423b077aed3SPierre Pronchery             goto err;
3424b077aed3SPierre Pronchery         return ret;
3425b077aed3SPierre Pronchery     }
3426b077aed3SPierre Pronchery #endif
3427b077aed3SPierre Pronchery     mac = EVP_MAC_fetch(ctx->libctx, "HMAC", ctx->propq);
3428b077aed3SPierre Pronchery     if (mac == NULL || (ret->ctx = EVP_MAC_CTX_new(mac)) == NULL)
3429b077aed3SPierre Pronchery         goto err;
3430b077aed3SPierre Pronchery     EVP_MAC_free(mac);
3431b077aed3SPierre Pronchery     return ret;
3432b077aed3SPierre Pronchery  err:
3433b077aed3SPierre Pronchery     EVP_MAC_CTX_free(ret->ctx);
3434b077aed3SPierre Pronchery     EVP_MAC_free(mac);
3435b077aed3SPierre Pronchery     OPENSSL_free(ret);
3436b077aed3SPierre Pronchery     return NULL;
3437b077aed3SPierre Pronchery }
3438b077aed3SPierre Pronchery 
ssl_hmac_free(SSL_HMAC * ctx)3439b077aed3SPierre Pronchery void ssl_hmac_free(SSL_HMAC *ctx)
3440b077aed3SPierre Pronchery {
3441b077aed3SPierre Pronchery     if (ctx != NULL) {
3442b077aed3SPierre Pronchery         EVP_MAC_CTX_free(ctx->ctx);
3443b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DEPRECATED_3_0
3444b077aed3SPierre Pronchery         ssl_hmac_old_free(ctx);
3445b077aed3SPierre Pronchery #endif
3446b077aed3SPierre Pronchery         OPENSSL_free(ctx);
3447b077aed3SPierre Pronchery     }
3448b077aed3SPierre Pronchery }
3449b077aed3SPierre Pronchery 
ssl_hmac_get0_EVP_MAC_CTX(SSL_HMAC * ctx)3450b077aed3SPierre Pronchery EVP_MAC_CTX *ssl_hmac_get0_EVP_MAC_CTX(SSL_HMAC *ctx)
3451b077aed3SPierre Pronchery {
3452b077aed3SPierre Pronchery     return ctx->ctx;
3453b077aed3SPierre Pronchery }
3454b077aed3SPierre Pronchery 
ssl_hmac_init(SSL_HMAC * ctx,void * key,size_t len,char * md)3455b077aed3SPierre Pronchery int ssl_hmac_init(SSL_HMAC *ctx, void *key, size_t len, char *md)
3456b077aed3SPierre Pronchery {
3457b077aed3SPierre Pronchery     OSSL_PARAM params[2], *p = params;
3458b077aed3SPierre Pronchery 
3459b077aed3SPierre Pronchery     if (ctx->ctx != NULL) {
3460b077aed3SPierre Pronchery         *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, md, 0);
3461b077aed3SPierre Pronchery         *p = OSSL_PARAM_construct_end();
3462b077aed3SPierre Pronchery         if (EVP_MAC_init(ctx->ctx, key, len, params))
3463b077aed3SPierre Pronchery             return 1;
3464b077aed3SPierre Pronchery     }
3465b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DEPRECATED_3_0
3466b077aed3SPierre Pronchery     if (ctx->old_ctx != NULL)
3467b077aed3SPierre Pronchery         return ssl_hmac_old_init(ctx, key, len, md);
3468b077aed3SPierre Pronchery #endif
3469b077aed3SPierre Pronchery     return 0;
3470b077aed3SPierre Pronchery }
3471b077aed3SPierre Pronchery 
ssl_hmac_update(SSL_HMAC * ctx,const unsigned char * data,size_t len)3472b077aed3SPierre Pronchery int ssl_hmac_update(SSL_HMAC *ctx, const unsigned char *data, size_t len)
3473b077aed3SPierre Pronchery {
3474b077aed3SPierre Pronchery     if (ctx->ctx != NULL)
3475b077aed3SPierre Pronchery         return EVP_MAC_update(ctx->ctx, data, len);
3476b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DEPRECATED_3_0
3477b077aed3SPierre Pronchery     if (ctx->old_ctx != NULL)
3478b077aed3SPierre Pronchery         return ssl_hmac_old_update(ctx, data, len);
3479b077aed3SPierre Pronchery #endif
3480b077aed3SPierre Pronchery     return 0;
3481b077aed3SPierre Pronchery }
3482b077aed3SPierre Pronchery 
ssl_hmac_final(SSL_HMAC * ctx,unsigned char * md,size_t * len,size_t max_size)3483b077aed3SPierre Pronchery int ssl_hmac_final(SSL_HMAC *ctx, unsigned char *md, size_t *len,
3484b077aed3SPierre Pronchery                    size_t max_size)
3485b077aed3SPierre Pronchery {
3486b077aed3SPierre Pronchery     if (ctx->ctx != NULL)
3487b077aed3SPierre Pronchery         return EVP_MAC_final(ctx->ctx, md, len, max_size);
3488b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DEPRECATED_3_0
3489b077aed3SPierre Pronchery     if (ctx->old_ctx != NULL)
3490b077aed3SPierre Pronchery         return ssl_hmac_old_final(ctx, md, len);
3491b077aed3SPierre Pronchery #endif
3492b077aed3SPierre Pronchery     return 0;
3493b077aed3SPierre Pronchery }
3494b077aed3SPierre Pronchery 
ssl_hmac_size(const SSL_HMAC * ctx)3495b077aed3SPierre Pronchery size_t ssl_hmac_size(const SSL_HMAC *ctx)
3496b077aed3SPierre Pronchery {
3497b077aed3SPierre Pronchery     if (ctx->ctx != NULL)
3498b077aed3SPierre Pronchery         return EVP_MAC_CTX_get_mac_size(ctx->ctx);
3499b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DEPRECATED_3_0
3500b077aed3SPierre Pronchery     if (ctx->old_ctx != NULL)
3501b077aed3SPierre Pronchery         return ssl_hmac_old_size(ctx);
3502b077aed3SPierre Pronchery #endif
3503b077aed3SPierre Pronchery     return 0;
3504b077aed3SPierre Pronchery }
3505b077aed3SPierre Pronchery 
ssl_get_EC_curve_nid(const EVP_PKEY * pkey)3506b077aed3SPierre Pronchery int ssl_get_EC_curve_nid(const EVP_PKEY *pkey)
3507b077aed3SPierre Pronchery {
3508b077aed3SPierre Pronchery     char gname[OSSL_MAX_NAME_SIZE];
3509b077aed3SPierre Pronchery 
3510b077aed3SPierre Pronchery     if (EVP_PKEY_get_group_name(pkey, gname, sizeof(gname), NULL) > 0)
3511b077aed3SPierre Pronchery         return OBJ_txt2nid(gname);
3512b077aed3SPierre Pronchery 
3513b077aed3SPierre Pronchery     return NID_undef;
3514b077aed3SPierre Pronchery }
3515b077aed3SPierre Pronchery 
tls13_set_encoded_pub_key(EVP_PKEY * pkey,const unsigned char * enckey,size_t enckeylen)3516b077aed3SPierre Pronchery __owur int tls13_set_encoded_pub_key(EVP_PKEY *pkey,
3517b077aed3SPierre Pronchery                                      const unsigned char *enckey,
3518b077aed3SPierre Pronchery                                      size_t enckeylen)
3519b077aed3SPierre Pronchery {
3520b077aed3SPierre Pronchery     if (EVP_PKEY_is_a(pkey, "DH")) {
3521b077aed3SPierre Pronchery         int bits = EVP_PKEY_get_bits(pkey);
3522b077aed3SPierre Pronchery 
3523b077aed3SPierre Pronchery         if (bits <= 0 || enckeylen != (size_t)bits / 8)
3524b077aed3SPierre Pronchery             /* the encoded key must be padded to the length of the p */
3525b077aed3SPierre Pronchery             return 0;
3526b077aed3SPierre Pronchery     } else if (EVP_PKEY_is_a(pkey, "EC")) {
3527b077aed3SPierre Pronchery         if (enckeylen < 3 /* point format and at least 1 byte for x and y */
3528b077aed3SPierre Pronchery             || enckey[0] != 0x04)
3529b077aed3SPierre Pronchery             return 0;
3530b077aed3SPierre Pronchery     }
3531b077aed3SPierre Pronchery 
3532b077aed3SPierre Pronchery     return EVP_PKEY_set1_encoded_public_key(pkey, enckey, enckeylen);
3533b077aed3SPierre Pronchery }
3534