xref: /freebsd/crypto/openssl/ssl/t1_lib.c (revision aa7957345732816fb0ba8308798d2f79f45597f9)
1e71b7053SJung-uk Kim /*
2b077aed3SPierre Pronchery  * Copyright 1995-2023 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"
26*aa795734SPierre 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 
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 
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 
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 
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;
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 
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 
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 
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 
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 
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 
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  */
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 
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 */
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" */
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  */
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;
604*aa795734SPierre 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];
641*aa795734SPierre 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;
646*aa795734SPierre Pronchery         inf = tls1_group_id_lookup(ctx, id);
647*aa795734SPierre Pronchery         if (!ossl_assert(inf != NULL))
648*aa795734SPierre Pronchery             return 0;
649*aa795734SPierre Pronchery         if (SSL_IS_DTLS(s)) {
650*aa795734SPierre Pronchery             if (inf->maxdtls == -1)
651*aa795734SPierre Pronchery                 continue;
652*aa795734SPierre Pronchery             if ((inf->mindtls != 0 && DTLS_VERSION_LT(s->version, inf->mindtls))
653*aa795734SPierre Pronchery                     || (inf->maxdtls != 0
654*aa795734SPierre Pronchery                         && DTLS_VERSION_GT(s->version, inf->maxdtls)))
655*aa795734SPierre Pronchery                 continue;
656*aa795734SPierre Pronchery         } else {
657*aa795734SPierre Pronchery             if (inf->maxtls == -1)
658*aa795734SPierre Pronchery                 continue;
659*aa795734SPierre Pronchery             if ((inf->mintls != 0 && s->version < inf->mintls)
660*aa795734SPierre Pronchery                     || (inf->maxtls != 0 && s->version > inf->maxtls))
661*aa795734SPierre Pronchery                 continue;
662*aa795734SPierre Pronchery         }
663*aa795734SPierre 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 
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 
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 =
737b077aed3SPierre Pronchery             OPENSSL_realloc(garg->gid_arr, garg->gidmax + GROUPLIST_INCREMENT);
738b077aed3SPierre Pronchery         if (tmp == NULL)
7397bded2dbSJung-uk Kim             return 0;
740b077aed3SPierre Pronchery         garg->gidmax += GROUPLIST_INCREMENT;
741b077aed3SPierre Pronchery         garg->gid_arr = tmp;
742b077aed3SPierre Pronchery     }
7437bded2dbSJung-uk Kim     if (len > (int)(sizeof(etmp) - 1))
7447bded2dbSJung-uk Kim         return 0;
7457bded2dbSJung-uk Kim     memcpy(etmp, elem, len);
7467bded2dbSJung-uk Kim     etmp[len] = 0;
747b077aed3SPierre Pronchery 
748b077aed3SPierre Pronchery     gid = tls1_group_name2id(garg->ctx, etmp);
749b077aed3SPierre Pronchery     if (gid == 0) {
750b077aed3SPierre Pronchery         ERR_raise_data(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT,
751b077aed3SPierre Pronchery                        "group '%s' cannot be set", etmp);
7527bded2dbSJung-uk Kim         return 0;
753b077aed3SPierre Pronchery     }
754b077aed3SPierre Pronchery     for (i = 0; i < garg->gidcnt; i++)
755b077aed3SPierre Pronchery         if (garg->gid_arr[i] == gid)
7567bded2dbSJung-uk Kim             return 0;
757b077aed3SPierre Pronchery     garg->gid_arr[garg->gidcnt++] = gid;
7587bded2dbSJung-uk Kim     return 1;
7597bded2dbSJung-uk Kim }
7607bded2dbSJung-uk Kim 
761b077aed3SPierre Pronchery /* Set groups based on a colon separated list */
762b077aed3SPierre Pronchery int tls1_set_groups_list(SSL_CTX *ctx, uint16_t **pext, size_t *pextlen,
763b077aed3SPierre Pronchery                          const char *str)
7647bded2dbSJung-uk Kim {
765b077aed3SPierre Pronchery     gid_cb_st gcb;
766b077aed3SPierre Pronchery     uint16_t *tmparr;
767b077aed3SPierre Pronchery     int ret = 0;
768e71b7053SJung-uk Kim 
769b077aed3SPierre Pronchery     gcb.gidcnt = 0;
770b077aed3SPierre Pronchery     gcb.gidmax = GROUPLIST_INCREMENT;
771b077aed3SPierre Pronchery     gcb.gid_arr = OPENSSL_malloc(gcb.gidmax * sizeof(*gcb.gid_arr));
772b077aed3SPierre Pronchery     if (gcb.gid_arr == NULL)
7737bded2dbSJung-uk Kim         return 0;
774b077aed3SPierre Pronchery     gcb.ctx = ctx;
775b077aed3SPierre Pronchery     if (!CONF_parse_list(str, ':', 1, gid_cb, &gcb))
776b077aed3SPierre Pronchery         goto end;
777b077aed3SPierre Pronchery     if (pext == NULL) {
778b077aed3SPierre Pronchery         ret = 1;
779b077aed3SPierre Pronchery         goto end;
7807bded2dbSJung-uk Kim     }
7817bded2dbSJung-uk Kim 
782e71b7053SJung-uk Kim     /*
783b077aed3SPierre Pronchery      * gid_cb ensurse there are no duplicates so we can just go ahead and set
784b077aed3SPierre Pronchery      * the result
785e71b7053SJung-uk Kim      */
786b077aed3SPierre Pronchery     tmparr = OPENSSL_memdup(gcb.gid_arr, gcb.gidcnt * sizeof(*tmparr));
787b077aed3SPierre Pronchery     if (tmparr == NULL)
788b077aed3SPierre Pronchery         goto end;
789b077aed3SPierre Pronchery     OPENSSL_free(*pext);
790b077aed3SPierre Pronchery     *pext = tmparr;
791b077aed3SPierre Pronchery     *pextlen = gcb.gidcnt;
792b077aed3SPierre Pronchery     ret = 1;
793b077aed3SPierre Pronchery  end:
794b077aed3SPierre Pronchery     OPENSSL_free(gcb.gid_arr);
795b077aed3SPierre Pronchery     return ret;
7967bded2dbSJung-uk Kim }
7977bded2dbSJung-uk Kim 
798e71b7053SJung-uk Kim /* Check a group id matches preferences */
799e71b7053SJung-uk Kim int tls1_check_group_id(SSL *s, uint16_t group_id, int check_own_groups)
800e71b7053SJung-uk Kim     {
801e71b7053SJung-uk Kim     const uint16_t *groups;
802e71b7053SJung-uk Kim     size_t groups_len;
803e71b7053SJung-uk Kim 
804e71b7053SJung-uk Kim     if (group_id == 0)
805e71b7053SJung-uk Kim         return 0;
806e71b7053SJung-uk Kim 
807e71b7053SJung-uk Kim     /* Check for Suite B compliance */
808b077aed3SPierre Pronchery     if (tls1_suiteb(s) && s->s3.tmp.new_cipher != NULL) {
809b077aed3SPierre Pronchery         unsigned long cid = s->s3.tmp.new_cipher->id;
810e71b7053SJung-uk Kim 
811e71b7053SJung-uk Kim         if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) {
812e71b7053SJung-uk Kim             if (group_id != TLSEXT_curve_P_256)
813e71b7053SJung-uk Kim                 return 0;
814e71b7053SJung-uk Kim         } else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) {
815e71b7053SJung-uk Kim             if (group_id != TLSEXT_curve_P_384)
816e71b7053SJung-uk Kim                 return 0;
817e71b7053SJung-uk Kim         } else {
818e71b7053SJung-uk Kim             /* Should never happen */
819e71b7053SJung-uk Kim             return 0;
820e71b7053SJung-uk Kim         }
821e71b7053SJung-uk Kim     }
822e71b7053SJung-uk Kim 
823e71b7053SJung-uk Kim     if (check_own_groups) {
824e71b7053SJung-uk Kim         /* Check group is one of our preferences */
825e71b7053SJung-uk Kim         tls1_get_supported_groups(s, &groups, &groups_len);
826e71b7053SJung-uk Kim         if (!tls1_in_list(group_id, groups, groups_len))
827e71b7053SJung-uk Kim             return 0;
828e71b7053SJung-uk Kim     }
829e71b7053SJung-uk Kim 
830b077aed3SPierre Pronchery     if (!tls_group_allowed(s, group_id, SSL_SECOP_CURVE_CHECK))
831e71b7053SJung-uk Kim         return 0;
832e71b7053SJung-uk Kim 
833e71b7053SJung-uk Kim     /* For clients, nothing more to check */
834e71b7053SJung-uk Kim     if (!s->server)
835e71b7053SJung-uk Kim         return 1;
836e71b7053SJung-uk Kim 
837e71b7053SJung-uk Kim     /* Check group is one of peers preferences */
838e71b7053SJung-uk Kim     tls1_get_peer_groups(s, &groups, &groups_len);
839e71b7053SJung-uk Kim 
840e71b7053SJung-uk Kim     /*
841e71b7053SJung-uk Kim      * RFC 4492 does not require the supported elliptic curves extension
842e71b7053SJung-uk Kim      * so if it is not sent we can just choose any curve.
843e71b7053SJung-uk Kim      * It is invalid to send an empty list in the supported groups
844e71b7053SJung-uk Kim      * extension, so groups_len == 0 always means no extension.
845e71b7053SJung-uk Kim      */
846e71b7053SJung-uk Kim     if (groups_len == 0)
847e71b7053SJung-uk Kim             return 1;
848e71b7053SJung-uk Kim     return tls1_in_list(group_id, groups, groups_len);
849e71b7053SJung-uk Kim }
850e71b7053SJung-uk Kim 
851e71b7053SJung-uk Kim void tls1_get_formatlist(SSL *s, const unsigned char **pformats,
8527bded2dbSJung-uk Kim                          size_t *num_formats)
8537bded2dbSJung-uk Kim {
8547bded2dbSJung-uk Kim     /*
8557bded2dbSJung-uk Kim      * If we have a custom point format list use it otherwise use default
8567bded2dbSJung-uk Kim      */
857e71b7053SJung-uk Kim     if (s->ext.ecpointformats) {
858e71b7053SJung-uk Kim         *pformats = s->ext.ecpointformats;
859e71b7053SJung-uk Kim         *num_formats = s->ext.ecpointformats_len;
8607bded2dbSJung-uk Kim     } else {
8617bded2dbSJung-uk Kim         *pformats = ecformats_default;
8627bded2dbSJung-uk Kim         /* For Suite B we don't support char2 fields */
8637bded2dbSJung-uk Kim         if (tls1_suiteb(s))
8647bded2dbSJung-uk Kim             *num_formats = sizeof(ecformats_default) - 1;
8657bded2dbSJung-uk Kim         else
8667bded2dbSJung-uk Kim             *num_formats = sizeof(ecformats_default);
8677bded2dbSJung-uk Kim     }
8687bded2dbSJung-uk Kim }
8697bded2dbSJung-uk Kim 
870b077aed3SPierre Pronchery /* Check a key is compatible with compression extension */
871b077aed3SPierre Pronchery static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey)
872b077aed3SPierre Pronchery {
873b077aed3SPierre Pronchery     unsigned char comp_id;
874b077aed3SPierre Pronchery     size_t i;
875b077aed3SPierre Pronchery     int point_conv;
876b077aed3SPierre Pronchery 
877b077aed3SPierre Pronchery     /* If not an EC key nothing to check */
878b077aed3SPierre Pronchery     if (!EVP_PKEY_is_a(pkey, "EC"))
879b077aed3SPierre Pronchery         return 1;
880b077aed3SPierre Pronchery 
881b077aed3SPierre Pronchery 
882b077aed3SPierre Pronchery     /* Get required compression id */
883b077aed3SPierre Pronchery     point_conv = EVP_PKEY_get_ec_point_conv_form(pkey);
884b077aed3SPierre Pronchery     if (point_conv == 0)
885b077aed3SPierre Pronchery         return 0;
886b077aed3SPierre Pronchery     if (point_conv == POINT_CONVERSION_UNCOMPRESSED) {
887b077aed3SPierre Pronchery             comp_id = TLSEXT_ECPOINTFORMAT_uncompressed;
888b077aed3SPierre Pronchery     } else if (SSL_IS_TLS13(s)) {
889b077aed3SPierre Pronchery         /*
890b077aed3SPierre Pronchery          * ec_point_formats extension is not used in TLSv1.3 so we ignore
891b077aed3SPierre Pronchery          * this check.
892b077aed3SPierre Pronchery          */
893b077aed3SPierre Pronchery         return 1;
894b077aed3SPierre Pronchery     } else {
895b077aed3SPierre Pronchery         int field_type = EVP_PKEY_get_field_type(pkey);
896b077aed3SPierre Pronchery 
897b077aed3SPierre Pronchery         if (field_type == NID_X9_62_prime_field)
898b077aed3SPierre Pronchery             comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
899b077aed3SPierre Pronchery         else if (field_type == NID_X9_62_characteristic_two_field)
900b077aed3SPierre Pronchery             comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
901b077aed3SPierre Pronchery         else
902b077aed3SPierre Pronchery             return 0;
903b077aed3SPierre Pronchery     }
904b077aed3SPierre Pronchery     /*
905b077aed3SPierre Pronchery      * If point formats extension present check it, otherwise everything is
906b077aed3SPierre Pronchery      * supported (see RFC4492).
907b077aed3SPierre Pronchery      */
908b077aed3SPierre Pronchery     if (s->ext.peer_ecpointformats == NULL)
909b077aed3SPierre Pronchery         return 1;
910b077aed3SPierre Pronchery 
911b077aed3SPierre Pronchery     for (i = 0; i < s->ext.peer_ecpointformats_len; i++) {
912b077aed3SPierre Pronchery         if (s->ext.peer_ecpointformats[i] == comp_id)
913b077aed3SPierre Pronchery             return 1;
914b077aed3SPierre Pronchery     }
915b077aed3SPierre Pronchery     return 0;
916b077aed3SPierre Pronchery }
917b077aed3SPierre Pronchery 
918b077aed3SPierre Pronchery /* Return group id of a key */
919b077aed3SPierre Pronchery static uint16_t tls1_get_group_id(EVP_PKEY *pkey)
920b077aed3SPierre Pronchery {
921b077aed3SPierre Pronchery     int curve_nid = ssl_get_EC_curve_nid(pkey);
922b077aed3SPierre Pronchery 
923b077aed3SPierre Pronchery     if (curve_nid == NID_undef)
924b077aed3SPierre Pronchery         return 0;
925b077aed3SPierre Pronchery     return tls1_nid2group_id(curve_nid);
926b077aed3SPierre Pronchery }
927b077aed3SPierre Pronchery 
9287bded2dbSJung-uk Kim /*
9297bded2dbSJung-uk Kim  * Check cert parameters compatible with extensions: currently just checks EC
9307bded2dbSJung-uk Kim  * certificates have compatible curves and compression.
9317bded2dbSJung-uk Kim  */
932e71b7053SJung-uk Kim static int tls1_check_cert_param(SSL *s, X509 *x, int check_ee_md)
9337bded2dbSJung-uk Kim {
934e71b7053SJung-uk Kim     uint16_t group_id;
9357bded2dbSJung-uk Kim     EVP_PKEY *pkey;
936e71b7053SJung-uk Kim     pkey = X509_get0_pubkey(x);
937e71b7053SJung-uk Kim     if (pkey == NULL)
9387bded2dbSJung-uk Kim         return 0;
9397bded2dbSJung-uk Kim     /* If not EC nothing to do */
940b077aed3SPierre Pronchery     if (!EVP_PKEY_is_a(pkey, "EC"))
9417bded2dbSJung-uk Kim         return 1;
942e71b7053SJung-uk Kim     /* Check compression */
943e71b7053SJung-uk Kim     if (!tls1_check_pkey_comp(s, pkey))
9447bded2dbSJung-uk Kim         return 0;
945e71b7053SJung-uk Kim     group_id = tls1_get_group_id(pkey);
9467bded2dbSJung-uk Kim     /*
947e71b7053SJung-uk Kim      * For a server we allow the certificate to not be in our list of supported
948e71b7053SJung-uk Kim      * groups.
9497bded2dbSJung-uk Kim      */
950e71b7053SJung-uk Kim     if (!tls1_check_group_id(s, group_id, !s->server))
9517bded2dbSJung-uk Kim         return 0;
9527bded2dbSJung-uk Kim     /*
9537bded2dbSJung-uk Kim      * Special case for suite B. We *MUST* sign using SHA256+P-256 or
954e71b7053SJung-uk Kim      * SHA384+P-384.
9557bded2dbSJung-uk Kim      */
956e71b7053SJung-uk Kim     if (check_ee_md && tls1_suiteb(s)) {
9577bded2dbSJung-uk Kim         int check_md;
9587bded2dbSJung-uk Kim         size_t i;
959e71b7053SJung-uk Kim 
9607bded2dbSJung-uk Kim         /* Check to see we have necessary signing algorithm */
961e71b7053SJung-uk Kim         if (group_id == TLSEXT_curve_P_256)
9627bded2dbSJung-uk Kim             check_md = NID_ecdsa_with_SHA256;
963e71b7053SJung-uk Kim         else if (group_id == TLSEXT_curve_P_384)
9647bded2dbSJung-uk Kim             check_md = NID_ecdsa_with_SHA384;
9657bded2dbSJung-uk Kim         else
9667bded2dbSJung-uk Kim             return 0;           /* Should never happen */
967da327cd2SJung-uk Kim         for (i = 0; i < s->shared_sigalgslen; i++) {
968da327cd2SJung-uk Kim             if (check_md == s->shared_sigalgs[i]->sigandhash)
969e71b7053SJung-uk Kim                 return 1;;
970e71b7053SJung-uk Kim         }
9717bded2dbSJung-uk Kim         return 0;
9727bded2dbSJung-uk Kim     }
973e71b7053SJung-uk Kim     return 1;
9747bded2dbSJung-uk Kim }
9757bded2dbSJung-uk Kim 
976e71b7053SJung-uk Kim /*
977e71b7053SJung-uk Kim  * tls1_check_ec_tmp_key - Check EC temporary key compatibility
978e71b7053SJung-uk Kim  * @s: SSL connection
979e71b7053SJung-uk Kim  * @cid: Cipher ID we're considering using
980e71b7053SJung-uk Kim  *
981e71b7053SJung-uk Kim  * Checks that the kECDHE cipher suite we're considering using
982e71b7053SJung-uk Kim  * is compatible with the client extensions.
983e71b7053SJung-uk Kim  *
984e71b7053SJung-uk Kim  * Returns 0 when the cipher can't be used or 1 when it can.
985e71b7053SJung-uk Kim  */
9867bded2dbSJung-uk Kim int tls1_check_ec_tmp_key(SSL *s, unsigned long cid)
9877bded2dbSJung-uk Kim {
988e71b7053SJung-uk Kim     /* If not Suite B just need a shared group */
989e71b7053SJung-uk Kim     if (!tls1_suiteb(s))
990e71b7053SJung-uk Kim         return tls1_shared_group(s, 0) != 0;
9917bded2dbSJung-uk Kim     /*
9927bded2dbSJung-uk Kim      * If Suite B, AES128 MUST use P-256 and AES256 MUST use P-384, no other
9937bded2dbSJung-uk Kim      * curves permitted.
9947bded2dbSJung-uk Kim      */
9957bded2dbSJung-uk Kim     if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
996e71b7053SJung-uk Kim         return tls1_check_group_id(s, TLSEXT_curve_P_256, 1);
997e71b7053SJung-uk Kim     if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
998e71b7053SJung-uk Kim         return tls1_check_group_id(s, TLSEXT_curve_P_384, 1);
9997bded2dbSJung-uk Kim 
10007bded2dbSJung-uk Kim     return 0;
10017bded2dbSJung-uk Kim }
10027bded2dbSJung-uk Kim 
1003e71b7053SJung-uk Kim /* Default sigalg schemes */
1004e71b7053SJung-uk Kim static const uint16_t tls12_sigalgs[] = {
1005e71b7053SJung-uk Kim     TLSEXT_SIGALG_ecdsa_secp256r1_sha256,
1006e71b7053SJung-uk Kim     TLSEXT_SIGALG_ecdsa_secp384r1_sha384,
1007e71b7053SJung-uk Kim     TLSEXT_SIGALG_ecdsa_secp521r1_sha512,
1008e71b7053SJung-uk Kim     TLSEXT_SIGALG_ed25519,
1009e71b7053SJung-uk Kim     TLSEXT_SIGALG_ed448,
1010e71b7053SJung-uk Kim 
1011e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pss_pss_sha256,
1012e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pss_pss_sha384,
1013e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pss_pss_sha512,
1014e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pss_rsae_sha256,
1015e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pss_rsae_sha384,
1016e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pss_rsae_sha512,
1017e71b7053SJung-uk Kim 
1018e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pkcs1_sha256,
1019e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pkcs1_sha384,
1020e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pkcs1_sha512,
1021e71b7053SJung-uk Kim 
1022e71b7053SJung-uk Kim     TLSEXT_SIGALG_ecdsa_sha224,
1023e71b7053SJung-uk Kim     TLSEXT_SIGALG_ecdsa_sha1,
1024b077aed3SPierre Pronchery 
1025e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pkcs1_sha224,
1026e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pkcs1_sha1,
1027b077aed3SPierre Pronchery 
1028e71b7053SJung-uk Kim     TLSEXT_SIGALG_dsa_sha224,
1029e71b7053SJung-uk Kim     TLSEXT_SIGALG_dsa_sha1,
1030e71b7053SJung-uk Kim 
1031e71b7053SJung-uk Kim     TLSEXT_SIGALG_dsa_sha256,
1032e71b7053SJung-uk Kim     TLSEXT_SIGALG_dsa_sha384,
1033e71b7053SJung-uk Kim     TLSEXT_SIGALG_dsa_sha512,
1034b077aed3SPierre Pronchery 
1035e71b7053SJung-uk Kim #ifndef OPENSSL_NO_GOST
1036b077aed3SPierre Pronchery     TLSEXT_SIGALG_gostr34102012_256_intrinsic,
1037b077aed3SPierre Pronchery     TLSEXT_SIGALG_gostr34102012_512_intrinsic,
1038e71b7053SJung-uk Kim     TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256,
1039e71b7053SJung-uk Kim     TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512,
1040e71b7053SJung-uk Kim     TLSEXT_SIGALG_gostr34102001_gostr3411,
1041e71b7053SJung-uk Kim #endif
1042e71b7053SJung-uk Kim };
1043e71b7053SJung-uk Kim 
1044b077aed3SPierre Pronchery 
1045e71b7053SJung-uk Kim static const uint16_t suiteb_sigalgs[] = {
1046e71b7053SJung-uk Kim     TLSEXT_SIGALG_ecdsa_secp256r1_sha256,
1047e71b7053SJung-uk Kim     TLSEXT_SIGALG_ecdsa_secp384r1_sha384
1048e71b7053SJung-uk Kim };
1049e71b7053SJung-uk Kim 
1050e71b7053SJung-uk Kim static const SIGALG_LOOKUP sigalg_lookup_tbl[] = {
1051e71b7053SJung-uk Kim     {"ecdsa_secp256r1_sha256", TLSEXT_SIGALG_ecdsa_secp256r1_sha256,
1052e71b7053SJung-uk Kim      NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
1053b077aed3SPierre Pronchery      NID_ecdsa_with_SHA256, NID_X9_62_prime256v1, 1},
1054e71b7053SJung-uk Kim     {"ecdsa_secp384r1_sha384", TLSEXT_SIGALG_ecdsa_secp384r1_sha384,
1055e71b7053SJung-uk Kim      NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
1056b077aed3SPierre Pronchery      NID_ecdsa_with_SHA384, NID_secp384r1, 1},
1057e71b7053SJung-uk Kim     {"ecdsa_secp521r1_sha512", TLSEXT_SIGALG_ecdsa_secp521r1_sha512,
1058e71b7053SJung-uk Kim      NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
1059b077aed3SPierre Pronchery      NID_ecdsa_with_SHA512, NID_secp521r1, 1},
1060e71b7053SJung-uk Kim     {"ed25519", TLSEXT_SIGALG_ed25519,
1061e71b7053SJung-uk Kim      NID_undef, -1, EVP_PKEY_ED25519, SSL_PKEY_ED25519,
1062b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1063e71b7053SJung-uk Kim     {"ed448", TLSEXT_SIGALG_ed448,
1064e71b7053SJung-uk Kim      NID_undef, -1, EVP_PKEY_ED448, SSL_PKEY_ED448,
1065b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1066e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_ecdsa_sha224,
1067e71b7053SJung-uk Kim      NID_sha224, SSL_MD_SHA224_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
1068b077aed3SPierre Pronchery      NID_ecdsa_with_SHA224, NID_undef, 1},
1069e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_ecdsa_sha1,
1070e71b7053SJung-uk Kim      NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
1071b077aed3SPierre Pronchery      NID_ecdsa_with_SHA1, NID_undef, 1},
1072e71b7053SJung-uk Kim     {"rsa_pss_rsae_sha256", TLSEXT_SIGALG_rsa_pss_rsae_sha256,
1073e71b7053SJung-uk Kim      NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA,
1074b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1075e71b7053SJung-uk Kim     {"rsa_pss_rsae_sha384", TLSEXT_SIGALG_rsa_pss_rsae_sha384,
1076e71b7053SJung-uk Kim      NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA,
1077b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1078e71b7053SJung-uk Kim     {"rsa_pss_rsae_sha512", TLSEXT_SIGALG_rsa_pss_rsae_sha512,
1079e71b7053SJung-uk Kim      NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA,
1080b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1081e71b7053SJung-uk Kim     {"rsa_pss_pss_sha256", TLSEXT_SIGALG_rsa_pss_pss_sha256,
1082e71b7053SJung-uk Kim      NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN,
1083b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1084e71b7053SJung-uk Kim     {"rsa_pss_pss_sha384", TLSEXT_SIGALG_rsa_pss_pss_sha384,
1085e71b7053SJung-uk Kim      NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN,
1086b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1087e71b7053SJung-uk Kim     {"rsa_pss_pss_sha512", TLSEXT_SIGALG_rsa_pss_pss_sha512,
1088e71b7053SJung-uk Kim      NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN,
1089b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1090e71b7053SJung-uk Kim     {"rsa_pkcs1_sha256", TLSEXT_SIGALG_rsa_pkcs1_sha256,
1091e71b7053SJung-uk Kim      NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
1092b077aed3SPierre Pronchery      NID_sha256WithRSAEncryption, NID_undef, 1},
1093e71b7053SJung-uk Kim     {"rsa_pkcs1_sha384", TLSEXT_SIGALG_rsa_pkcs1_sha384,
1094e71b7053SJung-uk Kim      NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
1095b077aed3SPierre Pronchery      NID_sha384WithRSAEncryption, NID_undef, 1},
1096e71b7053SJung-uk Kim     {"rsa_pkcs1_sha512", TLSEXT_SIGALG_rsa_pkcs1_sha512,
1097e71b7053SJung-uk Kim      NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
1098b077aed3SPierre Pronchery      NID_sha512WithRSAEncryption, NID_undef, 1},
1099e71b7053SJung-uk Kim     {"rsa_pkcs1_sha224", TLSEXT_SIGALG_rsa_pkcs1_sha224,
1100e71b7053SJung-uk Kim      NID_sha224, SSL_MD_SHA224_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
1101b077aed3SPierre Pronchery      NID_sha224WithRSAEncryption, NID_undef, 1},
1102e71b7053SJung-uk Kim     {"rsa_pkcs1_sha1", TLSEXT_SIGALG_rsa_pkcs1_sha1,
1103e71b7053SJung-uk Kim      NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
1104b077aed3SPierre Pronchery      NID_sha1WithRSAEncryption, NID_undef, 1},
1105e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_dsa_sha256,
1106e71b7053SJung-uk Kim      NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
1107b077aed3SPierre Pronchery      NID_dsa_with_SHA256, NID_undef, 1},
1108e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_dsa_sha384,
1109e71b7053SJung-uk Kim      NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
1110b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1111e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_dsa_sha512,
1112e71b7053SJung-uk Kim      NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
1113b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1114e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_dsa_sha224,
1115e71b7053SJung-uk Kim      NID_sha224, SSL_MD_SHA224_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
1116b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1117e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_dsa_sha1,
1118e71b7053SJung-uk Kim      NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
1119b077aed3SPierre Pronchery      NID_dsaWithSHA1, NID_undef, 1},
1120e71b7053SJung-uk Kim #ifndef OPENSSL_NO_GOST
1121b077aed3SPierre Pronchery     {NULL, TLSEXT_SIGALG_gostr34102012_256_intrinsic,
1122b077aed3SPierre Pronchery      NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX,
1123b077aed3SPierre Pronchery      NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256,
1124b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1125b077aed3SPierre Pronchery     {NULL, TLSEXT_SIGALG_gostr34102012_512_intrinsic,
1126b077aed3SPierre Pronchery      NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX,
1127b077aed3SPierre Pronchery      NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512,
1128b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1129e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256,
1130e71b7053SJung-uk Kim      NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX,
1131e71b7053SJung-uk Kim      NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256,
1132b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1133e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512,
1134e71b7053SJung-uk Kim      NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX,
1135e71b7053SJung-uk Kim      NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512,
1136b077aed3SPierre Pronchery      NID_undef, NID_undef, 1},
1137e71b7053SJung-uk Kim     {NULL, TLSEXT_SIGALG_gostr34102001_gostr3411,
1138e71b7053SJung-uk Kim      NID_id_GostR3411_94, SSL_MD_GOST94_IDX,
1139e71b7053SJung-uk Kim      NID_id_GostR3410_2001, SSL_PKEY_GOST01,
1140b077aed3SPierre Pronchery      NID_undef, NID_undef, 1}
1141e71b7053SJung-uk Kim #endif
1142e71b7053SJung-uk Kim };
1143e71b7053SJung-uk Kim /* Legacy sigalgs for TLS < 1.2 RSA TLS signatures */
1144e71b7053SJung-uk Kim static const SIGALG_LOOKUP legacy_rsa_sigalg = {
1145e71b7053SJung-uk Kim     "rsa_pkcs1_md5_sha1", 0,
1146e71b7053SJung-uk Kim      NID_md5_sha1, SSL_MD_MD5_SHA1_IDX,
1147e71b7053SJung-uk Kim      EVP_PKEY_RSA, SSL_PKEY_RSA,
1148b077aed3SPierre Pronchery      NID_undef, NID_undef, 1
1149e71b7053SJung-uk Kim };
11501f13597dSJung-uk Kim 
11516f9291ceSJung-uk Kim /*
1152e71b7053SJung-uk Kim  * Default signature algorithm values used if signature algorithms not present.
1153e71b7053SJung-uk Kim  * From RFC5246. Note: order must match certificate index order.
11541f13597dSJung-uk Kim  */
1155e71b7053SJung-uk Kim static const uint16_t tls_default_sigalg[] = {
1156e71b7053SJung-uk Kim     TLSEXT_SIGALG_rsa_pkcs1_sha1, /* SSL_PKEY_RSA */
1157e71b7053SJung-uk Kim     0, /* SSL_PKEY_RSA_PSS_SIGN */
1158e71b7053SJung-uk Kim     TLSEXT_SIGALG_dsa_sha1, /* SSL_PKEY_DSA_SIGN */
1159e71b7053SJung-uk Kim     TLSEXT_SIGALG_ecdsa_sha1, /* SSL_PKEY_ECC */
1160e71b7053SJung-uk Kim     TLSEXT_SIGALG_gostr34102001_gostr3411, /* SSL_PKEY_GOST01 */
1161b077aed3SPierre Pronchery     TLSEXT_SIGALG_gostr34102012_256_intrinsic, /* SSL_PKEY_GOST12_256 */
1162b077aed3SPierre Pronchery     TLSEXT_SIGALG_gostr34102012_512_intrinsic, /* SSL_PKEY_GOST12_512 */
1163e71b7053SJung-uk Kim     0, /* SSL_PKEY_ED25519 */
1164e71b7053SJung-uk Kim     0, /* SSL_PKEY_ED448 */
11651f13597dSJung-uk Kim };
11661f13597dSJung-uk Kim 
1167b077aed3SPierre Pronchery int ssl_setup_sig_algs(SSL_CTX *ctx)
1168e71b7053SJung-uk Kim {
1169e71b7053SJung-uk Kim     size_t i;
1170b077aed3SPierre Pronchery     const SIGALG_LOOKUP *lu;
1171b077aed3SPierre Pronchery     SIGALG_LOOKUP *cache
1172b077aed3SPierre Pronchery         = OPENSSL_malloc(sizeof(*lu) * OSSL_NELEM(sigalg_lookup_tbl));
1173b077aed3SPierre Pronchery     EVP_PKEY *tmpkey = EVP_PKEY_new();
1174b077aed3SPierre Pronchery     int ret = 0;
1175e71b7053SJung-uk Kim 
1176b077aed3SPierre Pronchery     if (cache == NULL || tmpkey == NULL)
1177b077aed3SPierre Pronchery         goto err;
1178b077aed3SPierre Pronchery 
1179b077aed3SPierre Pronchery     ERR_set_mark();
1180b077aed3SPierre Pronchery     for (i = 0, lu = sigalg_lookup_tbl;
1181b077aed3SPierre Pronchery          i < OSSL_NELEM(sigalg_lookup_tbl); lu++, i++) {
1182b077aed3SPierre Pronchery         EVP_PKEY_CTX *pctx;
1183b077aed3SPierre Pronchery 
1184b077aed3SPierre Pronchery         cache[i] = *lu;
1185b077aed3SPierre Pronchery 
1186b077aed3SPierre Pronchery         /*
1187b077aed3SPierre Pronchery          * Check hash is available.
1188b077aed3SPierre Pronchery          * This test is not perfect. A provider could have support
1189b077aed3SPierre Pronchery          * for a signature scheme, but not a particular hash. However the hash
1190b077aed3SPierre Pronchery          * could be available from some other loaded provider. In that case it
1191b077aed3SPierre Pronchery          * could be that the signature is available, and the hash is available
1192b077aed3SPierre Pronchery          * independently - but not as a combination. We ignore this for now.
1193b077aed3SPierre Pronchery          */
1194b077aed3SPierre Pronchery         if (lu->hash != NID_undef
1195b077aed3SPierre Pronchery                 && ctx->ssl_digest_methods[lu->hash_idx] == NULL) {
1196b077aed3SPierre Pronchery             cache[i].enabled = 0;
1197b077aed3SPierre Pronchery             continue;
1198b077aed3SPierre Pronchery         }
1199b077aed3SPierre Pronchery 
1200b077aed3SPierre Pronchery         if (!EVP_PKEY_set_type(tmpkey, lu->sig)) {
1201b077aed3SPierre Pronchery             cache[i].enabled = 0;
1202b077aed3SPierre Pronchery             continue;
1203b077aed3SPierre Pronchery         }
1204b077aed3SPierre Pronchery         pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, tmpkey, ctx->propq);
1205b077aed3SPierre Pronchery         /* If unable to create pctx we assume the sig algorithm is unavailable */
1206b077aed3SPierre Pronchery         if (pctx == NULL)
1207b077aed3SPierre Pronchery             cache[i].enabled = 0;
1208b077aed3SPierre Pronchery         EVP_PKEY_CTX_free(pctx);
1209b077aed3SPierre Pronchery     }
1210b077aed3SPierre Pronchery     ERR_pop_to_mark();
1211b077aed3SPierre Pronchery     ctx->sigalg_lookup_cache = cache;
1212b077aed3SPierre Pronchery     cache = NULL;
1213b077aed3SPierre Pronchery 
1214b077aed3SPierre Pronchery     ret = 1;
1215b077aed3SPierre Pronchery  err:
1216b077aed3SPierre Pronchery     OPENSSL_free(cache);
1217b077aed3SPierre Pronchery     EVP_PKEY_free(tmpkey);
1218b077aed3SPierre Pronchery     return ret;
1219b077aed3SPierre Pronchery }
1220b077aed3SPierre Pronchery 
1221b077aed3SPierre Pronchery /* Lookup TLS signature algorithm */
1222b077aed3SPierre Pronchery static const SIGALG_LOOKUP *tls1_lookup_sigalg(const SSL *s, uint16_t sigalg)
1223b077aed3SPierre Pronchery {
1224b077aed3SPierre Pronchery     size_t i;
1225b077aed3SPierre Pronchery     const SIGALG_LOOKUP *lu;
1226b077aed3SPierre Pronchery 
1227b077aed3SPierre Pronchery     for (i = 0, lu = s->ctx->sigalg_lookup_cache;
1228b077aed3SPierre Pronchery          /* cache should have the same number of elements as sigalg_lookup_tbl */
1229b077aed3SPierre Pronchery          i < OSSL_NELEM(sigalg_lookup_tbl);
1230b077aed3SPierre Pronchery          lu++, i++) {
1231b077aed3SPierre Pronchery         if (lu->sigalg == sigalg) {
1232b077aed3SPierre Pronchery             if (!lu->enabled)
1233b077aed3SPierre Pronchery                 return NULL;
1234b077aed3SPierre Pronchery             return lu;
1235b077aed3SPierre Pronchery         }
1236e71b7053SJung-uk Kim     }
1237e71b7053SJung-uk Kim     return NULL;
1238e71b7053SJung-uk Kim }
1239e71b7053SJung-uk Kim /* Lookup hash: return 0 if invalid or not enabled */
1240b077aed3SPierre Pronchery int tls1_lookup_md(SSL_CTX *ctx, const SIGALG_LOOKUP *lu, const EVP_MD **pmd)
1241e71b7053SJung-uk Kim {
1242e71b7053SJung-uk Kim     const EVP_MD *md;
1243e71b7053SJung-uk Kim     if (lu == NULL)
1244e71b7053SJung-uk Kim         return 0;
1245e71b7053SJung-uk Kim     /* lu->hash == NID_undef means no associated digest */
1246e71b7053SJung-uk Kim     if (lu->hash == NID_undef) {
1247e71b7053SJung-uk Kim         md = NULL;
1248e71b7053SJung-uk Kim     } else {
1249b077aed3SPierre Pronchery         md = ssl_md(ctx, lu->hash_idx);
1250e71b7053SJung-uk Kim         if (md == NULL)
1251e71b7053SJung-uk Kim             return 0;
1252e71b7053SJung-uk Kim     }
1253e71b7053SJung-uk Kim     if (pmd)
1254e71b7053SJung-uk Kim         *pmd = md;
1255e71b7053SJung-uk Kim     return 1;
1256e71b7053SJung-uk Kim }
1257e71b7053SJung-uk Kim 
1258e71b7053SJung-uk Kim /*
1259e71b7053SJung-uk Kim  * Check if key is large enough to generate RSA-PSS signature.
1260e71b7053SJung-uk Kim  *
1261e71b7053SJung-uk Kim  * The key must greater than or equal to 2 * hash length + 2.
1262e71b7053SJung-uk Kim  * SHA512 has a hash length of 64 bytes, which is incompatible
1263e71b7053SJung-uk Kim  * with a 128 byte (1024 bit) key.
1264e71b7053SJung-uk Kim  */
1265b077aed3SPierre Pronchery #define RSA_PSS_MINIMUM_KEY_SIZE(md) (2 * EVP_MD_get_size(md) + 2)
1266b077aed3SPierre Pronchery static int rsa_pss_check_min_key_size(SSL_CTX *ctx, const EVP_PKEY *pkey,
1267b077aed3SPierre Pronchery                                       const SIGALG_LOOKUP *lu)
1268e71b7053SJung-uk Kim {
1269e71b7053SJung-uk Kim     const EVP_MD *md;
1270e71b7053SJung-uk Kim 
1271b077aed3SPierre Pronchery     if (pkey == NULL)
1272e71b7053SJung-uk Kim         return 0;
1273b077aed3SPierre Pronchery     if (!tls1_lookup_md(ctx, lu, &md) || md == NULL)
1274e71b7053SJung-uk Kim         return 0;
1275b077aed3SPierre Pronchery     if (EVP_PKEY_get_size(pkey) < RSA_PSS_MINIMUM_KEY_SIZE(md))
1276e71b7053SJung-uk Kim         return 0;
1277e71b7053SJung-uk Kim     return 1;
1278e71b7053SJung-uk Kim }
1279e71b7053SJung-uk Kim 
1280e71b7053SJung-uk Kim /*
128117f01e99SJung-uk Kim  * Returns a signature algorithm when the peer did not send a list of supported
128217f01e99SJung-uk Kim  * signature algorithms. The signature algorithm is fixed for the certificate
128317f01e99SJung-uk Kim  * type. |idx| is a certificate type index (SSL_PKEY_*). When |idx| is -1 the
128417f01e99SJung-uk Kim  * certificate type from |s| will be used.
128517f01e99SJung-uk Kim  * Returns the signature algorithm to use, or NULL on error.
1286e71b7053SJung-uk Kim  */
1287e71b7053SJung-uk Kim static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx)
1288e71b7053SJung-uk Kim {
1289e71b7053SJung-uk Kim     if (idx == -1) {
1290e71b7053SJung-uk Kim         if (s->server) {
1291e71b7053SJung-uk Kim             size_t i;
1292e71b7053SJung-uk Kim 
1293e71b7053SJung-uk Kim             /* Work out index corresponding to ciphersuite */
1294e71b7053SJung-uk Kim             for (i = 0; i < SSL_PKEY_NUM; i++) {
1295e71b7053SJung-uk Kim                 const SSL_CERT_LOOKUP *clu = ssl_cert_lookup_by_idx(i);
1296e71b7053SJung-uk Kim 
1297b077aed3SPierre Pronchery                 if (clu == NULL)
1298b077aed3SPierre Pronchery                     continue;
1299b077aed3SPierre Pronchery                 if (clu->amask & s->s3.tmp.new_cipher->algorithm_auth) {
1300e71b7053SJung-uk Kim                     idx = i;
1301e71b7053SJung-uk Kim                     break;
1302e71b7053SJung-uk Kim                 }
1303e71b7053SJung-uk Kim             }
1304e71b7053SJung-uk Kim 
1305e71b7053SJung-uk Kim             /*
1306e71b7053SJung-uk Kim              * Some GOST ciphersuites allow more than one signature algorithms
1307e71b7053SJung-uk Kim              * */
1308b077aed3SPierre Pronchery             if (idx == SSL_PKEY_GOST01 && s->s3.tmp.new_cipher->algorithm_auth != SSL_aGOST01) {
1309e71b7053SJung-uk Kim                 int real_idx;
1310e71b7053SJung-uk Kim 
1311e71b7053SJung-uk Kim                 for (real_idx = SSL_PKEY_GOST12_512; real_idx >= SSL_PKEY_GOST01;
1312e71b7053SJung-uk Kim                      real_idx--) {
1313e71b7053SJung-uk Kim                     if (s->cert->pkeys[real_idx].privatekey != NULL) {
1314e71b7053SJung-uk Kim                         idx = real_idx;
1315e71b7053SJung-uk Kim                         break;
1316e71b7053SJung-uk Kim                     }
1317e71b7053SJung-uk Kim                 }
1318e71b7053SJung-uk Kim             }
1319b077aed3SPierre Pronchery             /*
1320b077aed3SPierre Pronchery              * As both SSL_PKEY_GOST12_512 and SSL_PKEY_GOST12_256 indices can be used
1321b077aed3SPierre Pronchery              * with new (aGOST12-only) ciphersuites, we should find out which one is available really.
1322b077aed3SPierre Pronchery              */
1323b077aed3SPierre Pronchery             else if (idx == SSL_PKEY_GOST12_256) {
1324b077aed3SPierre Pronchery                 int real_idx;
1325b077aed3SPierre Pronchery 
1326b077aed3SPierre Pronchery                 for (real_idx = SSL_PKEY_GOST12_512; real_idx >= SSL_PKEY_GOST12_256;
1327b077aed3SPierre Pronchery                      real_idx--) {
1328b077aed3SPierre Pronchery                      if (s->cert->pkeys[real_idx].privatekey != NULL) {
1329b077aed3SPierre Pronchery                          idx = real_idx;
1330b077aed3SPierre Pronchery                          break;
1331b077aed3SPierre Pronchery                      }
1332b077aed3SPierre Pronchery                 }
1333b077aed3SPierre Pronchery             }
1334e71b7053SJung-uk Kim         } else {
1335e71b7053SJung-uk Kim             idx = s->cert->key - s->cert->pkeys;
1336e71b7053SJung-uk Kim         }
1337e71b7053SJung-uk Kim     }
1338e71b7053SJung-uk Kim     if (idx < 0 || idx >= (int)OSSL_NELEM(tls_default_sigalg))
1339e71b7053SJung-uk Kim         return NULL;
1340e71b7053SJung-uk Kim     if (SSL_USE_SIGALGS(s) || idx != SSL_PKEY_RSA) {
1341b077aed3SPierre Pronchery         const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, tls_default_sigalg[idx]);
1342e71b7053SJung-uk Kim 
1343b077aed3SPierre Pronchery         if (lu == NULL)
1344b077aed3SPierre Pronchery             return NULL;
1345b077aed3SPierre Pronchery         if (!tls1_lookup_md(s->ctx, lu, NULL))
1346e71b7053SJung-uk Kim             return NULL;
134717f01e99SJung-uk Kim         if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, lu))
134817f01e99SJung-uk Kim             return NULL;
1349e71b7053SJung-uk Kim         return lu;
1350e71b7053SJung-uk Kim     }
135117f01e99SJung-uk Kim     if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, &legacy_rsa_sigalg))
135217f01e99SJung-uk Kim         return NULL;
1353e71b7053SJung-uk Kim     return &legacy_rsa_sigalg;
1354e71b7053SJung-uk Kim }
1355e71b7053SJung-uk Kim /* Set peer sigalg based key type */
1356e71b7053SJung-uk Kim int tls1_set_peer_legacy_sigalg(SSL *s, const EVP_PKEY *pkey)
1357e71b7053SJung-uk Kim {
1358e71b7053SJung-uk Kim     size_t idx;
1359e71b7053SJung-uk Kim     const SIGALG_LOOKUP *lu;
1360e71b7053SJung-uk Kim 
1361e71b7053SJung-uk Kim     if (ssl_cert_lookup_by_pkey(pkey, &idx) == NULL)
1362e71b7053SJung-uk Kim         return 0;
1363e71b7053SJung-uk Kim     lu = tls1_get_legacy_sigalg(s, idx);
1364e71b7053SJung-uk Kim     if (lu == NULL)
1365e71b7053SJung-uk Kim         return 0;
1366b077aed3SPierre Pronchery     s->s3.tmp.peer_sigalg = lu;
1367e71b7053SJung-uk Kim     return 1;
1368e71b7053SJung-uk Kim }
1369e71b7053SJung-uk Kim 
1370e71b7053SJung-uk Kim size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs)
13711f13597dSJung-uk Kim {
13727bded2dbSJung-uk Kim     /*
13737bded2dbSJung-uk Kim      * If Suite B mode use Suite B sigalgs only, ignore any other
13747bded2dbSJung-uk Kim      * preferences.
13757bded2dbSJung-uk Kim      */
13767bded2dbSJung-uk Kim     switch (tls1_suiteb(s)) {
13777bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_128_LOS:
13787bded2dbSJung-uk Kim         *psigs = suiteb_sigalgs;
1379e71b7053SJung-uk Kim         return OSSL_NELEM(suiteb_sigalgs);
13807bded2dbSJung-uk Kim 
13817bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:
13827bded2dbSJung-uk Kim         *psigs = suiteb_sigalgs;
1383e71b7053SJung-uk Kim         return 1;
13847bded2dbSJung-uk Kim 
13857bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_192_LOS:
1386e71b7053SJung-uk Kim         *psigs = suiteb_sigalgs + 1;
1387e71b7053SJung-uk Kim         return 1;
13887bded2dbSJung-uk Kim     }
1389e71b7053SJung-uk Kim     /*
1390e71b7053SJung-uk Kim      *  We use client_sigalgs (if not NULL) if we're a server
1391e71b7053SJung-uk Kim      *  and sending a certificate request or if we're a client and
1392e71b7053SJung-uk Kim      *  determining which shared algorithm to use.
1393e71b7053SJung-uk Kim      */
1394e71b7053SJung-uk Kim     if ((s->server == sent) && s->cert->client_sigalgs != NULL) {
13957bded2dbSJung-uk Kim         *psigs = s->cert->client_sigalgs;
13967bded2dbSJung-uk Kim         return s->cert->client_sigalgslen;
13977bded2dbSJung-uk Kim     } else if (s->cert->conf_sigalgs) {
13987bded2dbSJung-uk Kim         *psigs = s->cert->conf_sigalgs;
13997bded2dbSJung-uk Kim         return s->cert->conf_sigalgslen;
14007bded2dbSJung-uk Kim     } else {
14017bded2dbSJung-uk Kim         *psigs = tls12_sigalgs;
1402e71b7053SJung-uk Kim         return OSSL_NELEM(tls12_sigalgs);
14037bded2dbSJung-uk Kim     }
14047bded2dbSJung-uk Kim }
14057bded2dbSJung-uk Kim 
1406c9cf7b5cSJung-uk Kim /*
1407c9cf7b5cSJung-uk Kim  * Called by servers only. Checks that we have a sig alg that supports the
1408c9cf7b5cSJung-uk Kim  * specified EC curve.
1409c9cf7b5cSJung-uk Kim  */
1410c9cf7b5cSJung-uk Kim int tls_check_sigalg_curve(const SSL *s, int curve)
1411c9cf7b5cSJung-uk Kim {
1412c9cf7b5cSJung-uk Kim    const uint16_t *sigs;
1413c9cf7b5cSJung-uk Kim    size_t siglen, i;
1414c9cf7b5cSJung-uk Kim 
1415c9cf7b5cSJung-uk Kim     if (s->cert->conf_sigalgs) {
1416c9cf7b5cSJung-uk Kim         sigs = s->cert->conf_sigalgs;
1417c9cf7b5cSJung-uk Kim         siglen = s->cert->conf_sigalgslen;
1418c9cf7b5cSJung-uk Kim     } else {
1419c9cf7b5cSJung-uk Kim         sigs = tls12_sigalgs;
1420c9cf7b5cSJung-uk Kim         siglen = OSSL_NELEM(tls12_sigalgs);
1421c9cf7b5cSJung-uk Kim     }
1422c9cf7b5cSJung-uk Kim 
1423c9cf7b5cSJung-uk Kim     for (i = 0; i < siglen; i++) {
1424b077aed3SPierre Pronchery         const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, sigs[i]);
1425c9cf7b5cSJung-uk Kim 
1426c9cf7b5cSJung-uk Kim         if (lu == NULL)
1427c9cf7b5cSJung-uk Kim             continue;
1428c9cf7b5cSJung-uk Kim         if (lu->sig == EVP_PKEY_EC
1429c9cf7b5cSJung-uk Kim                 && lu->curve != NID_undef
1430c9cf7b5cSJung-uk Kim                 && curve == lu->curve)
1431c9cf7b5cSJung-uk Kim             return 1;
1432c9cf7b5cSJung-uk Kim     }
1433c9cf7b5cSJung-uk Kim 
1434c9cf7b5cSJung-uk Kim     return 0;
1435c9cf7b5cSJung-uk Kim }
1436c9cf7b5cSJung-uk Kim 
14377bded2dbSJung-uk Kim /*
143817f01e99SJung-uk Kim  * Return the number of security bits for the signature algorithm, or 0 on
143917f01e99SJung-uk Kim  * error.
144017f01e99SJung-uk Kim  */
1441b077aed3SPierre Pronchery static int sigalg_security_bits(SSL_CTX *ctx, const SIGALG_LOOKUP *lu)
144217f01e99SJung-uk Kim {
144317f01e99SJung-uk Kim     const EVP_MD *md = NULL;
144417f01e99SJung-uk Kim     int secbits = 0;
144517f01e99SJung-uk Kim 
1446b077aed3SPierre Pronchery     if (!tls1_lookup_md(ctx, lu, &md))
144717f01e99SJung-uk Kim         return 0;
144817f01e99SJung-uk Kim     if (md != NULL)
144917f01e99SJung-uk Kim     {
1450b077aed3SPierre Pronchery         int md_type = EVP_MD_get_type(md);
1451b077aed3SPierre Pronchery 
145217f01e99SJung-uk Kim         /* Security bits: half digest bits */
1453b077aed3SPierre Pronchery         secbits = EVP_MD_get_size(md) * 4;
1454b077aed3SPierre Pronchery         /*
1455b077aed3SPierre Pronchery          * SHA1 and MD5 are known to be broken. Reduce security bits so that
1456b077aed3SPierre Pronchery          * they're no longer accepted at security level 1. The real values don't
1457b077aed3SPierre Pronchery          * really matter as long as they're lower than 80, which is our
1458b077aed3SPierre Pronchery          * security level 1.
1459b077aed3SPierre Pronchery          * https://eprint.iacr.org/2020/014 puts a chosen-prefix attack for
1460b077aed3SPierre Pronchery          * SHA1 at 2^63.4 and MD5+SHA1 at 2^67.2
1461b077aed3SPierre Pronchery          * https://documents.epfl.ch/users/l/le/lenstra/public/papers/lat.pdf
1462b077aed3SPierre Pronchery          * puts a chosen-prefix attack for MD5 at 2^39.
1463b077aed3SPierre Pronchery          */
1464b077aed3SPierre Pronchery         if (md_type == NID_sha1)
1465b077aed3SPierre Pronchery             secbits = 64;
1466b077aed3SPierre Pronchery         else if (md_type == NID_md5_sha1)
1467b077aed3SPierre Pronchery             secbits = 67;
1468b077aed3SPierre Pronchery         else if (md_type == NID_md5)
1469b077aed3SPierre Pronchery             secbits = 39;
147017f01e99SJung-uk Kim     } else {
147117f01e99SJung-uk Kim         /* Values from https://tools.ietf.org/html/rfc8032#section-8.5 */
147217f01e99SJung-uk Kim         if (lu->sigalg == TLSEXT_SIGALG_ed25519)
147317f01e99SJung-uk Kim             secbits = 128;
147417f01e99SJung-uk Kim         else if (lu->sigalg == TLSEXT_SIGALG_ed448)
147517f01e99SJung-uk Kim             secbits = 224;
147617f01e99SJung-uk Kim     }
147717f01e99SJung-uk Kim     return secbits;
147817f01e99SJung-uk Kim }
147917f01e99SJung-uk Kim 
148017f01e99SJung-uk Kim /*
14817bded2dbSJung-uk Kim  * Check signature algorithm is consistent with sent supported signature
1482e71b7053SJung-uk Kim  * algorithms and if so set relevant digest and signature scheme in
1483e71b7053SJung-uk Kim  * s.
14847bded2dbSJung-uk Kim  */
1485e71b7053SJung-uk Kim int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey)
14867bded2dbSJung-uk Kim {
1487e71b7053SJung-uk Kim     const uint16_t *sent_sigs;
1488e71b7053SJung-uk Kim     const EVP_MD *md = NULL;
1489e71b7053SJung-uk Kim     char sigalgstr[2];
1490e71b7053SJung-uk Kim     size_t sent_sigslen, i, cidx;
1491b077aed3SPierre Pronchery     int pkeyid = -1;
1492e71b7053SJung-uk Kim     const SIGALG_LOOKUP *lu;
149317f01e99SJung-uk Kim     int secbits = 0;
1494e71b7053SJung-uk Kim 
1495b077aed3SPierre Pronchery     pkeyid = EVP_PKEY_get_id(pkey);
14967bded2dbSJung-uk Kim     /* Should never happen */
1497e71b7053SJung-uk Kim     if (pkeyid == -1)
14987bded2dbSJung-uk Kim         return -1;
1499e71b7053SJung-uk Kim     if (SSL_IS_TLS13(s)) {
1500e71b7053SJung-uk Kim         /* Disallow DSA for TLS 1.3 */
1501e71b7053SJung-uk Kim         if (pkeyid == EVP_PKEY_DSA) {
1502b077aed3SPierre Pronchery             SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_SIGNATURE_TYPE);
15037bded2dbSJung-uk Kim             return 0;
15047bded2dbSJung-uk Kim         }
1505e71b7053SJung-uk Kim         /* Only allow PSS for TLS 1.3 */
1506e71b7053SJung-uk Kim         if (pkeyid == EVP_PKEY_RSA)
1507e71b7053SJung-uk Kim             pkeyid = EVP_PKEY_RSA_PSS;
1508e71b7053SJung-uk Kim     }
1509b077aed3SPierre Pronchery     lu = tls1_lookup_sigalg(s, sig);
1510e71b7053SJung-uk Kim     /*
1511e71b7053SJung-uk Kim      * Check sigalgs is known. Disallow SHA1/SHA224 with TLS 1.3. Check key type
1512e71b7053SJung-uk Kim      * is consistent with signature: RSA keys can be used for RSA-PSS
1513e71b7053SJung-uk Kim      */
1514e71b7053SJung-uk Kim     if (lu == NULL
1515e71b7053SJung-uk Kim         || (SSL_IS_TLS13(s) && (lu->hash == NID_sha1 || lu->hash == NID_sha224))
1516e71b7053SJung-uk Kim         || (pkeyid != lu->sig
1517e71b7053SJung-uk Kim         && (lu->sig != EVP_PKEY_RSA_PSS || pkeyid != EVP_PKEY_RSA))) {
1518b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_SIGNATURE_TYPE);
1519e71b7053SJung-uk Kim         return 0;
1520e71b7053SJung-uk Kim     }
1521e71b7053SJung-uk Kim     /* Check the sigalg is consistent with the key OID */
1522b077aed3SPierre Pronchery     if (!ssl_cert_lookup_by_nid(EVP_PKEY_get_id(pkey), &cidx)
1523e71b7053SJung-uk Kim             || lu->sig_idx != (int)cidx) {
1524b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_SIGNATURE_TYPE);
1525e71b7053SJung-uk Kim         return 0;
1526e71b7053SJung-uk Kim     }
1527e71b7053SJung-uk Kim 
1528e71b7053SJung-uk Kim     if (pkeyid == EVP_PKEY_EC) {
1529e71b7053SJung-uk Kim 
1530e71b7053SJung-uk Kim         /* Check point compression is permitted */
1531e71b7053SJung-uk Kim         if (!tls1_check_pkey_comp(s, pkey)) {
1532e71b7053SJung-uk Kim             SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
1533e71b7053SJung-uk Kim                      SSL_R_ILLEGAL_POINT_COMPRESSION);
15347bded2dbSJung-uk Kim             return 0;
15357bded2dbSJung-uk Kim         }
1536e71b7053SJung-uk Kim 
1537e71b7053SJung-uk Kim         /* For TLS 1.3 or Suite B check curve matches signature algorithm */
1538e71b7053SJung-uk Kim         if (SSL_IS_TLS13(s) || tls1_suiteb(s)) {
1539b077aed3SPierre Pronchery             int curve = ssl_get_EC_curve_nid(pkey);
1540e71b7053SJung-uk Kim 
1541e71b7053SJung-uk Kim             if (lu->curve != NID_undef && curve != lu->curve) {
1542b077aed3SPierre Pronchery                 SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CURVE);
1543e71b7053SJung-uk Kim                 return 0;
1544e71b7053SJung-uk Kim             }
1545e71b7053SJung-uk Kim         }
1546e71b7053SJung-uk Kim         if (!SSL_IS_TLS13(s)) {
1547e71b7053SJung-uk Kim             /* Check curve matches extensions */
1548e71b7053SJung-uk Kim             if (!tls1_check_group_id(s, tls1_get_group_id(pkey), 1)) {
1549b077aed3SPierre Pronchery                 SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CURVE);
1550e71b7053SJung-uk Kim                 return 0;
1551e71b7053SJung-uk Kim             }
15527bded2dbSJung-uk Kim             if (tls1_suiteb(s)) {
1553e71b7053SJung-uk Kim                 /* Check sigalg matches a permissible Suite B value */
1554e71b7053SJung-uk Kim                 if (sig != TLSEXT_SIGALG_ecdsa_secp256r1_sha256
1555e71b7053SJung-uk Kim                     && sig != TLSEXT_SIGALG_ecdsa_secp384r1_sha384) {
1556e71b7053SJung-uk Kim                     SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
1557e71b7053SJung-uk Kim                              SSL_R_WRONG_SIGNATURE_TYPE);
15587bded2dbSJung-uk Kim                     return 0;
15597bded2dbSJung-uk Kim                 }
1560e71b7053SJung-uk Kim             }
1561e71b7053SJung-uk Kim         }
1562e71b7053SJung-uk Kim     } else if (tls1_suiteb(s)) {
1563b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE);
15647bded2dbSJung-uk Kim         return 0;
15657bded2dbSJung-uk Kim     }
15667bded2dbSJung-uk Kim 
15677bded2dbSJung-uk Kim     /* Check signature matches a type we sent */
1568ed7112f0SJung-uk Kim     sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs);
1569e71b7053SJung-uk Kim     for (i = 0; i < sent_sigslen; i++, sent_sigs++) {
1570e71b7053SJung-uk Kim         if (sig == *sent_sigs)
15717bded2dbSJung-uk Kim             break;
15727bded2dbSJung-uk Kim     }
15737bded2dbSJung-uk Kim     /* Allow fallback to SHA1 if not strict mode */
1574e71b7053SJung-uk Kim     if (i == sent_sigslen && (lu->hash != NID_sha1
15757bded2dbSJung-uk Kim         || s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) {
1576b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE);
15777bded2dbSJung-uk Kim         return 0;
15787bded2dbSJung-uk Kim     }
1579b077aed3SPierre Pronchery     if (!tls1_lookup_md(s->ctx, lu, &md)) {
1580b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_UNKNOWN_DIGEST);
15817bded2dbSJung-uk Kim         return 0;
15827bded2dbSJung-uk Kim     }
15837bded2dbSJung-uk Kim     /*
1584e71b7053SJung-uk Kim      * Make sure security callback allows algorithm. For historical
1585e71b7053SJung-uk Kim      * reasons we have to pass the sigalg as a two byte char array.
15867bded2dbSJung-uk Kim      */
1587e71b7053SJung-uk Kim     sigalgstr[0] = (sig >> 8) & 0xff;
1588e71b7053SJung-uk Kim     sigalgstr[1] = sig & 0xff;
1589b077aed3SPierre Pronchery     secbits = sigalg_security_bits(s->ctx, lu);
159017f01e99SJung-uk Kim     if (secbits == 0 ||
159117f01e99SJung-uk Kim         !ssl_security(s, SSL_SECOP_SIGALG_CHECK, secbits,
1592b077aed3SPierre Pronchery                       md != NULL ? EVP_MD_get_type(md) : NID_undef,
1593e71b7053SJung-uk Kim                       (void *)sigalgstr)) {
1594b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE);
1595e71b7053SJung-uk Kim         return 0;
1596e71b7053SJung-uk Kim     }
1597e71b7053SJung-uk Kim     /* Store the sigalg the peer uses */
1598b077aed3SPierre Pronchery     s->s3.tmp.peer_sigalg = lu;
1599e71b7053SJung-uk Kim     return 1;
1600e71b7053SJung-uk Kim }
1601e71b7053SJung-uk Kim 
1602e71b7053SJung-uk Kim int SSL_get_peer_signature_type_nid(const SSL *s, int *pnid)
1603e71b7053SJung-uk Kim {
1604b077aed3SPierre Pronchery     if (s->s3.tmp.peer_sigalg == NULL)
1605e71b7053SJung-uk Kim         return 0;
1606b077aed3SPierre Pronchery     *pnid = s->s3.tmp.peer_sigalg->sig;
16077bded2dbSJung-uk Kim     return 1;
16087bded2dbSJung-uk Kim }
16097bded2dbSJung-uk Kim 
1610c9cf7b5cSJung-uk Kim int SSL_get_signature_type_nid(const SSL *s, int *pnid)
1611c9cf7b5cSJung-uk Kim {
1612b077aed3SPierre Pronchery     if (s->s3.tmp.sigalg == NULL)
1613c9cf7b5cSJung-uk Kim         return 0;
1614b077aed3SPierre Pronchery     *pnid = s->s3.tmp.sigalg->sig;
1615c9cf7b5cSJung-uk Kim     return 1;
1616c9cf7b5cSJung-uk Kim }
1617c9cf7b5cSJung-uk Kim 
16187bded2dbSJung-uk Kim /*
1619e71b7053SJung-uk Kim  * Set a mask of disabled algorithms: an algorithm is disabled if it isn't
1620e71b7053SJung-uk Kim  * supported, doesn't appear in supported signature algorithms, isn't supported
1621e71b7053SJung-uk Kim  * by the enabled protocol versions or by the security level.
1622e71b7053SJung-uk Kim  *
1623e71b7053SJung-uk Kim  * This function should only be used for checking which ciphers are supported
1624e71b7053SJung-uk Kim  * by the client.
1625e71b7053SJung-uk Kim  *
1626e71b7053SJung-uk Kim  * Call ssl_cipher_disabled() to check that it's enabled or not.
16277bded2dbSJung-uk Kim  */
1628e71b7053SJung-uk Kim int ssl_set_client_disabled(SSL *s)
16297bded2dbSJung-uk Kim {
1630b077aed3SPierre Pronchery     s->s3.tmp.mask_a = 0;
1631b077aed3SPierre Pronchery     s->s3.tmp.mask_k = 0;
1632b077aed3SPierre Pronchery     ssl_set_sig_mask(&s->s3.tmp.mask_a, s, SSL_SECOP_SIGALG_MASK);
1633b077aed3SPierre Pronchery     if (ssl_get_min_max_version(s, &s->s3.tmp.min_ver,
1634b077aed3SPierre Pronchery                                 &s->s3.tmp.max_ver, NULL) != 0)
1635e71b7053SJung-uk Kim         return 0;
16367bded2dbSJung-uk Kim #ifndef OPENSSL_NO_PSK
16377bded2dbSJung-uk Kim     /* with PSK there must be client callback set */
16387bded2dbSJung-uk Kim     if (!s->psk_client_callback) {
1639b077aed3SPierre Pronchery         s->s3.tmp.mask_a |= SSL_aPSK;
1640b077aed3SPierre Pronchery         s->s3.tmp.mask_k |= SSL_PSK;
16417bded2dbSJung-uk Kim     }
16427bded2dbSJung-uk Kim #endif                          /* OPENSSL_NO_PSK */
16437bded2dbSJung-uk Kim #ifndef OPENSSL_NO_SRP
16447bded2dbSJung-uk Kim     if (!(s->srp_ctx.srp_Mask & SSL_kSRP)) {
1645b077aed3SPierre Pronchery         s->s3.tmp.mask_a |= SSL_aSRP;
1646b077aed3SPierre Pronchery         s->s3.tmp.mask_k |= SSL_kSRP;
16477bded2dbSJung-uk Kim     }
16487bded2dbSJung-uk Kim #endif
1649e71b7053SJung-uk Kim     return 1;
16501f13597dSJung-uk Kim }
16511f13597dSJung-uk Kim 
16526f9291ceSJung-uk Kim /*
1653e71b7053SJung-uk Kim  * ssl_cipher_disabled - check that a cipher is disabled or not
1654e71b7053SJung-uk Kim  * @s: SSL connection that you want to use the cipher on
1655e71b7053SJung-uk Kim  * @c: cipher to check
1656e71b7053SJung-uk Kim  * @op: Security check that you want to do
1657e71b7053SJung-uk Kim  * @ecdhe: If set to 1 then TLSv1 ECDHE ciphers are also allowed in SSLv3
16586cf8931aSJung-uk Kim  *
1659e71b7053SJung-uk Kim  * Returns 1 when it's disabled, 0 when enabled.
16606cf8931aSJung-uk Kim  */
166117f01e99SJung-uk Kim int ssl_cipher_disabled(const SSL *s, const SSL_CIPHER *c, int op, int ecdhe)
1662db522d3aSSimon L. B. Nielsen {
1663b077aed3SPierre Pronchery     if (c->algorithm_mkey & s->s3.tmp.mask_k
1664b077aed3SPierre Pronchery         || c->algorithm_auth & s->s3.tmp.mask_a)
1665e71b7053SJung-uk Kim         return 1;
1666b077aed3SPierre Pronchery     if (s->s3.tmp.max_ver == 0)
1667e71b7053SJung-uk Kim         return 1;
1668e71b7053SJung-uk Kim     if (!SSL_IS_DTLS(s)) {
1669e71b7053SJung-uk Kim         int min_tls = c->min_tls;
1670de78d5d8SJung-uk Kim 
16717bded2dbSJung-uk Kim         /*
1672e71b7053SJung-uk Kim          * For historical reasons we will allow ECHDE to be selected by a server
1673e71b7053SJung-uk Kim          * in SSLv3 if we are a client
16747bded2dbSJung-uk Kim          */
1675e71b7053SJung-uk Kim         if (min_tls == TLS1_VERSION && ecdhe
1676e71b7053SJung-uk Kim                 && (c->algorithm_mkey & (SSL_kECDHE | SSL_kECDHEPSK)) != 0)
1677e71b7053SJung-uk Kim             min_tls = SSL3_VERSION;
16787bded2dbSJung-uk Kim 
1679b077aed3SPierre Pronchery         if ((min_tls > s->s3.tmp.max_ver) || (c->max_tls < s->s3.tmp.min_ver))
1680b8721c16SJung-uk Kim             return 1;
1681b8721c16SJung-uk Kim     }
1682b077aed3SPierre Pronchery     if (SSL_IS_DTLS(s) && (DTLS_VERSION_GT(c->min_dtls, s->s3.tmp.max_ver)
1683b077aed3SPierre Pronchery                            || DTLS_VERSION_LT(c->max_dtls, s->s3.tmp.min_ver)))
16847bded2dbSJung-uk Kim         return 1;
16857bded2dbSJung-uk Kim 
1686e71b7053SJung-uk Kim     return !ssl_security(s, op, c->strength_bits, 0, (void *)c);
16877bded2dbSJung-uk Kim }
16887bded2dbSJung-uk Kim 
1689e71b7053SJung-uk Kim int tls_use_ticket(SSL *s)
16907bded2dbSJung-uk Kim {
1691e71b7053SJung-uk Kim     if ((s->options & SSL_OP_NO_TICKET))
16927bded2dbSJung-uk Kim         return 0;
1693e71b7053SJung-uk Kim     return ssl_security(s, SSL_SECOP_TICKET, 0, 0, NULL);
1694db522d3aSSimon L. B. Nielsen }
1695db522d3aSSimon L. B. Nielsen 
16967bded2dbSJung-uk Kim int tls1_set_server_sigalgs(SSL *s)
16977bded2dbSJung-uk Kim {
16987bded2dbSJung-uk Kim     size_t i;
1699e71b7053SJung-uk Kim 
1700e71b7053SJung-uk Kim     /* Clear any shared signature algorithms */
1701da327cd2SJung-uk Kim     OPENSSL_free(s->shared_sigalgs);
1702da327cd2SJung-uk Kim     s->shared_sigalgs = NULL;
1703da327cd2SJung-uk Kim     s->shared_sigalgslen = 0;
1704e71b7053SJung-uk Kim     /* Clear certificate validity flags */
1705e71b7053SJung-uk Kim     for (i = 0; i < SSL_PKEY_NUM; i++)
1706b077aed3SPierre Pronchery         s->s3.tmp.valid_flags[i] = 0;
1707e71b7053SJung-uk Kim     /*
1708e71b7053SJung-uk Kim      * If peer sent no signature algorithms check to see if we support
1709e71b7053SJung-uk Kim      * the default algorithm for each certificate type
1710e71b7053SJung-uk Kim      */
1711b077aed3SPierre Pronchery     if (s->s3.tmp.peer_cert_sigalgs == NULL
1712b077aed3SPierre Pronchery             && s->s3.tmp.peer_sigalgs == NULL) {
1713e71b7053SJung-uk Kim         const uint16_t *sent_sigs;
1714e71b7053SJung-uk Kim         size_t sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs);
1715e71b7053SJung-uk Kim 
17167bded2dbSJung-uk Kim         for (i = 0; i < SSL_PKEY_NUM; i++) {
1717e71b7053SJung-uk Kim             const SIGALG_LOOKUP *lu = tls1_get_legacy_sigalg(s, i);
1718e71b7053SJung-uk Kim             size_t j;
1719e71b7053SJung-uk Kim 
1720e71b7053SJung-uk Kim             if (lu == NULL)
1721e71b7053SJung-uk Kim                 continue;
1722e71b7053SJung-uk Kim             /* Check default matches a type we sent */
1723e71b7053SJung-uk Kim             for (j = 0; j < sent_sigslen; j++) {
1724e71b7053SJung-uk Kim                 if (lu->sigalg == sent_sigs[j]) {
1725b077aed3SPierre Pronchery                         s->s3.tmp.valid_flags[i] = CERT_PKEY_SIGN;
1726e71b7053SJung-uk Kim                         break;
1727e71b7053SJung-uk Kim                 }
1728e71b7053SJung-uk Kim             }
1729e71b7053SJung-uk Kim         }
1730e71b7053SJung-uk Kim         return 1;
17317bded2dbSJung-uk Kim     }
17327bded2dbSJung-uk Kim 
17337bded2dbSJung-uk Kim     if (!tls1_process_sigalgs(s)) {
1734b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
17357bded2dbSJung-uk Kim         return 0;
17367bded2dbSJung-uk Kim     }
1737da327cd2SJung-uk Kim     if (s->shared_sigalgs != NULL)
1738e71b7053SJung-uk Kim         return 1;
17397bded2dbSJung-uk Kim 
1740e71b7053SJung-uk Kim     /* Fatal error if no shared signature algorithms */
1741b077aed3SPierre Pronchery     SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
1742e71b7053SJung-uk Kim              SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS);
17436cf8931aSJung-uk Kim     return 0;
174409286989SJung-uk Kim }
17457bded2dbSJung-uk Kim 
17466f9291ceSJung-uk Kim /*-
1747e71b7053SJung-uk Kim  * Gets the ticket information supplied by the client if any.
17481f13597dSJung-uk Kim  *
1749e71b7053SJung-uk Kim  *   hello: The parsed ClientHello data
17501f13597dSJung-uk Kim  *   ret: (output) on return, if a ticket was decrypted, then this is set to
17511f13597dSJung-uk Kim  *       point to the resulting session.
1752e71b7053SJung-uk Kim  */
1753e71b7053SJung-uk Kim SSL_TICKET_STATUS tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello,
1754e71b7053SJung-uk Kim                                              SSL_SESSION **ret)
1755e71b7053SJung-uk Kim {
1756e71b7053SJung-uk Kim     size_t size;
1757e71b7053SJung-uk Kim     RAW_EXTENSION *ticketext;
1758e71b7053SJung-uk Kim 
1759e71b7053SJung-uk Kim     *ret = NULL;
1760e71b7053SJung-uk Kim     s->ext.ticket_expected = 0;
1761e71b7053SJung-uk Kim 
1762e71b7053SJung-uk Kim     /*
1763e71b7053SJung-uk Kim      * If tickets disabled or not supported by the protocol version
1764e71b7053SJung-uk Kim      * (e.g. TLSv1.3) behave as if no ticket present to permit stateful
1765e71b7053SJung-uk Kim      * resumption.
1766e71b7053SJung-uk Kim      */
1767e71b7053SJung-uk Kim     if (s->version <= SSL3_VERSION || !tls_use_ticket(s))
1768e71b7053SJung-uk Kim         return SSL_TICKET_NONE;
1769e71b7053SJung-uk Kim 
1770e71b7053SJung-uk Kim     ticketext = &hello->pre_proc_exts[TLSEXT_IDX_session_ticket];
1771e71b7053SJung-uk Kim     if (!ticketext->present)
1772e71b7053SJung-uk Kim         return SSL_TICKET_NONE;
1773e71b7053SJung-uk Kim 
1774e71b7053SJung-uk Kim     size = PACKET_remaining(&ticketext->data);
1775e71b7053SJung-uk Kim 
1776e71b7053SJung-uk Kim     return tls_decrypt_ticket(s, PACKET_data(&ticketext->data), size,
1777e71b7053SJung-uk Kim                               hello->session_id, hello->session_id_len, ret);
1778e71b7053SJung-uk Kim }
1779e71b7053SJung-uk Kim 
1780e71b7053SJung-uk Kim /*-
1781e71b7053SJung-uk Kim  * tls_decrypt_ticket attempts to decrypt a session ticket.
17821f13597dSJung-uk Kim  *
1783e71b7053SJung-uk Kim  * If s->tls_session_secret_cb is set and we're not doing TLSv1.3 then we are
1784e71b7053SJung-uk Kim  * expecting a pre-shared key ciphersuite, in which case we have no use for
1785e71b7053SJung-uk Kim  * session tickets and one will never be decrypted, nor will
1786e71b7053SJung-uk Kim  * s->ext.ticket_expected be set to 1.
17871f13597dSJung-uk Kim  *
17881f13597dSJung-uk Kim  * Side effects:
1789e71b7053SJung-uk Kim  *   Sets s->ext.ticket_expected to 1 if the server will have to issue
17901f13597dSJung-uk Kim  *   a new session ticket to the client because the client indicated support
17911f13597dSJung-uk Kim  *   (and s->tls_session_secret_cb is NULL) but the client either doesn't have
17921f13597dSJung-uk Kim  *   a session ticket or we couldn't use the one it gave us, or if
1793e71b7053SJung-uk Kim  *   s->ctx->ext.ticket_key_cb asked to renew the client's ticket.
1794e71b7053SJung-uk Kim  *   Otherwise, s->ext.ticket_expected is set to 0.
1795e71b7053SJung-uk Kim  *
1796e71b7053SJung-uk Kim  *   etick: points to the body of the session ticket extension.
1797e71b7053SJung-uk Kim  *   eticklen: the length of the session tickets extension.
1798e71b7053SJung-uk Kim  *   sess_id: points at the session ID.
1799e71b7053SJung-uk Kim  *   sesslen: the length of the session ID.
1800e71b7053SJung-uk Kim  *   psess: (output) on return, if a ticket was decrypted, then this is set to
1801e71b7053SJung-uk Kim  *       point to the resulting session.
1802db522d3aSSimon L. B. Nielsen  */
1803e71b7053SJung-uk Kim SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick,
1804e71b7053SJung-uk Kim                                      size_t eticklen, const unsigned char *sess_id,
1805e71b7053SJung-uk Kim                                      size_t sesslen, SSL_SESSION **psess)
1806db522d3aSSimon L. B. Nielsen {
1807e71b7053SJung-uk Kim     SSL_SESSION *sess = NULL;
1808e71b7053SJung-uk Kim     unsigned char *sdec;
1809e71b7053SJung-uk Kim     const unsigned char *p;
1810b077aed3SPierre Pronchery     int slen, ivlen, renew_ticket = 0, declen;
1811e71b7053SJung-uk Kim     SSL_TICKET_STATUS ret = SSL_TICKET_FATAL_ERR_OTHER;
1812e71b7053SJung-uk Kim     size_t mlen;
1813e71b7053SJung-uk Kim     unsigned char tick_hmac[EVP_MAX_MD_SIZE];
1814b077aed3SPierre Pronchery     SSL_HMAC *hctx = NULL;
1815e71b7053SJung-uk Kim     EVP_CIPHER_CTX *ctx = NULL;
1816e71b7053SJung-uk Kim     SSL_CTX *tctx = s->session_ctx;
1817db522d3aSSimon L. B. Nielsen 
1818e71b7053SJung-uk Kim     if (eticklen == 0) {
18196f9291ceSJung-uk Kim         /*
18206f9291ceSJung-uk Kim          * The client will accept a ticket but doesn't currently have
1821e71b7053SJung-uk Kim          * one (TLSv1.2 and below), or treated as a fatal error in TLSv1.3
18226f9291ceSJung-uk Kim          */
1823e71b7053SJung-uk Kim         ret = SSL_TICKET_EMPTY;
1824e71b7053SJung-uk Kim         goto end;
1825db522d3aSSimon L. B. Nielsen     }
1826e71b7053SJung-uk Kim     if (!SSL_IS_TLS13(s) && s->ext.session_secret_cb) {
18276f9291ceSJung-uk Kim         /*
18286f9291ceSJung-uk Kim          * Indicate that the ticket couldn't be decrypted rather than
18296f9291ceSJung-uk Kim          * generating the session from ticket now, trigger
18306f9291ceSJung-uk Kim          * abbreviated handshake based on external mechanism to
18316f9291ceSJung-uk Kim          * calculate the master secret later.
18326f9291ceSJung-uk Kim          */
1833e71b7053SJung-uk Kim         ret = SSL_TICKET_NO_DECRYPT;
1834e71b7053SJung-uk Kim         goto end;
18351f13597dSJung-uk Kim     }
1836aeb5019cSJung-uk Kim 
1837dee36b4fSJung-uk Kim     /* Need at least keyname + iv */
1838e71b7053SJung-uk Kim     if (eticklen < TLSEXT_KEYNAME_LENGTH + EVP_MAX_IV_LENGTH) {
1839e71b7053SJung-uk Kim         ret = SSL_TICKET_NO_DECRYPT;
1840e71b7053SJung-uk Kim         goto end;
1841e71b7053SJung-uk Kim     }
1842dee36b4fSJung-uk Kim 
1843db522d3aSSimon L. B. Nielsen     /* Initialize session ticket encryption and HMAC contexts */
1844b077aed3SPierre Pronchery     hctx = ssl_hmac_new(tctx);
1845e71b7053SJung-uk Kim     if (hctx == NULL) {
1846e71b7053SJung-uk Kim         ret = SSL_TICKET_FATAL_ERR_MALLOC;
1847e71b7053SJung-uk Kim         goto end;
1848e71b7053SJung-uk Kim     }
1849e71b7053SJung-uk Kim     ctx = EVP_CIPHER_CTX_new();
1850e71b7053SJung-uk Kim     if (ctx == NULL) {
1851e71b7053SJung-uk Kim         ret = SSL_TICKET_FATAL_ERR_MALLOC;
1852e71b7053SJung-uk Kim         goto end;
1853e71b7053SJung-uk Kim     }
1854b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DEPRECATED_3_0
1855b077aed3SPierre Pronchery     if (tctx->ext.ticket_key_evp_cb != NULL || tctx->ext.ticket_key_cb != NULL)
1856b077aed3SPierre Pronchery #else
1857b077aed3SPierre Pronchery     if (tctx->ext.ticket_key_evp_cb != NULL)
1858b077aed3SPierre Pronchery #endif
1859b077aed3SPierre Pronchery     {
1860db522d3aSSimon L. B. Nielsen         unsigned char *nctick = (unsigned char *)etick;
1861b077aed3SPierre Pronchery         int rv = 0;
1862b077aed3SPierre Pronchery 
1863b077aed3SPierre Pronchery         if (tctx->ext.ticket_key_evp_cb != NULL)
1864b077aed3SPierre Pronchery             rv = tctx->ext.ticket_key_evp_cb(s, nctick,
1865e71b7053SJung-uk Kim                                              nctick + TLSEXT_KEYNAME_LENGTH,
1866b077aed3SPierre Pronchery                                              ctx,
1867b077aed3SPierre Pronchery                                              ssl_hmac_get0_EVP_MAC_CTX(hctx),
1868b077aed3SPierre Pronchery                                              0);
1869b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DEPRECATED_3_0
1870b077aed3SPierre Pronchery         else if (tctx->ext.ticket_key_cb != NULL)
1871b077aed3SPierre Pronchery             /* if 0 is returned, write an empty ticket */
1872b077aed3SPierre Pronchery             rv = tctx->ext.ticket_key_cb(s, nctick,
1873b077aed3SPierre Pronchery                                          nctick + TLSEXT_KEYNAME_LENGTH,
1874b077aed3SPierre Pronchery                                          ctx, ssl_hmac_get0_HMAC_CTX(hctx), 0);
1875b077aed3SPierre Pronchery #endif
1876e71b7053SJung-uk Kim         if (rv < 0) {
1877e71b7053SJung-uk Kim             ret = SSL_TICKET_FATAL_ERR_OTHER;
1878e71b7053SJung-uk Kim             goto end;
1879e71b7053SJung-uk Kim         }
1880dee36b4fSJung-uk Kim         if (rv == 0) {
1881e71b7053SJung-uk Kim             ret = SSL_TICKET_NO_DECRYPT;
1882e71b7053SJung-uk Kim             goto end;
1883dee36b4fSJung-uk Kim         }
1884db522d3aSSimon L. B. Nielsen         if (rv == 2)
1885db522d3aSSimon L. B. Nielsen             renew_ticket = 1;
18866f9291ceSJung-uk Kim     } else {
1887b077aed3SPierre Pronchery         EVP_CIPHER *aes256cbc = NULL;
1888b077aed3SPierre Pronchery 
1889db522d3aSSimon L. B. Nielsen         /* Check key name matches */
1890e71b7053SJung-uk Kim         if (memcmp(etick, tctx->ext.tick_key_name,
1891e71b7053SJung-uk Kim                    TLSEXT_KEYNAME_LENGTH) != 0) {
1892e71b7053SJung-uk Kim             ret = SSL_TICKET_NO_DECRYPT;
1893e71b7053SJung-uk Kim             goto end;
189480815a77SJung-uk Kim         }
1895b077aed3SPierre Pronchery 
1896b077aed3SPierre Pronchery         aes256cbc = EVP_CIPHER_fetch(s->ctx->libctx, "AES-256-CBC",
1897b077aed3SPierre Pronchery                                      s->ctx->propq);
1898b077aed3SPierre Pronchery         if (aes256cbc == NULL
1899b077aed3SPierre Pronchery             || ssl_hmac_init(hctx, tctx->ext.secure->tick_hmac_key,
1900e71b7053SJung-uk Kim                              sizeof(tctx->ext.secure->tick_hmac_key),
1901b077aed3SPierre Pronchery                              "SHA256") <= 0
1902b077aed3SPierre Pronchery             || EVP_DecryptInit_ex(ctx, aes256cbc, NULL,
1903e71b7053SJung-uk Kim                                   tctx->ext.secure->tick_aes_key,
1904e71b7053SJung-uk Kim                                   etick + TLSEXT_KEYNAME_LENGTH) <= 0) {
1905b077aed3SPierre Pronchery             EVP_CIPHER_free(aes256cbc);
1906e71b7053SJung-uk Kim             ret = SSL_TICKET_FATAL_ERR_OTHER;
1907e71b7053SJung-uk Kim             goto end;
1908e71b7053SJung-uk Kim         }
1909b077aed3SPierre Pronchery         EVP_CIPHER_free(aes256cbc);
1910e71b7053SJung-uk Kim         if (SSL_IS_TLS13(s))
1911e71b7053SJung-uk Kim             renew_ticket = 1;
1912db522d3aSSimon L. B. Nielsen     }
19136f9291ceSJung-uk Kim     /*
19146f9291ceSJung-uk Kim      * Attempt to process session ticket, first conduct sanity and integrity
19156f9291ceSJung-uk Kim      * checks on ticket.
1916db522d3aSSimon L. B. Nielsen      */
1917b077aed3SPierre Pronchery     mlen = ssl_hmac_size(hctx);
1918e71b7053SJung-uk Kim     if (mlen == 0) {
1919e71b7053SJung-uk Kim         ret = SSL_TICKET_FATAL_ERR_OTHER;
1920e71b7053SJung-uk Kim         goto end;
1921aeb5019cSJung-uk Kim     }
1922aeb5019cSJung-uk Kim 
1923b077aed3SPierre Pronchery     ivlen = EVP_CIPHER_CTX_get_iv_length(ctx);
1924b077aed3SPierre Pronchery     if (ivlen < 0) {
1925b077aed3SPierre Pronchery         ret = SSL_TICKET_FATAL_ERR_OTHER;
1926b077aed3SPierre Pronchery         goto end;
1927b077aed3SPierre Pronchery     }
1928b077aed3SPierre Pronchery 
1929e71b7053SJung-uk Kim     /* Sanity check ticket length: must exceed keyname + IV + HMAC */
1930b077aed3SPierre Pronchery     if (eticklen <= TLSEXT_KEYNAME_LENGTH + ivlen + mlen) {
1931e71b7053SJung-uk Kim         ret = SSL_TICKET_NO_DECRYPT;
1932e71b7053SJung-uk Kim         goto end;
1933e71b7053SJung-uk Kim     }
1934db522d3aSSimon L. B. Nielsen     eticklen -= mlen;
1935db522d3aSSimon L. B. Nielsen     /* Check HMAC of encrypted ticket */
1936b077aed3SPierre Pronchery     if (ssl_hmac_update(hctx, etick, eticklen) <= 0
1937b077aed3SPierre Pronchery         || ssl_hmac_final(hctx, tick_hmac, NULL, sizeof(tick_hmac)) <= 0) {
1938e71b7053SJung-uk Kim         ret = SSL_TICKET_FATAL_ERR_OTHER;
1939e71b7053SJung-uk Kim         goto end;
194080815a77SJung-uk Kim     }
1941e71b7053SJung-uk Kim 
19426f9291ceSJung-uk Kim     if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) {
1943e71b7053SJung-uk Kim         ret = SSL_TICKET_NO_DECRYPT;
1944e71b7053SJung-uk Kim         goto end;
1945fa5fddf1SJung-uk Kim     }
1946db522d3aSSimon L. B. Nielsen     /* Attempt to decrypt session data */
1947db522d3aSSimon L. B. Nielsen     /* Move p after IV to start of encrypted ticket, update length */
1948b077aed3SPierre Pronchery     p = etick + TLSEXT_KEYNAME_LENGTH + ivlen;
1949b077aed3SPierre Pronchery     eticklen -= TLSEXT_KEYNAME_LENGTH + ivlen;
1950db522d3aSSimon L. B. Nielsen     sdec = OPENSSL_malloc(eticklen);
1951e71b7053SJung-uk Kim     if (sdec == NULL || EVP_DecryptUpdate(ctx, sdec, &slen, p,
1952e71b7053SJung-uk Kim                                           (int)eticklen) <= 0) {
1953b8721c16SJung-uk Kim         OPENSSL_free(sdec);
1954e71b7053SJung-uk Kim         ret = SSL_TICKET_FATAL_ERR_OTHER;
1955e71b7053SJung-uk Kim         goto end;
1956db522d3aSSimon L. B. Nielsen     }
1957e71b7053SJung-uk Kim     if (EVP_DecryptFinal(ctx, sdec + slen, &declen) <= 0) {
1958a93cbc2bSJung-uk Kim         OPENSSL_free(sdec);
1959e71b7053SJung-uk Kim         ret = SSL_TICKET_NO_DECRYPT;
1960e71b7053SJung-uk Kim         goto end;
1961a93cbc2bSJung-uk Kim     }
1962e71b7053SJung-uk Kim     slen += declen;
1963db522d3aSSimon L. B. Nielsen     p = sdec;
1964db522d3aSSimon L. B. Nielsen 
1965db522d3aSSimon L. B. Nielsen     sess = d2i_SSL_SESSION(NULL, &p, slen);
1966ed7112f0SJung-uk Kim     slen -= p - sdec;
1967db522d3aSSimon L. B. Nielsen     OPENSSL_free(sdec);
19686f9291ceSJung-uk Kim     if (sess) {
1969ed7112f0SJung-uk Kim         /* Some additional consistency checks */
1970e71b7053SJung-uk Kim         if (slen != 0) {
1971ed7112f0SJung-uk Kim             SSL_SESSION_free(sess);
1972e71b7053SJung-uk Kim             sess = NULL;
1973e71b7053SJung-uk Kim             ret = SSL_TICKET_NO_DECRYPT;
1974e71b7053SJung-uk Kim             goto end;
1975ed7112f0SJung-uk Kim         }
19766f9291ceSJung-uk Kim         /*
19776f9291ceSJung-uk Kim          * The session ID, if non-empty, is used by some clients to detect
19786f9291ceSJung-uk Kim          * that the ticket has been accepted. So we copy it to the session
19796f9291ceSJung-uk Kim          * structure. If it is empty set length to zero as required by
19806f9291ceSJung-uk Kim          * standard.
1981db522d3aSSimon L. B. Nielsen          */
1982e71b7053SJung-uk Kim         if (sesslen) {
1983db522d3aSSimon L. B. Nielsen             memcpy(sess->session_id, sess_id, sesslen);
1984db522d3aSSimon L. B. Nielsen             sess->session_id_length = sesslen;
1985e71b7053SJung-uk Kim         }
19861f13597dSJung-uk Kim         if (renew_ticket)
1987e71b7053SJung-uk Kim             ret = SSL_TICKET_SUCCESS_RENEW;
19881f13597dSJung-uk Kim         else
1989e71b7053SJung-uk Kim             ret = SSL_TICKET_SUCCESS;
1990e71b7053SJung-uk Kim         goto end;
19911f13597dSJung-uk Kim     }
19921f13597dSJung-uk Kim     ERR_clear_error();
19936f9291ceSJung-uk Kim     /*
19946f9291ceSJung-uk Kim      * For session parse failure, indicate that we need to send a new ticket.
19956f9291ceSJung-uk Kim      */
1996e71b7053SJung-uk Kim     ret = SSL_TICKET_NO_DECRYPT;
19971f13597dSJung-uk Kim 
1998e71b7053SJung-uk Kim  end:
1999e71b7053SJung-uk Kim     EVP_CIPHER_CTX_free(ctx);
2000b077aed3SPierre Pronchery     ssl_hmac_free(hctx);
20011f13597dSJung-uk Kim 
2002e71b7053SJung-uk Kim     /*
2003e71b7053SJung-uk Kim      * If set, the decrypt_ticket_cb() is called unless a fatal error was
2004e71b7053SJung-uk Kim      * detected above. The callback is responsible for checking |ret| before it
2005e71b7053SJung-uk Kim      * performs any action
2006e71b7053SJung-uk Kim      */
2007e71b7053SJung-uk Kim     if (s->session_ctx->decrypt_ticket_cb != NULL
2008e71b7053SJung-uk Kim             && (ret == SSL_TICKET_EMPTY
2009e71b7053SJung-uk Kim                 || ret == SSL_TICKET_NO_DECRYPT
2010e71b7053SJung-uk Kim                 || ret == SSL_TICKET_SUCCESS
2011e71b7053SJung-uk Kim                 || ret == SSL_TICKET_SUCCESS_RENEW)) {
2012e71b7053SJung-uk Kim         size_t keyname_len = eticklen;
2013e71b7053SJung-uk Kim         int retcb;
20141f13597dSJung-uk Kim 
2015e71b7053SJung-uk Kim         if (keyname_len > TLSEXT_KEYNAME_LENGTH)
2016e71b7053SJung-uk Kim             keyname_len = TLSEXT_KEYNAME_LENGTH;
2017e71b7053SJung-uk Kim         retcb = s->session_ctx->decrypt_ticket_cb(s, sess, etick, keyname_len,
2018e71b7053SJung-uk Kim                                                   ret,
2019e71b7053SJung-uk Kim                                                   s->session_ctx->ticket_cb_data);
2020e71b7053SJung-uk Kim         switch (retcb) {
2021e71b7053SJung-uk Kim         case SSL_TICKET_RETURN_ABORT:
2022e71b7053SJung-uk Kim             ret = SSL_TICKET_FATAL_ERR_OTHER;
2023e71b7053SJung-uk Kim             break;
20241f13597dSJung-uk Kim 
2025e71b7053SJung-uk Kim         case SSL_TICKET_RETURN_IGNORE:
2026e71b7053SJung-uk Kim             ret = SSL_TICKET_NONE;
2027e71b7053SJung-uk Kim             SSL_SESSION_free(sess);
2028e71b7053SJung-uk Kim             sess = NULL;
2029e71b7053SJung-uk Kim             break;
20301f13597dSJung-uk Kim 
2031e71b7053SJung-uk Kim         case SSL_TICKET_RETURN_IGNORE_RENEW:
2032e71b7053SJung-uk Kim             if (ret != SSL_TICKET_EMPTY && ret != SSL_TICKET_NO_DECRYPT)
2033e71b7053SJung-uk Kim                 ret = SSL_TICKET_NO_DECRYPT;
2034e71b7053SJung-uk Kim             /* else the value of |ret| will already do the right thing */
2035e71b7053SJung-uk Kim             SSL_SESSION_free(sess);
2036e71b7053SJung-uk Kim             sess = NULL;
2037e71b7053SJung-uk Kim             break;
20386f9291ceSJung-uk Kim 
2039e71b7053SJung-uk Kim         case SSL_TICKET_RETURN_USE:
2040e71b7053SJung-uk Kim         case SSL_TICKET_RETURN_USE_RENEW:
2041e71b7053SJung-uk Kim             if (ret != SSL_TICKET_SUCCESS
2042e71b7053SJung-uk Kim                     && ret != SSL_TICKET_SUCCESS_RENEW)
2043e71b7053SJung-uk Kim                 ret = SSL_TICKET_FATAL_ERR_OTHER;
2044e71b7053SJung-uk Kim             else if (retcb == SSL_TICKET_RETURN_USE)
2045e71b7053SJung-uk Kim                 ret = SSL_TICKET_SUCCESS;
2046e71b7053SJung-uk Kim             else
2047e71b7053SJung-uk Kim                 ret = SSL_TICKET_SUCCESS_RENEW;
2048e71b7053SJung-uk Kim             break;
20491f13597dSJung-uk Kim 
20501f13597dSJung-uk Kim         default:
2051e71b7053SJung-uk Kim             ret = SSL_TICKET_FATAL_ERR_OTHER;
20521f13597dSJung-uk Kim         }
20531f13597dSJung-uk Kim     }
20541f13597dSJung-uk Kim 
2055e71b7053SJung-uk Kim     if (s->ext.session_secret_cb == NULL || SSL_IS_TLS13(s)) {
2056e71b7053SJung-uk Kim         switch (ret) {
2057e71b7053SJung-uk Kim         case SSL_TICKET_NO_DECRYPT:
2058e71b7053SJung-uk Kim         case SSL_TICKET_SUCCESS_RENEW:
2059e71b7053SJung-uk Kim         case SSL_TICKET_EMPTY:
2060e71b7053SJung-uk Kim             s->ext.ticket_expected = 1;
2061e71b7053SJung-uk Kim         }
2062e71b7053SJung-uk Kim     }
2063e71b7053SJung-uk Kim 
2064e71b7053SJung-uk Kim     *psess = sess;
2065e71b7053SJung-uk Kim 
2066e71b7053SJung-uk Kim     return ret;
2067e71b7053SJung-uk Kim }
2068e71b7053SJung-uk Kim 
2069e71b7053SJung-uk Kim /* Check to see if a signature algorithm is allowed */
207017f01e99SJung-uk Kim static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu)
20717bded2dbSJung-uk Kim {
2072e71b7053SJung-uk Kim     unsigned char sigalgstr[2];
2073e71b7053SJung-uk Kim     int secbits;
2074e71b7053SJung-uk Kim 
2075b077aed3SPierre Pronchery     if (lu == NULL || !lu->enabled)
2076e71b7053SJung-uk Kim         return 0;
2077e71b7053SJung-uk Kim     /* DSA is not allowed in TLS 1.3 */
2078e71b7053SJung-uk Kim     if (SSL_IS_TLS13(s) && lu->sig == EVP_PKEY_DSA)
2079e71b7053SJung-uk Kim         return 0;
2080b077aed3SPierre Pronchery     /*
2081b077aed3SPierre Pronchery      * At some point we should fully axe DSA/etc. in ClientHello as per TLS 1.3
2082b077aed3SPierre Pronchery      * spec
2083b077aed3SPierre Pronchery      */
2084b077aed3SPierre Pronchery     if (!s->server && !SSL_IS_DTLS(s) && s->s3.tmp.min_ver >= TLS1_3_VERSION
2085e71b7053SJung-uk Kim         && (lu->sig == EVP_PKEY_DSA || lu->hash_idx == SSL_MD_SHA1_IDX
2086e71b7053SJung-uk Kim             || lu->hash_idx == SSL_MD_MD5_IDX
2087e71b7053SJung-uk Kim             || lu->hash_idx == SSL_MD_SHA224_IDX))
2088e71b7053SJung-uk Kim         return 0;
2089e71b7053SJung-uk Kim 
2090e71b7053SJung-uk Kim     /* See if public key algorithm allowed */
2091b077aed3SPierre Pronchery     if (ssl_cert_is_disabled(s->ctx, lu->sig_idx))
2092e71b7053SJung-uk Kim         return 0;
2093e71b7053SJung-uk Kim 
2094e71b7053SJung-uk Kim     if (lu->sig == NID_id_GostR3410_2012_256
2095e71b7053SJung-uk Kim             || lu->sig == NID_id_GostR3410_2012_512
2096e71b7053SJung-uk Kim             || lu->sig == NID_id_GostR3410_2001) {
2097e71b7053SJung-uk Kim         /* We never allow GOST sig algs on the server with TLSv1.3 */
2098e71b7053SJung-uk Kim         if (s->server && SSL_IS_TLS13(s))
2099e71b7053SJung-uk Kim             return 0;
2100e71b7053SJung-uk Kim         if (!s->server
2101e71b7053SJung-uk Kim                 && s->method->version == TLS_ANY_VERSION
2102b077aed3SPierre Pronchery                 && s->s3.tmp.max_ver >= TLS1_3_VERSION) {
2103e71b7053SJung-uk Kim             int i, num;
2104e71b7053SJung-uk Kim             STACK_OF(SSL_CIPHER) *sk;
2105e71b7053SJung-uk Kim 
2106e71b7053SJung-uk Kim             /*
2107e71b7053SJung-uk Kim              * We're a client that could negotiate TLSv1.3. We only allow GOST
2108e71b7053SJung-uk Kim              * sig algs if we could negotiate TLSv1.2 or below and we have GOST
2109e71b7053SJung-uk Kim              * ciphersuites enabled.
2110e71b7053SJung-uk Kim              */
2111e71b7053SJung-uk Kim 
2112b077aed3SPierre Pronchery             if (s->s3.tmp.min_ver >= TLS1_3_VERSION)
2113e71b7053SJung-uk Kim                 return 0;
2114e71b7053SJung-uk Kim 
2115e71b7053SJung-uk Kim             sk = SSL_get_ciphers(s);
2116e71b7053SJung-uk Kim             num = sk != NULL ? sk_SSL_CIPHER_num(sk) : 0;
2117e71b7053SJung-uk Kim             for (i = 0; i < num; i++) {
2118e71b7053SJung-uk Kim                 const SSL_CIPHER *c;
2119e71b7053SJung-uk Kim 
2120e71b7053SJung-uk Kim                 c = sk_SSL_CIPHER_value(sk, i);
2121e71b7053SJung-uk Kim                 /* Skip disabled ciphers */
2122e71b7053SJung-uk Kim                 if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED, 0))
2123e71b7053SJung-uk Kim                     continue;
2124e71b7053SJung-uk Kim 
2125b077aed3SPierre Pronchery                 if ((c->algorithm_mkey & (SSL_kGOST | SSL_kGOST18)) != 0)
2126e71b7053SJung-uk Kim                     break;
21277bded2dbSJung-uk Kim             }
2128e71b7053SJung-uk Kim             if (i == num)
2129e71b7053SJung-uk Kim                 return 0;
2130e71b7053SJung-uk Kim         }
21317bded2dbSJung-uk Kim     }
21327bded2dbSJung-uk Kim 
2133e71b7053SJung-uk Kim     /* Finally see if security callback allows it */
2134b077aed3SPierre Pronchery     secbits = sigalg_security_bits(s->ctx, lu);
2135e71b7053SJung-uk Kim     sigalgstr[0] = (lu->sigalg >> 8) & 0xff;
2136e71b7053SJung-uk Kim     sigalgstr[1] = lu->sigalg & 0xff;
2137e71b7053SJung-uk Kim     return ssl_security(s, op, secbits, lu->hash, (void *)sigalgstr);
2138e71b7053SJung-uk Kim }
2139e71b7053SJung-uk Kim 
2140e71b7053SJung-uk Kim /*
2141e71b7053SJung-uk Kim  * Get a mask of disabled public key algorithms based on supported signature
2142e71b7053SJung-uk Kim  * algorithms. For example if no signature algorithm supports RSA then RSA is
2143e71b7053SJung-uk Kim  * disabled.
2144e71b7053SJung-uk Kim  */
2145e71b7053SJung-uk Kim 
2146e71b7053SJung-uk Kim void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op)
21477bded2dbSJung-uk Kim {
2148e71b7053SJung-uk Kim     const uint16_t *sigalgs;
2149e71b7053SJung-uk Kim     size_t i, sigalgslen;
2150e71b7053SJung-uk Kim     uint32_t disabled_mask = SSL_aRSA | SSL_aDSS | SSL_aECDSA;
2151e71b7053SJung-uk Kim     /*
2152e71b7053SJung-uk Kim      * Go through all signature algorithms seeing if we support any
2153e71b7053SJung-uk Kim      * in disabled_mask.
2154e71b7053SJung-uk Kim      */
2155e71b7053SJung-uk Kim     sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs);
2156e71b7053SJung-uk Kim     for (i = 0; i < sigalgslen; i++, sigalgs++) {
2157b077aed3SPierre Pronchery         const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *sigalgs);
2158e71b7053SJung-uk Kim         const SSL_CERT_LOOKUP *clu;
2159e71b7053SJung-uk Kim 
2160e71b7053SJung-uk Kim         if (lu == NULL)
2161e71b7053SJung-uk Kim             continue;
2162e71b7053SJung-uk Kim 
2163e71b7053SJung-uk Kim         clu = ssl_cert_lookup_by_idx(lu->sig_idx);
2164e71b7053SJung-uk Kim         if (clu == NULL)
2165e71b7053SJung-uk Kim                 continue;
2166e71b7053SJung-uk Kim 
2167e71b7053SJung-uk Kim         /* If algorithm is disabled see if we can enable it */
2168e71b7053SJung-uk Kim         if ((clu->amask & disabled_mask) != 0
2169e71b7053SJung-uk Kim                 && tls12_sigalg_allowed(s, op, lu))
2170e71b7053SJung-uk Kim             disabled_mask &= ~clu->amask;
21717bded2dbSJung-uk Kim     }
2172e71b7053SJung-uk Kim     *pmask_a |= disabled_mask;
21737bded2dbSJung-uk Kim }
2174e71b7053SJung-uk Kim 
2175e71b7053SJung-uk Kim int tls12_copy_sigalgs(SSL *s, WPACKET *pkt,
2176e71b7053SJung-uk Kim                        const uint16_t *psig, size_t psiglen)
2177e71b7053SJung-uk Kim {
2178e71b7053SJung-uk Kim     size_t i;
2179e71b7053SJung-uk Kim     int rv = 0;
2180e71b7053SJung-uk Kim 
2181e71b7053SJung-uk Kim     for (i = 0; i < psiglen; i++, psig++) {
2182b077aed3SPierre Pronchery         const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *psig);
2183e71b7053SJung-uk Kim 
2184b077aed3SPierre Pronchery         if (lu == NULL
2185b077aed3SPierre Pronchery                 || !tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, lu))
2186e71b7053SJung-uk Kim             continue;
2187e71b7053SJung-uk Kim         if (!WPACKET_put_bytes_u16(pkt, *psig))
2188e71b7053SJung-uk Kim             return 0;
2189e71b7053SJung-uk Kim         /*
2190e71b7053SJung-uk Kim          * If TLS 1.3 must have at least one valid TLS 1.3 message
2191e71b7053SJung-uk Kim          * signing algorithm: i.e. neither RSA nor SHA1/SHA224
2192e71b7053SJung-uk Kim          */
2193e71b7053SJung-uk Kim         if (rv == 0 && (!SSL_IS_TLS13(s)
2194e71b7053SJung-uk Kim             || (lu->sig != EVP_PKEY_RSA
2195e71b7053SJung-uk Kim                 && lu->hash != NID_sha1
2196e71b7053SJung-uk Kim                 && lu->hash != NID_sha224)))
2197e71b7053SJung-uk Kim             rv = 1;
21987bded2dbSJung-uk Kim     }
2199e71b7053SJung-uk Kim     if (rv == 0)
2200b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM);
2201e71b7053SJung-uk Kim     return rv;
22027bded2dbSJung-uk Kim }
22037bded2dbSJung-uk Kim 
22047bded2dbSJung-uk Kim /* Given preference and allowed sigalgs set shared sigalgs */
2205e71b7053SJung-uk Kim static size_t tls12_shared_sigalgs(SSL *s, const SIGALG_LOOKUP **shsig,
2206e71b7053SJung-uk Kim                                    const uint16_t *pref, size_t preflen,
2207e71b7053SJung-uk Kim                                    const uint16_t *allow, size_t allowlen)
22087bded2dbSJung-uk Kim {
2209e71b7053SJung-uk Kim     const uint16_t *ptmp, *atmp;
22107bded2dbSJung-uk Kim     size_t i, j, nmatch = 0;
2211e71b7053SJung-uk Kim     for (i = 0, ptmp = pref; i < preflen; i++, ptmp++) {
2212b077aed3SPierre Pronchery         const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *ptmp);
2213e71b7053SJung-uk Kim 
22147bded2dbSJung-uk Kim         /* Skip disabled hashes or signature algorithms */
2215b077aed3SPierre Pronchery         if (lu == NULL
2216b077aed3SPierre Pronchery                 || !tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SHARED, lu))
22177bded2dbSJung-uk Kim             continue;
2218e71b7053SJung-uk Kim         for (j = 0, atmp = allow; j < allowlen; j++, atmp++) {
2219e71b7053SJung-uk Kim             if (*ptmp == *atmp) {
22207bded2dbSJung-uk Kim                 nmatch++;
2221e71b7053SJung-uk Kim                 if (shsig)
2222e71b7053SJung-uk Kim                     *shsig++ = lu;
22237bded2dbSJung-uk Kim                 break;
22247bded2dbSJung-uk Kim             }
22257bded2dbSJung-uk Kim         }
22267bded2dbSJung-uk Kim     }
22277bded2dbSJung-uk Kim     return nmatch;
22287bded2dbSJung-uk Kim }
22297bded2dbSJung-uk Kim 
22307bded2dbSJung-uk Kim /* Set shared signature algorithms for SSL structures */
22317bded2dbSJung-uk Kim static int tls1_set_shared_sigalgs(SSL *s)
22327bded2dbSJung-uk Kim {
2233e71b7053SJung-uk Kim     const uint16_t *pref, *allow, *conf;
22347bded2dbSJung-uk Kim     size_t preflen, allowlen, conflen;
22357bded2dbSJung-uk Kim     size_t nmatch;
2236e71b7053SJung-uk Kim     const SIGALG_LOOKUP **salgs = NULL;
22377bded2dbSJung-uk Kim     CERT *c = s->cert;
22387bded2dbSJung-uk Kim     unsigned int is_suiteb = tls1_suiteb(s);
2239e71b7053SJung-uk Kim 
2240da327cd2SJung-uk Kim     OPENSSL_free(s->shared_sigalgs);
2241da327cd2SJung-uk Kim     s->shared_sigalgs = NULL;
2242da327cd2SJung-uk Kim     s->shared_sigalgslen = 0;
22437bded2dbSJung-uk Kim     /* If client use client signature algorithms if not NULL */
22447bded2dbSJung-uk Kim     if (!s->server && c->client_sigalgs && !is_suiteb) {
22457bded2dbSJung-uk Kim         conf = c->client_sigalgs;
22467bded2dbSJung-uk Kim         conflen = c->client_sigalgslen;
22477bded2dbSJung-uk Kim     } else if (c->conf_sigalgs && !is_suiteb) {
22487bded2dbSJung-uk Kim         conf = c->conf_sigalgs;
22497bded2dbSJung-uk Kim         conflen = c->conf_sigalgslen;
22507bded2dbSJung-uk Kim     } else
2251ed7112f0SJung-uk Kim         conflen = tls12_get_psigalgs(s, 0, &conf);
22527bded2dbSJung-uk Kim     if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) {
22537bded2dbSJung-uk Kim         pref = conf;
22547bded2dbSJung-uk Kim         preflen = conflen;
2255b077aed3SPierre Pronchery         allow = s->s3.tmp.peer_sigalgs;
2256b077aed3SPierre Pronchery         allowlen = s->s3.tmp.peer_sigalgslen;
22577bded2dbSJung-uk Kim     } else {
22587bded2dbSJung-uk Kim         allow = conf;
22597bded2dbSJung-uk Kim         allowlen = conflen;
2260b077aed3SPierre Pronchery         pref = s->s3.tmp.peer_sigalgs;
2261b077aed3SPierre Pronchery         preflen = s->s3.tmp.peer_sigalgslen;
22627bded2dbSJung-uk Kim     }
2263e71b7053SJung-uk Kim     nmatch = tls12_shared_sigalgs(s, NULL, pref, preflen, allow, allowlen);
22647bded2dbSJung-uk Kim     if (nmatch) {
2265e71b7053SJung-uk Kim         if ((salgs = OPENSSL_malloc(nmatch * sizeof(*salgs))) == NULL) {
2266b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
22677bded2dbSJung-uk Kim             return 0;
2268e71b7053SJung-uk Kim         }
2269e71b7053SJung-uk Kim         nmatch = tls12_shared_sigalgs(s, salgs, pref, preflen, allow, allowlen);
22707bded2dbSJung-uk Kim     } else {
22717bded2dbSJung-uk Kim         salgs = NULL;
22727bded2dbSJung-uk Kim     }
2273da327cd2SJung-uk Kim     s->shared_sigalgs = salgs;
2274da327cd2SJung-uk Kim     s->shared_sigalgslen = nmatch;
22757bded2dbSJung-uk Kim     return 1;
22767bded2dbSJung-uk Kim }
22777bded2dbSJung-uk Kim 
2278e71b7053SJung-uk Kim int tls1_save_u16(PACKET *pkt, uint16_t **pdest, size_t *pdestlen)
22791f13597dSJung-uk Kim {
2280e71b7053SJung-uk Kim     unsigned int stmp;
2281e71b7053SJung-uk Kim     size_t size, i;
2282e71b7053SJung-uk Kim     uint16_t *buf;
2283e71b7053SJung-uk Kim 
2284e71b7053SJung-uk Kim     size = PACKET_remaining(pkt);
2285e71b7053SJung-uk Kim 
2286e71b7053SJung-uk Kim     /* Invalid data length */
2287e71b7053SJung-uk Kim     if (size == 0 || (size & 1) != 0)
2288e71b7053SJung-uk Kim         return 0;
2289e71b7053SJung-uk Kim 
2290e71b7053SJung-uk Kim     size >>= 1;
2291e71b7053SJung-uk Kim 
2292e71b7053SJung-uk Kim     if ((buf = OPENSSL_malloc(size * sizeof(*buf))) == NULL)  {
2293b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
2294e71b7053SJung-uk Kim         return 0;
2295e71b7053SJung-uk Kim     }
2296e71b7053SJung-uk Kim     for (i = 0; i < size && PACKET_get_net_2(pkt, &stmp); i++)
2297e71b7053SJung-uk Kim         buf[i] = stmp;
2298e71b7053SJung-uk Kim 
2299e71b7053SJung-uk Kim     if (i != size) {
2300e71b7053SJung-uk Kim         OPENSSL_free(buf);
2301e71b7053SJung-uk Kim         return 0;
2302e71b7053SJung-uk Kim     }
2303e71b7053SJung-uk Kim 
2304e71b7053SJung-uk Kim     OPENSSL_free(*pdest);
2305e71b7053SJung-uk Kim     *pdest = buf;
2306e71b7053SJung-uk Kim     *pdestlen = size;
2307e71b7053SJung-uk Kim 
2308e71b7053SJung-uk Kim     return 1;
2309e71b7053SJung-uk Kim }
2310e71b7053SJung-uk Kim 
2311e71b7053SJung-uk Kim int tls1_save_sigalgs(SSL *s, PACKET *pkt, int cert)
2312e71b7053SJung-uk Kim {
23137bded2dbSJung-uk Kim     /* Extension ignored for inappropriate versions */
23147bded2dbSJung-uk Kim     if (!SSL_USE_SIGALGS(s))
23151f13597dSJung-uk Kim         return 1;
23161f13597dSJung-uk Kim     /* Should never happen */
2317e71b7053SJung-uk Kim     if (s->cert == NULL)
23181f13597dSJung-uk Kim         return 0;
23191f13597dSJung-uk Kim 
2320e71b7053SJung-uk Kim     if (cert)
2321b077aed3SPierre Pronchery         return tls1_save_u16(pkt, &s->s3.tmp.peer_cert_sigalgs,
2322b077aed3SPierre Pronchery                              &s->s3.tmp.peer_cert_sigalgslen);
2323e71b7053SJung-uk Kim     else
2324b077aed3SPierre Pronchery         return tls1_save_u16(pkt, &s->s3.tmp.peer_sigalgs,
2325b077aed3SPierre Pronchery                              &s->s3.tmp.peer_sigalgslen);
2326e71b7053SJung-uk Kim 
23271f13597dSJung-uk Kim }
23281f13597dSJung-uk Kim 
2329e71b7053SJung-uk Kim /* Set preferred digest for each key type */
2330e71b7053SJung-uk Kim 
23317bded2dbSJung-uk Kim int tls1_process_sigalgs(SSL *s)
23327bded2dbSJung-uk Kim {
23337bded2dbSJung-uk Kim     size_t i;
2334b077aed3SPierre Pronchery     uint32_t *pvalid = s->s3.tmp.valid_flags;
2335e71b7053SJung-uk Kim 
23367bded2dbSJung-uk Kim     if (!tls1_set_shared_sigalgs(s))
23377bded2dbSJung-uk Kim         return 0;
23387bded2dbSJung-uk Kim 
2339e71b7053SJung-uk Kim     for (i = 0; i < SSL_PKEY_NUM; i++)
2340e71b7053SJung-uk Kim         pvalid[i] = 0;
23417bded2dbSJung-uk Kim 
2342da327cd2SJung-uk Kim     for (i = 0; i < s->shared_sigalgslen; i++) {
2343da327cd2SJung-uk Kim         const SIGALG_LOOKUP *sigptr = s->shared_sigalgs[i];
2344e71b7053SJung-uk Kim         int idx = sigptr->sig_idx;
23451f13597dSJung-uk Kim 
2346e71b7053SJung-uk Kim         /* Ignore PKCS1 based sig algs in TLSv1.3 */
2347e71b7053SJung-uk Kim         if (SSL_IS_TLS13(s) && sigptr->sig == EVP_PKEY_RSA)
2348e71b7053SJung-uk Kim             continue;
2349e71b7053SJung-uk Kim         /* If not disabled indicate we can explicitly sign */
2350b077aed3SPierre Pronchery         if (pvalid[idx] == 0 && !ssl_cert_is_disabled(s->ctx, idx))
2351e71b7053SJung-uk Kim             pvalid[idx] = CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN;
23527bded2dbSJung-uk Kim     }
23531f13597dSJung-uk Kim     return 1;
23541f13597dSJung-uk Kim }
23551f13597dSJung-uk Kim 
23567bded2dbSJung-uk Kim int SSL_get_sigalgs(SSL *s, int idx,
23577bded2dbSJung-uk Kim                     int *psign, int *phash, int *psignhash,
23587bded2dbSJung-uk Kim                     unsigned char *rsig, unsigned char *rhash)
23597bded2dbSJung-uk Kim {
2360b077aed3SPierre Pronchery     uint16_t *psig = s->s3.tmp.peer_sigalgs;
2361b077aed3SPierre Pronchery     size_t numsigalgs = s->s3.tmp.peer_sigalgslen;
2362e71b7053SJung-uk Kim     if (psig == NULL || numsigalgs > INT_MAX)
23637bded2dbSJung-uk Kim         return 0;
23647bded2dbSJung-uk Kim     if (idx >= 0) {
2365e71b7053SJung-uk Kim         const SIGALG_LOOKUP *lu;
2366e71b7053SJung-uk Kim 
2367e71b7053SJung-uk Kim         if (idx >= (int)numsigalgs)
23687bded2dbSJung-uk Kim             return 0;
23697bded2dbSJung-uk Kim         psig += idx;
2370e71b7053SJung-uk Kim         if (rhash != NULL)
2371e71b7053SJung-uk Kim             *rhash = (unsigned char)((*psig >> 8) & 0xff);
2372e71b7053SJung-uk Kim         if (rsig != NULL)
2373e71b7053SJung-uk Kim             *rsig = (unsigned char)(*psig & 0xff);
2374b077aed3SPierre Pronchery         lu = tls1_lookup_sigalg(s, *psig);
2375e71b7053SJung-uk Kim         if (psign != NULL)
2376e71b7053SJung-uk Kim             *psign = lu != NULL ? lu->sig : NID_undef;
2377e71b7053SJung-uk Kim         if (phash != NULL)
2378e71b7053SJung-uk Kim             *phash = lu != NULL ? lu->hash : NID_undef;
2379e71b7053SJung-uk Kim         if (psignhash != NULL)
2380e71b7053SJung-uk Kim             *psignhash = lu != NULL ? lu->sigandhash : NID_undef;
23817bded2dbSJung-uk Kim     }
2382e71b7053SJung-uk Kim     return (int)numsigalgs;
23837bded2dbSJung-uk Kim }
23847bded2dbSJung-uk Kim 
23857bded2dbSJung-uk Kim int SSL_get_shared_sigalgs(SSL *s, int idx,
23867bded2dbSJung-uk Kim                            int *psign, int *phash, int *psignhash,
23877bded2dbSJung-uk Kim                            unsigned char *rsig, unsigned char *rhash)
23887bded2dbSJung-uk Kim {
2389e71b7053SJung-uk Kim     const SIGALG_LOOKUP *shsigalgs;
2390da327cd2SJung-uk Kim     if (s->shared_sigalgs == NULL
2391e71b7053SJung-uk Kim         || idx < 0
2392da327cd2SJung-uk Kim         || idx >= (int)s->shared_sigalgslen
2393da327cd2SJung-uk Kim         || s->shared_sigalgslen > INT_MAX)
23947bded2dbSJung-uk Kim         return 0;
2395da327cd2SJung-uk Kim     shsigalgs = s->shared_sigalgs[idx];
2396e71b7053SJung-uk Kim     if (phash != NULL)
2397e71b7053SJung-uk Kim         *phash = shsigalgs->hash;
2398e71b7053SJung-uk Kim     if (psign != NULL)
2399e71b7053SJung-uk Kim         *psign = shsigalgs->sig;
2400e71b7053SJung-uk Kim     if (psignhash != NULL)
2401e71b7053SJung-uk Kim         *psignhash = shsigalgs->sigandhash;
2402e71b7053SJung-uk Kim     if (rsig != NULL)
2403e71b7053SJung-uk Kim         *rsig = (unsigned char)(shsigalgs->sigalg & 0xff);
2404e71b7053SJung-uk Kim     if (rhash != NULL)
2405e71b7053SJung-uk Kim         *rhash = (unsigned char)((shsigalgs->sigalg >> 8) & 0xff);
2406da327cd2SJung-uk Kim     return (int)s->shared_sigalgslen;
24077bded2dbSJung-uk Kim }
24081f13597dSJung-uk Kim 
2409e71b7053SJung-uk Kim /* Maximum possible number of unique entries in sigalgs array */
2410e71b7053SJung-uk Kim #define TLS_MAX_SIGALGCNT (OSSL_NELEM(sigalg_lookup_tbl) * 2)
24117bded2dbSJung-uk Kim 
24127bded2dbSJung-uk Kim typedef struct {
24137bded2dbSJung-uk Kim     size_t sigalgcnt;
2414e71b7053SJung-uk Kim     /* TLSEXT_SIGALG_XXX values */
2415e71b7053SJung-uk Kim     uint16_t sigalgs[TLS_MAX_SIGALGCNT];
24167bded2dbSJung-uk Kim } sig_cb_st;
24177bded2dbSJung-uk Kim 
2418e71b7053SJung-uk Kim static void get_sigorhash(int *psig, int *phash, const char *str)
2419e71b7053SJung-uk Kim {
2420e71b7053SJung-uk Kim     if (strcmp(str, "RSA") == 0) {
2421e71b7053SJung-uk Kim         *psig = EVP_PKEY_RSA;
2422e71b7053SJung-uk Kim     } else if (strcmp(str, "RSA-PSS") == 0 || strcmp(str, "PSS") == 0) {
2423e71b7053SJung-uk Kim         *psig = EVP_PKEY_RSA_PSS;
2424e71b7053SJung-uk Kim     } else if (strcmp(str, "DSA") == 0) {
2425e71b7053SJung-uk Kim         *psig = EVP_PKEY_DSA;
2426e71b7053SJung-uk Kim     } else if (strcmp(str, "ECDSA") == 0) {
2427e71b7053SJung-uk Kim         *psig = EVP_PKEY_EC;
2428e71b7053SJung-uk Kim     } else {
2429e71b7053SJung-uk Kim         *phash = OBJ_sn2nid(str);
2430e71b7053SJung-uk Kim         if (*phash == NID_undef)
2431e71b7053SJung-uk Kim             *phash = OBJ_ln2nid(str);
2432e71b7053SJung-uk Kim     }
2433e71b7053SJung-uk Kim }
2434e71b7053SJung-uk Kim /* Maximum length of a signature algorithm string component */
2435e71b7053SJung-uk Kim #define TLS_MAX_SIGSTRING_LEN   40
2436e71b7053SJung-uk Kim 
24377bded2dbSJung-uk Kim static int sig_cb(const char *elem, int len, void *arg)
24387bded2dbSJung-uk Kim {
24397bded2dbSJung-uk Kim     sig_cb_st *sarg = arg;
24407bded2dbSJung-uk Kim     size_t i;
2441e71b7053SJung-uk Kim     const SIGALG_LOOKUP *s;
2442e71b7053SJung-uk Kim     char etmp[TLS_MAX_SIGSTRING_LEN], *p;
2443e71b7053SJung-uk Kim     int sig_alg = NID_undef, hash_alg = NID_undef;
24447bded2dbSJung-uk Kim     if (elem == NULL)
24457bded2dbSJung-uk Kim         return 0;
2446e71b7053SJung-uk Kim     if (sarg->sigalgcnt == TLS_MAX_SIGALGCNT)
24477bded2dbSJung-uk Kim         return 0;
24487bded2dbSJung-uk Kim     if (len > (int)(sizeof(etmp) - 1))
24497bded2dbSJung-uk Kim         return 0;
24507bded2dbSJung-uk Kim     memcpy(etmp, elem, len);
24517bded2dbSJung-uk Kim     etmp[len] = 0;
24527bded2dbSJung-uk Kim     p = strchr(etmp, '+');
2453e71b7053SJung-uk Kim     /*
2454e71b7053SJung-uk Kim      * We only allow SignatureSchemes listed in the sigalg_lookup_tbl;
2455e71b7053SJung-uk Kim      * if there's no '+' in the provided name, look for the new-style combined
2456e71b7053SJung-uk Kim      * name.  If not, match both sig+hash to find the needed SIGALG_LOOKUP.
2457e71b7053SJung-uk Kim      * Just sig+hash is not unique since TLS 1.3 adds rsa_pss_pss_* and
2458e71b7053SJung-uk Kim      * rsa_pss_rsae_* that differ only by public key OID; in such cases
2459e71b7053SJung-uk Kim      * we will pick the _rsae_ variant, by virtue of them appearing earlier
2460e71b7053SJung-uk Kim      * in the table.
2461e71b7053SJung-uk Kim      */
2462e71b7053SJung-uk Kim     if (p == NULL) {
2463e71b7053SJung-uk Kim         for (i = 0, s = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl);
2464e71b7053SJung-uk Kim              i++, s++) {
2465e71b7053SJung-uk Kim             if (s->name != NULL && strcmp(etmp, s->name) == 0) {
2466e71b7053SJung-uk Kim                 sarg->sigalgs[sarg->sigalgcnt++] = s->sigalg;
2467e71b7053SJung-uk Kim                 break;
2468e71b7053SJung-uk Kim             }
2469e71b7053SJung-uk Kim         }
2470e71b7053SJung-uk Kim         if (i == OSSL_NELEM(sigalg_lookup_tbl))
24717bded2dbSJung-uk Kim             return 0;
2472e71b7053SJung-uk Kim     } else {
24737bded2dbSJung-uk Kim         *p = 0;
24747bded2dbSJung-uk Kim         p++;
2475e71b7053SJung-uk Kim         if (*p == 0)
24767bded2dbSJung-uk Kim             return 0;
2477e71b7053SJung-uk Kim         get_sigorhash(&sig_alg, &hash_alg, etmp);
2478e71b7053SJung-uk Kim         get_sigorhash(&sig_alg, &hash_alg, p);
2479e71b7053SJung-uk Kim         if (sig_alg == NID_undef || hash_alg == NID_undef)
24807bded2dbSJung-uk Kim             return 0;
2481e71b7053SJung-uk Kim         for (i = 0, s = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl);
2482e71b7053SJung-uk Kim              i++, s++) {
2483e71b7053SJung-uk Kim             if (s->hash == hash_alg && s->sig == sig_alg) {
2484e71b7053SJung-uk Kim                 sarg->sigalgs[sarg->sigalgcnt++] = s->sigalg;
2485e71b7053SJung-uk Kim                 break;
2486e71b7053SJung-uk Kim             }
2487e71b7053SJung-uk Kim         }
2488e71b7053SJung-uk Kim         if (i == OSSL_NELEM(sigalg_lookup_tbl))
24897bded2dbSJung-uk Kim             return 0;
24907bded2dbSJung-uk Kim     }
2491e71b7053SJung-uk Kim 
2492e71b7053SJung-uk Kim     /* Reject duplicates */
2493e71b7053SJung-uk Kim     for (i = 0; i < sarg->sigalgcnt - 1; i++) {
2494e71b7053SJung-uk Kim         if (sarg->sigalgs[i] == sarg->sigalgs[sarg->sigalgcnt - 1]) {
2495e71b7053SJung-uk Kim             sarg->sigalgcnt--;
2496e71b7053SJung-uk Kim             return 0;
2497e71b7053SJung-uk Kim         }
2498e71b7053SJung-uk Kim     }
24997bded2dbSJung-uk Kim     return 1;
25007bded2dbSJung-uk Kim }
25017bded2dbSJung-uk Kim 
25027bded2dbSJung-uk Kim /*
2503e71b7053SJung-uk Kim  * Set supported signature algorithms based on a colon separated list of the
25047bded2dbSJung-uk Kim  * form sig+hash e.g. RSA+SHA512:DSA+SHA512
25057bded2dbSJung-uk Kim  */
25067bded2dbSJung-uk Kim int tls1_set_sigalgs_list(CERT *c, const char *str, int client)
25077bded2dbSJung-uk Kim {
25087bded2dbSJung-uk Kim     sig_cb_st sig;
25097bded2dbSJung-uk Kim     sig.sigalgcnt = 0;
25107bded2dbSJung-uk Kim     if (!CONF_parse_list(str, ':', 1, sig_cb, &sig))
25117bded2dbSJung-uk Kim         return 0;
25127bded2dbSJung-uk Kim     if (c == NULL)
25137bded2dbSJung-uk Kim         return 1;
2514e71b7053SJung-uk Kim     return tls1_set_raw_sigalgs(c, sig.sigalgs, sig.sigalgcnt, client);
25157bded2dbSJung-uk Kim }
25167bded2dbSJung-uk Kim 
2517e71b7053SJung-uk Kim int tls1_set_raw_sigalgs(CERT *c, const uint16_t *psigs, size_t salglen,
25187bded2dbSJung-uk Kim                      int client)
25197bded2dbSJung-uk Kim {
2520e71b7053SJung-uk Kim     uint16_t *sigalgs;
25217bded2dbSJung-uk Kim 
2522e71b7053SJung-uk Kim     if ((sigalgs = OPENSSL_malloc(salglen * sizeof(*sigalgs))) == NULL) {
2523b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
2524e71b7053SJung-uk Kim         return 0;
25257bded2dbSJung-uk Kim     }
2526e71b7053SJung-uk Kim     memcpy(sigalgs, psigs, salglen * sizeof(*sigalgs));
25277bded2dbSJung-uk Kim 
25287bded2dbSJung-uk Kim     if (client) {
25297bded2dbSJung-uk Kim         OPENSSL_free(c->client_sigalgs);
25307bded2dbSJung-uk Kim         c->client_sigalgs = sigalgs;
25317bded2dbSJung-uk Kim         c->client_sigalgslen = salglen;
25327bded2dbSJung-uk Kim     } else {
25337bded2dbSJung-uk Kim         OPENSSL_free(c->conf_sigalgs);
25347bded2dbSJung-uk Kim         c->conf_sigalgs = sigalgs;
25357bded2dbSJung-uk Kim         c->conf_sigalgslen = salglen;
25367bded2dbSJung-uk Kim     }
25377bded2dbSJung-uk Kim 
25387bded2dbSJung-uk Kim     return 1;
2539e71b7053SJung-uk Kim }
2540e71b7053SJung-uk Kim 
2541e71b7053SJung-uk Kim int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client)
2542e71b7053SJung-uk Kim {
2543e71b7053SJung-uk Kim     uint16_t *sigalgs, *sptr;
2544e71b7053SJung-uk Kim     size_t i;
2545e71b7053SJung-uk Kim 
2546e71b7053SJung-uk Kim     if (salglen & 1)
2547e71b7053SJung-uk Kim         return 0;
2548e71b7053SJung-uk Kim     if ((sigalgs = OPENSSL_malloc((salglen / 2) * sizeof(*sigalgs))) == NULL) {
2549b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
2550e71b7053SJung-uk Kim         return 0;
2551e71b7053SJung-uk Kim     }
2552e71b7053SJung-uk Kim     for (i = 0, sptr = sigalgs; i < salglen; i += 2) {
2553e71b7053SJung-uk Kim         size_t j;
2554e71b7053SJung-uk Kim         const SIGALG_LOOKUP *curr;
2555e71b7053SJung-uk Kim         int md_id = *psig_nids++;
2556e71b7053SJung-uk Kim         int sig_id = *psig_nids++;
2557e71b7053SJung-uk Kim 
2558e71b7053SJung-uk Kim         for (j = 0, curr = sigalg_lookup_tbl; j < OSSL_NELEM(sigalg_lookup_tbl);
2559e71b7053SJung-uk Kim              j++, curr++) {
2560e71b7053SJung-uk Kim             if (curr->hash == md_id && curr->sig == sig_id) {
2561e71b7053SJung-uk Kim                 *sptr++ = curr->sigalg;
2562e71b7053SJung-uk Kim                 break;
2563e71b7053SJung-uk Kim             }
2564e71b7053SJung-uk Kim         }
2565e71b7053SJung-uk Kim 
2566e71b7053SJung-uk Kim         if (j == OSSL_NELEM(sigalg_lookup_tbl))
2567e71b7053SJung-uk Kim             goto err;
2568e71b7053SJung-uk Kim     }
2569e71b7053SJung-uk Kim 
2570e71b7053SJung-uk Kim     if (client) {
2571e71b7053SJung-uk Kim         OPENSSL_free(c->client_sigalgs);
2572e71b7053SJung-uk Kim         c->client_sigalgs = sigalgs;
2573e71b7053SJung-uk Kim         c->client_sigalgslen = salglen / 2;
2574e71b7053SJung-uk Kim     } else {
2575e71b7053SJung-uk Kim         OPENSSL_free(c->conf_sigalgs);
2576e71b7053SJung-uk Kim         c->conf_sigalgs = sigalgs;
2577e71b7053SJung-uk Kim         c->conf_sigalgslen = salglen / 2;
2578e71b7053SJung-uk Kim     }
2579e71b7053SJung-uk Kim 
2580e71b7053SJung-uk Kim     return 1;
25817bded2dbSJung-uk Kim 
25827bded2dbSJung-uk Kim  err:
25837bded2dbSJung-uk Kim     OPENSSL_free(sigalgs);
25847bded2dbSJung-uk Kim     return 0;
25857bded2dbSJung-uk Kim }
25867bded2dbSJung-uk Kim 
2587da327cd2SJung-uk Kim static int tls1_check_sig_alg(SSL *s, X509 *x, int default_nid)
25887bded2dbSJung-uk Kim {
2589da327cd2SJung-uk Kim     int sig_nid, use_pc_sigalgs = 0;
25907bded2dbSJung-uk Kim     size_t i;
2591da327cd2SJung-uk Kim     const SIGALG_LOOKUP *sigalg;
2592da327cd2SJung-uk Kim     size_t sigalgslen;
25937bded2dbSJung-uk Kim     if (default_nid == -1)
25947bded2dbSJung-uk Kim         return 1;
25957bded2dbSJung-uk Kim     sig_nid = X509_get_signature_nid(x);
25967bded2dbSJung-uk Kim     if (default_nid)
25977bded2dbSJung-uk Kim         return sig_nid == default_nid ? 1 : 0;
2598da327cd2SJung-uk Kim 
2599b077aed3SPierre Pronchery     if (SSL_IS_TLS13(s) && s->s3.tmp.peer_cert_sigalgs != NULL) {
2600da327cd2SJung-uk Kim         /*
2601da327cd2SJung-uk Kim          * If we're in TLSv1.3 then we only get here if we're checking the
2602da327cd2SJung-uk Kim          * chain. If the peer has specified peer_cert_sigalgs then we use them
2603da327cd2SJung-uk Kim          * otherwise we default to normal sigalgs.
2604da327cd2SJung-uk Kim          */
2605b077aed3SPierre Pronchery         sigalgslen = s->s3.tmp.peer_cert_sigalgslen;
2606da327cd2SJung-uk Kim         use_pc_sigalgs = 1;
2607da327cd2SJung-uk Kim     } else {
2608da327cd2SJung-uk Kim         sigalgslen = s->shared_sigalgslen;
2609da327cd2SJung-uk Kim     }
2610da327cd2SJung-uk Kim     for (i = 0; i < sigalgslen; i++) {
2611da327cd2SJung-uk Kim         sigalg = use_pc_sigalgs
2612b077aed3SPierre Pronchery                  ? tls1_lookup_sigalg(s, s->s3.tmp.peer_cert_sigalgs[i])
2613da327cd2SJung-uk Kim                  : s->shared_sigalgs[i];
2614c79d631aSGordon Tetlow         if (sigalg != NULL && sig_nid == sigalg->sigandhash)
26157bded2dbSJung-uk Kim             return 1;
2616da327cd2SJung-uk Kim     }
26177bded2dbSJung-uk Kim     return 0;
26187bded2dbSJung-uk Kim }
26197bded2dbSJung-uk Kim 
26207bded2dbSJung-uk Kim /* Check to see if a certificate issuer name matches list of CA names */
26217bded2dbSJung-uk Kim static int ssl_check_ca_name(STACK_OF(X509_NAME) *names, X509 *x)
26227bded2dbSJung-uk Kim {
2623b077aed3SPierre Pronchery     const X509_NAME *nm;
26247bded2dbSJung-uk Kim     int i;
26257bded2dbSJung-uk Kim     nm = X509_get_issuer_name(x);
26267bded2dbSJung-uk Kim     for (i = 0; i < sk_X509_NAME_num(names); i++) {
26277bded2dbSJung-uk Kim         if (!X509_NAME_cmp(nm, sk_X509_NAME_value(names, i)))
26287bded2dbSJung-uk Kim             return 1;
26297bded2dbSJung-uk Kim     }
26307bded2dbSJung-uk Kim     return 0;
26317bded2dbSJung-uk Kim }
26327bded2dbSJung-uk Kim 
26337bded2dbSJung-uk Kim /*
26347bded2dbSJung-uk Kim  * Check certificate chain is consistent with TLS extensions and is usable by
26357bded2dbSJung-uk Kim  * server. This servers two purposes: it allows users to check chains before
26367bded2dbSJung-uk Kim  * passing them to the server and it allows the server to check chains before
26377bded2dbSJung-uk Kim  * attempting to use them.
26387bded2dbSJung-uk Kim  */
26397bded2dbSJung-uk Kim 
2640e71b7053SJung-uk Kim /* Flags which need to be set for a certificate when strict mode not set */
26417bded2dbSJung-uk Kim 
26427bded2dbSJung-uk Kim #define CERT_PKEY_VALID_FLAGS \
26437bded2dbSJung-uk Kim         (CERT_PKEY_EE_SIGNATURE|CERT_PKEY_EE_PARAM)
26447bded2dbSJung-uk Kim /* Strict mode flags */
26457bded2dbSJung-uk Kim #define CERT_PKEY_STRICT_FLAGS \
26467bded2dbSJung-uk Kim          (CERT_PKEY_VALID_FLAGS|CERT_PKEY_CA_SIGNATURE|CERT_PKEY_CA_PARAM \
26477bded2dbSJung-uk Kim          | CERT_PKEY_ISSUER_NAME|CERT_PKEY_CERT_TYPE)
26487bded2dbSJung-uk Kim 
26497bded2dbSJung-uk Kim int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
26507bded2dbSJung-uk Kim                      int idx)
26517bded2dbSJung-uk Kim {
26527bded2dbSJung-uk Kim     int i;
26537bded2dbSJung-uk Kim     int rv = 0;
26547bded2dbSJung-uk Kim     int check_flags = 0, strict_mode;
26557bded2dbSJung-uk Kim     CERT_PKEY *cpk = NULL;
26567bded2dbSJung-uk Kim     CERT *c = s->cert;
2657e71b7053SJung-uk Kim     uint32_t *pvalid;
26587bded2dbSJung-uk Kim     unsigned int suiteb_flags = tls1_suiteb(s);
26597bded2dbSJung-uk Kim     /* idx == -1 means checking server chains */
26607bded2dbSJung-uk Kim     if (idx != -1) {
26617bded2dbSJung-uk Kim         /* idx == -2 means checking client certificate chains */
26627bded2dbSJung-uk Kim         if (idx == -2) {
26637bded2dbSJung-uk Kim             cpk = c->key;
2664e71b7053SJung-uk Kim             idx = (int)(cpk - c->pkeys);
26657bded2dbSJung-uk Kim         } else
26667bded2dbSJung-uk Kim             cpk = c->pkeys + idx;
2667b077aed3SPierre Pronchery         pvalid = s->s3.tmp.valid_flags + idx;
26687bded2dbSJung-uk Kim         x = cpk->x509;
26697bded2dbSJung-uk Kim         pk = cpk->privatekey;
26707bded2dbSJung-uk Kim         chain = cpk->chain;
26717bded2dbSJung-uk Kim         strict_mode = c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT;
26727bded2dbSJung-uk Kim         /* If no cert or key, forget it */
26737bded2dbSJung-uk Kim         if (!x || !pk)
26747bded2dbSJung-uk Kim             goto end;
26757bded2dbSJung-uk Kim     } else {
2676e71b7053SJung-uk Kim         size_t certidx;
2677e71b7053SJung-uk Kim 
26787bded2dbSJung-uk Kim         if (!x || !pk)
26797bded2dbSJung-uk Kim             return 0;
2680e71b7053SJung-uk Kim 
2681e71b7053SJung-uk Kim         if (ssl_cert_lookup_by_pkey(pk, &certidx) == NULL)
26827bded2dbSJung-uk Kim             return 0;
2683e71b7053SJung-uk Kim         idx = certidx;
2684b077aed3SPierre Pronchery         pvalid = s->s3.tmp.valid_flags + idx;
2685e71b7053SJung-uk Kim 
26867bded2dbSJung-uk Kim         if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)
26877bded2dbSJung-uk Kim             check_flags = CERT_PKEY_STRICT_FLAGS;
26887bded2dbSJung-uk Kim         else
26897bded2dbSJung-uk Kim             check_flags = CERT_PKEY_VALID_FLAGS;
26907bded2dbSJung-uk Kim         strict_mode = 1;
26917bded2dbSJung-uk Kim     }
26927bded2dbSJung-uk Kim 
26937bded2dbSJung-uk Kim     if (suiteb_flags) {
26947bded2dbSJung-uk Kim         int ok;
26957bded2dbSJung-uk Kim         if (check_flags)
26967bded2dbSJung-uk Kim             check_flags |= CERT_PKEY_SUITEB;
26977bded2dbSJung-uk Kim         ok = X509_chain_check_suiteb(NULL, x, chain, suiteb_flags);
26987bded2dbSJung-uk Kim         if (ok == X509_V_OK)
26997bded2dbSJung-uk Kim             rv |= CERT_PKEY_SUITEB;
27007bded2dbSJung-uk Kim         else if (!check_flags)
27017bded2dbSJung-uk Kim             goto end;
27027bded2dbSJung-uk Kim     }
27037bded2dbSJung-uk Kim 
27047bded2dbSJung-uk Kim     /*
27057bded2dbSJung-uk Kim      * Check all signature algorithms are consistent with signature
27067bded2dbSJung-uk Kim      * algorithms extension if TLS 1.2 or later and strict mode.
27077bded2dbSJung-uk Kim      */
27087bded2dbSJung-uk Kim     if (TLS1_get_version(s) >= TLS1_2_VERSION && strict_mode) {
27097bded2dbSJung-uk Kim         int default_nid;
2710e71b7053SJung-uk Kim         int rsign = 0;
2711b077aed3SPierre Pronchery         if (s->s3.tmp.peer_cert_sigalgs != NULL
2712b077aed3SPierre Pronchery                 || s->s3.tmp.peer_sigalgs != NULL) {
27137bded2dbSJung-uk Kim             default_nid = 0;
27147bded2dbSJung-uk Kim         /* If no sigalgs extension use defaults from RFC5246 */
2715e71b7053SJung-uk Kim         } else {
27167bded2dbSJung-uk Kim             switch (idx) {
2717e71b7053SJung-uk Kim             case SSL_PKEY_RSA:
2718e71b7053SJung-uk Kim                 rsign = EVP_PKEY_RSA;
27197bded2dbSJung-uk Kim                 default_nid = NID_sha1WithRSAEncryption;
27207bded2dbSJung-uk Kim                 break;
27217bded2dbSJung-uk Kim 
27227bded2dbSJung-uk Kim             case SSL_PKEY_DSA_SIGN:
2723e71b7053SJung-uk Kim                 rsign = EVP_PKEY_DSA;
27247bded2dbSJung-uk Kim                 default_nid = NID_dsaWithSHA1;
27257bded2dbSJung-uk Kim                 break;
27267bded2dbSJung-uk Kim 
27277bded2dbSJung-uk Kim             case SSL_PKEY_ECC:
2728e71b7053SJung-uk Kim                 rsign = EVP_PKEY_EC;
27297bded2dbSJung-uk Kim                 default_nid = NID_ecdsa_with_SHA1;
27307bded2dbSJung-uk Kim                 break;
27317bded2dbSJung-uk Kim 
2732e71b7053SJung-uk Kim             case SSL_PKEY_GOST01:
2733e71b7053SJung-uk Kim                 rsign = NID_id_GostR3410_2001;
2734e71b7053SJung-uk Kim                 default_nid = NID_id_GostR3411_94_with_GostR3410_2001;
2735e71b7053SJung-uk Kim                 break;
2736e71b7053SJung-uk Kim 
2737e71b7053SJung-uk Kim             case SSL_PKEY_GOST12_256:
2738e71b7053SJung-uk Kim                 rsign = NID_id_GostR3410_2012_256;
2739e71b7053SJung-uk Kim                 default_nid = NID_id_tc26_signwithdigest_gost3410_2012_256;
2740e71b7053SJung-uk Kim                 break;
2741e71b7053SJung-uk Kim 
2742e71b7053SJung-uk Kim             case SSL_PKEY_GOST12_512:
2743e71b7053SJung-uk Kim                 rsign = NID_id_GostR3410_2012_512;
2744e71b7053SJung-uk Kim                 default_nid = NID_id_tc26_signwithdigest_gost3410_2012_512;
2745e71b7053SJung-uk Kim                 break;
2746e71b7053SJung-uk Kim 
27477bded2dbSJung-uk Kim             default:
27487bded2dbSJung-uk Kim                 default_nid = -1;
27497bded2dbSJung-uk Kim                 break;
27507bded2dbSJung-uk Kim             }
27517bded2dbSJung-uk Kim         }
27527bded2dbSJung-uk Kim         /*
27537bded2dbSJung-uk Kim          * If peer sent no signature algorithms extension and we have set
27547bded2dbSJung-uk Kim          * preferred signature algorithms check we support sha1.
27557bded2dbSJung-uk Kim          */
27567bded2dbSJung-uk Kim         if (default_nid > 0 && c->conf_sigalgs) {
27577bded2dbSJung-uk Kim             size_t j;
2758e71b7053SJung-uk Kim             const uint16_t *p = c->conf_sigalgs;
2759e71b7053SJung-uk Kim             for (j = 0; j < c->conf_sigalgslen; j++, p++) {
2760b077aed3SPierre Pronchery                 const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *p);
2761e71b7053SJung-uk Kim 
2762e71b7053SJung-uk Kim                 if (lu != NULL && lu->hash == NID_sha1 && lu->sig == rsign)
27637bded2dbSJung-uk Kim                     break;
27647bded2dbSJung-uk Kim             }
27657bded2dbSJung-uk Kim             if (j == c->conf_sigalgslen) {
27667bded2dbSJung-uk Kim                 if (check_flags)
27677bded2dbSJung-uk Kim                     goto skip_sigs;
27687bded2dbSJung-uk Kim                 else
27697bded2dbSJung-uk Kim                     goto end;
27707bded2dbSJung-uk Kim             }
27717bded2dbSJung-uk Kim         }
27727bded2dbSJung-uk Kim         /* Check signature algorithm of each cert in chain */
2773da327cd2SJung-uk Kim         if (SSL_IS_TLS13(s)) {
2774da327cd2SJung-uk Kim             /*
2775da327cd2SJung-uk Kim              * We only get here if the application has called SSL_check_chain(),
2776da327cd2SJung-uk Kim              * so check_flags is always set.
2777da327cd2SJung-uk Kim              */
2778da327cd2SJung-uk Kim             if (find_sig_alg(s, x, pk) != NULL)
2779da327cd2SJung-uk Kim                 rv |= CERT_PKEY_EE_SIGNATURE;
2780da327cd2SJung-uk Kim         } else if (!tls1_check_sig_alg(s, x, default_nid)) {
27817bded2dbSJung-uk Kim             if (!check_flags)
27827bded2dbSJung-uk Kim                 goto end;
27837bded2dbSJung-uk Kim         } else
27847bded2dbSJung-uk Kim             rv |= CERT_PKEY_EE_SIGNATURE;
27857bded2dbSJung-uk Kim         rv |= CERT_PKEY_CA_SIGNATURE;
27867bded2dbSJung-uk Kim         for (i = 0; i < sk_X509_num(chain); i++) {
2787da327cd2SJung-uk Kim             if (!tls1_check_sig_alg(s, sk_X509_value(chain, i), default_nid)) {
27887bded2dbSJung-uk Kim                 if (check_flags) {
27897bded2dbSJung-uk Kim                     rv &= ~CERT_PKEY_CA_SIGNATURE;
27907bded2dbSJung-uk Kim                     break;
27917bded2dbSJung-uk Kim                 } else
27927bded2dbSJung-uk Kim                     goto end;
27937bded2dbSJung-uk Kim             }
27947bded2dbSJung-uk Kim         }
27957bded2dbSJung-uk Kim     }
27967bded2dbSJung-uk Kim     /* Else not TLS 1.2, so mark EE and CA signing algorithms OK */
27977bded2dbSJung-uk Kim     else if (check_flags)
27987bded2dbSJung-uk Kim         rv |= CERT_PKEY_EE_SIGNATURE | CERT_PKEY_CA_SIGNATURE;
27997bded2dbSJung-uk Kim  skip_sigs:
28007bded2dbSJung-uk Kim     /* Check cert parameters are consistent */
2801e71b7053SJung-uk Kim     if (tls1_check_cert_param(s, x, 1))
28027bded2dbSJung-uk Kim         rv |= CERT_PKEY_EE_PARAM;
28037bded2dbSJung-uk Kim     else if (!check_flags)
28047bded2dbSJung-uk Kim         goto end;
28057bded2dbSJung-uk Kim     if (!s->server)
28067bded2dbSJung-uk Kim         rv |= CERT_PKEY_CA_PARAM;
28077bded2dbSJung-uk Kim     /* In strict mode check rest of chain too */
28087bded2dbSJung-uk Kim     else if (strict_mode) {
28097bded2dbSJung-uk Kim         rv |= CERT_PKEY_CA_PARAM;
28107bded2dbSJung-uk Kim         for (i = 0; i < sk_X509_num(chain); i++) {
28117bded2dbSJung-uk Kim             X509 *ca = sk_X509_value(chain, i);
28127bded2dbSJung-uk Kim             if (!tls1_check_cert_param(s, ca, 0)) {
28137bded2dbSJung-uk Kim                 if (check_flags) {
28147bded2dbSJung-uk Kim                     rv &= ~CERT_PKEY_CA_PARAM;
28157bded2dbSJung-uk Kim                     break;
28167bded2dbSJung-uk Kim                 } else
28177bded2dbSJung-uk Kim                     goto end;
28187bded2dbSJung-uk Kim             }
28197bded2dbSJung-uk Kim         }
28207bded2dbSJung-uk Kim     }
28217bded2dbSJung-uk Kim     if (!s->server && strict_mode) {
28227bded2dbSJung-uk Kim         STACK_OF(X509_NAME) *ca_dn;
28237bded2dbSJung-uk Kim         int check_type = 0;
2824b077aed3SPierre Pronchery 
2825b077aed3SPierre Pronchery         if (EVP_PKEY_is_a(pk, "RSA"))
28267bded2dbSJung-uk Kim             check_type = TLS_CT_RSA_SIGN;
2827b077aed3SPierre Pronchery         else if (EVP_PKEY_is_a(pk, "DSA"))
28287bded2dbSJung-uk Kim             check_type = TLS_CT_DSS_SIGN;
2829b077aed3SPierre Pronchery         else if (EVP_PKEY_is_a(pk, "EC"))
28307bded2dbSJung-uk Kim             check_type = TLS_CT_ECDSA_SIGN;
2831b077aed3SPierre Pronchery 
28327bded2dbSJung-uk Kim         if (check_type) {
2833b077aed3SPierre Pronchery             const uint8_t *ctypes = s->s3.tmp.ctype;
2834e71b7053SJung-uk Kim             size_t j;
2835e71b7053SJung-uk Kim 
2836b077aed3SPierre Pronchery             for (j = 0; j < s->s3.tmp.ctype_len; j++, ctypes++) {
2837e71b7053SJung-uk Kim                 if (*ctypes == check_type) {
28387bded2dbSJung-uk Kim                     rv |= CERT_PKEY_CERT_TYPE;
28397bded2dbSJung-uk Kim                     break;
28407bded2dbSJung-uk Kim                 }
28417bded2dbSJung-uk Kim             }
28427bded2dbSJung-uk Kim             if (!(rv & CERT_PKEY_CERT_TYPE) && !check_flags)
28437bded2dbSJung-uk Kim                 goto end;
2844e71b7053SJung-uk Kim         } else {
28457bded2dbSJung-uk Kim             rv |= CERT_PKEY_CERT_TYPE;
2846e71b7053SJung-uk Kim         }
28477bded2dbSJung-uk Kim 
2848b077aed3SPierre Pronchery         ca_dn = s->s3.tmp.peer_ca_names;
28497bded2dbSJung-uk Kim 
285083eaf7aeSJung-uk Kim         if (ca_dn == NULL
285183eaf7aeSJung-uk Kim             || sk_X509_NAME_num(ca_dn) == 0
285283eaf7aeSJung-uk Kim             || ssl_check_ca_name(ca_dn, x))
28537bded2dbSJung-uk Kim             rv |= CERT_PKEY_ISSUER_NAME;
285483eaf7aeSJung-uk Kim         else
28557bded2dbSJung-uk Kim             for (i = 0; i < sk_X509_num(chain); i++) {
28567bded2dbSJung-uk Kim                 X509 *xtmp = sk_X509_value(chain, i);
285783eaf7aeSJung-uk Kim 
28587bded2dbSJung-uk Kim                 if (ssl_check_ca_name(ca_dn, xtmp)) {
28597bded2dbSJung-uk Kim                     rv |= CERT_PKEY_ISSUER_NAME;
28607bded2dbSJung-uk Kim                     break;
28617bded2dbSJung-uk Kim                 }
28627bded2dbSJung-uk Kim             }
286383eaf7aeSJung-uk Kim 
28647bded2dbSJung-uk Kim         if (!check_flags && !(rv & CERT_PKEY_ISSUER_NAME))
28657bded2dbSJung-uk Kim             goto end;
28667bded2dbSJung-uk Kim     } else
28677bded2dbSJung-uk Kim         rv |= CERT_PKEY_ISSUER_NAME | CERT_PKEY_CERT_TYPE;
28687bded2dbSJung-uk Kim 
28697bded2dbSJung-uk Kim     if (!check_flags || (rv & check_flags) == check_flags)
28707bded2dbSJung-uk Kim         rv |= CERT_PKEY_VALID;
28717bded2dbSJung-uk Kim 
28727bded2dbSJung-uk Kim  end:
28737bded2dbSJung-uk Kim 
2874e71b7053SJung-uk Kim     if (TLS1_get_version(s) >= TLS1_2_VERSION)
2875e71b7053SJung-uk Kim         rv |= *pvalid & (CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN);
2876e71b7053SJung-uk Kim     else
28777bded2dbSJung-uk Kim         rv |= CERT_PKEY_SIGN | CERT_PKEY_EXPLICIT_SIGN;
28787bded2dbSJung-uk Kim 
28797bded2dbSJung-uk Kim     /*
28807bded2dbSJung-uk Kim      * When checking a CERT_PKEY structure all flags are irrelevant if the
28817bded2dbSJung-uk Kim      * chain is invalid.
28827bded2dbSJung-uk Kim      */
28837bded2dbSJung-uk Kim     if (!check_flags) {
2884e71b7053SJung-uk Kim         if (rv & CERT_PKEY_VALID) {
2885e71b7053SJung-uk Kim             *pvalid = rv;
2886e71b7053SJung-uk Kim         } else {
2887e71b7053SJung-uk Kim             /* Preserve sign and explicit sign flag, clear rest */
2888e71b7053SJung-uk Kim             *pvalid &= CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN;
28897bded2dbSJung-uk Kim             return 0;
28907bded2dbSJung-uk Kim         }
28917bded2dbSJung-uk Kim     }
28927bded2dbSJung-uk Kim     return rv;
28937bded2dbSJung-uk Kim }
28947bded2dbSJung-uk Kim 
28957bded2dbSJung-uk Kim /* Set validity of certificates in an SSL structure */
28967bded2dbSJung-uk Kim void tls1_set_cert_validity(SSL *s)
28977bded2dbSJung-uk Kim {
2898e71b7053SJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA);
2899e71b7053SJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_PSS_SIGN);
29007bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DSA_SIGN);
29017bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ECC);
2902e71b7053SJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_GOST01);
2903e71b7053SJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_GOST12_256);
2904e71b7053SJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_GOST12_512);
2905e71b7053SJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ED25519);
2906e71b7053SJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ED448);
29077bded2dbSJung-uk Kim }
29087bded2dbSJung-uk Kim 
2909e71b7053SJung-uk Kim /* User level utility function to check a chain is suitable */
29107bded2dbSJung-uk Kim int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
29117bded2dbSJung-uk Kim {
29127bded2dbSJung-uk Kim     return tls1_check_chain(s, x, pk, chain, -1);
29137bded2dbSJung-uk Kim }
29147bded2dbSJung-uk Kim 
2915b077aed3SPierre Pronchery EVP_PKEY *ssl_get_auto_dh(SSL *s)
2916e71b7053SJung-uk Kim {
2917b077aed3SPierre Pronchery     EVP_PKEY *dhp = NULL;
2918b077aed3SPierre Pronchery     BIGNUM *p;
29199a3ae0cdSJung-uk Kim     int dh_secbits = 80, sec_level_bits;
2920b077aed3SPierre Pronchery     EVP_PKEY_CTX *pctx = NULL;
2921b077aed3SPierre Pronchery     OSSL_PARAM_BLD *tmpl = NULL;
2922b077aed3SPierre Pronchery     OSSL_PARAM *params = NULL;
29239a3ae0cdSJung-uk Kim 
292458f35182SJung-uk Kim     if (s->cert->dh_tmp_auto != 2) {
2925b077aed3SPierre Pronchery         if (s->s3.tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aPSK)) {
2926b077aed3SPierre Pronchery             if (s->s3.tmp.new_cipher->strength_bits == 256)
2927e71b7053SJung-uk Kim                 dh_secbits = 128;
2928e71b7053SJung-uk Kim             else
2929e71b7053SJung-uk Kim                 dh_secbits = 80;
2930e71b7053SJung-uk Kim         } else {
2931b077aed3SPierre Pronchery             if (s->s3.tmp.cert == NULL)
2932e71b7053SJung-uk Kim                 return NULL;
2933b077aed3SPierre Pronchery             dh_secbits = EVP_PKEY_get_security_bits(s->s3.tmp.cert->privatekey);
2934e71b7053SJung-uk Kim         }
293558f35182SJung-uk Kim     }
2936e71b7053SJung-uk Kim 
29379a3ae0cdSJung-uk Kim     /* Do not pick a prime that is too weak for the current security level */
29389a3ae0cdSJung-uk Kim     sec_level_bits = ssl_get_security_level_bits(s, NULL, NULL);
29399a3ae0cdSJung-uk Kim     if (dh_secbits < sec_level_bits)
29409a3ae0cdSJung-uk Kim         dh_secbits = sec_level_bits;
29419a3ae0cdSJung-uk Kim 
2942e71b7053SJung-uk Kim     if (dh_secbits >= 192)
2943e71b7053SJung-uk Kim         p = BN_get_rfc3526_prime_8192(NULL);
294458f35182SJung-uk Kim     else if (dh_secbits >= 152)
294558f35182SJung-uk Kim         p = BN_get_rfc3526_prime_4096(NULL);
294658f35182SJung-uk Kim     else if (dh_secbits >= 128)
2947e71b7053SJung-uk Kim         p = BN_get_rfc3526_prime_3072(NULL);
294858f35182SJung-uk Kim     else if (dh_secbits >= 112)
294958f35182SJung-uk Kim         p = BN_get_rfc3526_prime_2048(NULL);
295058f35182SJung-uk Kim     else
295158f35182SJung-uk Kim         p = BN_get_rfc2409_prime_1024(NULL);
2952b077aed3SPierre Pronchery     if (p == NULL)
2953b077aed3SPierre Pronchery         goto err;
2954b077aed3SPierre Pronchery 
2955b077aed3SPierre Pronchery     pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, "DH", s->ctx->propq);
2956b077aed3SPierre Pronchery     if (pctx == NULL
2957b077aed3SPierre Pronchery             || EVP_PKEY_fromdata_init(pctx) != 1)
2958b077aed3SPierre Pronchery         goto err;
2959b077aed3SPierre Pronchery 
2960b077aed3SPierre Pronchery     tmpl = OSSL_PARAM_BLD_new();
2961b077aed3SPierre Pronchery     if (tmpl == NULL
2962b077aed3SPierre Pronchery             || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p)
2963b077aed3SPierre Pronchery             || !OSSL_PARAM_BLD_push_uint(tmpl, OSSL_PKEY_PARAM_FFC_G, 2))
2964b077aed3SPierre Pronchery         goto err;
2965b077aed3SPierre Pronchery 
2966b077aed3SPierre Pronchery     params = OSSL_PARAM_BLD_to_param(tmpl);
2967b077aed3SPierre Pronchery     if (params == NULL
2968b077aed3SPierre Pronchery             || EVP_PKEY_fromdata(pctx, &dhp, EVP_PKEY_KEY_PARAMETERS, params) != 1)
2969b077aed3SPierre Pronchery         goto err;
2970b077aed3SPierre Pronchery 
2971b077aed3SPierre Pronchery err:
2972b077aed3SPierre Pronchery     OSSL_PARAM_free(params);
2973b077aed3SPierre Pronchery     OSSL_PARAM_BLD_free(tmpl);
2974b077aed3SPierre Pronchery     EVP_PKEY_CTX_free(pctx);
2975e71b7053SJung-uk Kim     BN_free(p);
2976e71b7053SJung-uk Kim     return dhp;
2977e71b7053SJung-uk Kim }
2978e71b7053SJung-uk Kim 
2979e71b7053SJung-uk Kim static int ssl_security_cert_key(SSL *s, SSL_CTX *ctx, X509 *x, int op)
2980e71b7053SJung-uk Kim {
2981e71b7053SJung-uk Kim     int secbits = -1;
2982e71b7053SJung-uk Kim     EVP_PKEY *pkey = X509_get0_pubkey(x);
2983e71b7053SJung-uk Kim     if (pkey) {
2984e71b7053SJung-uk Kim         /*
2985e71b7053SJung-uk Kim          * If no parameters this will return -1 and fail using the default
2986e71b7053SJung-uk Kim          * security callback for any non-zero security level. This will
2987e71b7053SJung-uk Kim          * reject keys which omit parameters but this only affects DSA and
2988e71b7053SJung-uk Kim          * omission of parameters is never (?) done in practice.
2989e71b7053SJung-uk Kim          */
2990b077aed3SPierre Pronchery         secbits = EVP_PKEY_get_security_bits(pkey);
2991e71b7053SJung-uk Kim     }
2992e71b7053SJung-uk Kim     if (s)
2993e71b7053SJung-uk Kim         return ssl_security(s, op, secbits, 0, x);
2994e71b7053SJung-uk Kim     else
2995e71b7053SJung-uk Kim         return ssl_ctx_security(ctx, op, secbits, 0, x);
2996e71b7053SJung-uk Kim }
2997e71b7053SJung-uk Kim 
2998e71b7053SJung-uk Kim static int ssl_security_cert_sig(SSL *s, SSL_CTX *ctx, X509 *x, int op)
2999e71b7053SJung-uk Kim {
3000e71b7053SJung-uk Kim     /* Lookup signature algorithm digest */
3001e71b7053SJung-uk Kim     int secbits, nid, pknid;
3002e71b7053SJung-uk Kim     /* Don't check signature if self signed */
3003e71b7053SJung-uk Kim     if ((X509_get_extension_flags(x) & EXFLAG_SS) != 0)
3004e71b7053SJung-uk Kim         return 1;
3005e71b7053SJung-uk Kim     if (!X509_get_signature_info(x, &nid, &pknid, &secbits, NULL))
3006e71b7053SJung-uk Kim         secbits = -1;
3007e71b7053SJung-uk Kim     /* If digest NID not defined use signature NID */
3008e71b7053SJung-uk Kim     if (nid == NID_undef)
3009e71b7053SJung-uk Kim         nid = pknid;
3010e71b7053SJung-uk Kim     if (s)
3011e71b7053SJung-uk Kim         return ssl_security(s, op, secbits, nid, x);
3012e71b7053SJung-uk Kim     else
3013e71b7053SJung-uk Kim         return ssl_ctx_security(ctx, op, secbits, nid, x);
3014e71b7053SJung-uk Kim }
3015e71b7053SJung-uk Kim 
3016e71b7053SJung-uk Kim int ssl_security_cert(SSL *s, SSL_CTX *ctx, X509 *x, int vfy, int is_ee)
3017e71b7053SJung-uk Kim {
3018e71b7053SJung-uk Kim     if (vfy)
3019e71b7053SJung-uk Kim         vfy = SSL_SECOP_PEER;
3020e71b7053SJung-uk Kim     if (is_ee) {
3021e71b7053SJung-uk Kim         if (!ssl_security_cert_key(s, ctx, x, SSL_SECOP_EE_KEY | vfy))
3022e71b7053SJung-uk Kim             return SSL_R_EE_KEY_TOO_SMALL;
3023e71b7053SJung-uk Kim     } else {
3024e71b7053SJung-uk Kim         if (!ssl_security_cert_key(s, ctx, x, SSL_SECOP_CA_KEY | vfy))
3025e71b7053SJung-uk Kim             return SSL_R_CA_KEY_TOO_SMALL;
3026e71b7053SJung-uk Kim     }
3027e71b7053SJung-uk Kim     if (!ssl_security_cert_sig(s, ctx, x, SSL_SECOP_CA_MD | vfy))
3028e71b7053SJung-uk Kim         return SSL_R_CA_MD_TOO_WEAK;
3029e71b7053SJung-uk Kim     return 1;
3030e71b7053SJung-uk Kim }
3031e71b7053SJung-uk Kim 
3032e71b7053SJung-uk Kim /*
3033e71b7053SJung-uk Kim  * Check security of a chain, if |sk| includes the end entity certificate then
3034e71b7053SJung-uk Kim  * |x| is NULL. If |vfy| is 1 then we are verifying a peer chain and not sending
3035e71b7053SJung-uk Kim  * one to the peer. Return values: 1 if ok otherwise error code to use
3036e71b7053SJung-uk Kim  */
3037e71b7053SJung-uk Kim 
3038e71b7053SJung-uk Kim int ssl_security_cert_chain(SSL *s, STACK_OF(X509) *sk, X509 *x, int vfy)
3039e71b7053SJung-uk Kim {
3040e71b7053SJung-uk Kim     int rv, start_idx, i;
3041e71b7053SJung-uk Kim     if (x == NULL) {
3042e71b7053SJung-uk Kim         x = sk_X509_value(sk, 0);
304383eaf7aeSJung-uk Kim         if (x == NULL)
304483eaf7aeSJung-uk Kim             return ERR_R_INTERNAL_ERROR;
3045e71b7053SJung-uk Kim         start_idx = 1;
3046e71b7053SJung-uk Kim     } else
3047e71b7053SJung-uk Kim         start_idx = 0;
3048e71b7053SJung-uk Kim 
3049e71b7053SJung-uk Kim     rv = ssl_security_cert(s, NULL, x, vfy, 1);
3050e71b7053SJung-uk Kim     if (rv != 1)
3051e71b7053SJung-uk Kim         return rv;
3052e71b7053SJung-uk Kim 
3053e71b7053SJung-uk Kim     for (i = start_idx; i < sk_X509_num(sk); i++) {
3054e71b7053SJung-uk Kim         x = sk_X509_value(sk, i);
3055e71b7053SJung-uk Kim         rv = ssl_security_cert(s, NULL, x, vfy, 0);
3056e71b7053SJung-uk Kim         if (rv != 1)
3057e71b7053SJung-uk Kim             return rv;
3058e71b7053SJung-uk Kim     }
3059e71b7053SJung-uk Kim     return 1;
3060e71b7053SJung-uk Kim }
3061e71b7053SJung-uk Kim 
3062e71b7053SJung-uk Kim /*
3063e71b7053SJung-uk Kim  * For TLS 1.2 servers check if we have a certificate which can be used
3064e71b7053SJung-uk Kim  * with the signature algorithm "lu" and return index of certificate.
3065e71b7053SJung-uk Kim  */
3066e71b7053SJung-uk Kim 
3067e71b7053SJung-uk Kim static int tls12_get_cert_sigalg_idx(const SSL *s, const SIGALG_LOOKUP *lu)
3068e71b7053SJung-uk Kim {
3069e71b7053SJung-uk Kim     int sig_idx = lu->sig_idx;
3070e71b7053SJung-uk Kim     const SSL_CERT_LOOKUP *clu = ssl_cert_lookup_by_idx(sig_idx);
3071e71b7053SJung-uk Kim 
3072e71b7053SJung-uk Kim     /* If not recognised or not supported by cipher mask it is not suitable */
3073e71b7053SJung-uk Kim     if (clu == NULL
3074b077aed3SPierre Pronchery             || (clu->amask & s->s3.tmp.new_cipher->algorithm_auth) == 0
3075e71b7053SJung-uk Kim             || (clu->nid == EVP_PKEY_RSA_PSS
3076b077aed3SPierre Pronchery                 && (s->s3.tmp.new_cipher->algorithm_mkey & SSL_kRSA) != 0))
3077e71b7053SJung-uk Kim         return -1;
3078e71b7053SJung-uk Kim 
3079b077aed3SPierre Pronchery     return s->s3.tmp.valid_flags[sig_idx] & CERT_PKEY_VALID ? sig_idx : -1;
3080e71b7053SJung-uk Kim }
3081e71b7053SJung-uk Kim 
3082e71b7053SJung-uk Kim /*
3083da327cd2SJung-uk Kim  * Checks the given cert against signature_algorithm_cert restrictions sent by
3084da327cd2SJung-uk Kim  * the peer (if any) as well as whether the hash from the sigalg is usable with
3085da327cd2SJung-uk Kim  * the key.
3086da327cd2SJung-uk Kim  * Returns true if the cert is usable and false otherwise.
3087e71b7053SJung-uk Kim  */
3088da327cd2SJung-uk Kim static int check_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x,
3089da327cd2SJung-uk Kim                              EVP_PKEY *pkey)
3090e71b7053SJung-uk Kim {
3091e71b7053SJung-uk Kim     const SIGALG_LOOKUP *lu;
3092b077aed3SPierre Pronchery     int mdnid, pknid, supported;
3093e71b7053SJung-uk Kim     size_t i;
3094b077aed3SPierre Pronchery     const char *mdname = NULL;
3095e71b7053SJung-uk Kim 
3096b077aed3SPierre Pronchery     /*
3097b077aed3SPierre Pronchery      * If the given EVP_PKEY cannot support signing with this digest,
3098b077aed3SPierre Pronchery      * the answer is simply 'no'.
3099b077aed3SPierre Pronchery      */
3100b077aed3SPierre Pronchery     if (sig->hash != NID_undef)
3101b077aed3SPierre Pronchery         mdname = OBJ_nid2sn(sig->hash);
3102b077aed3SPierre Pronchery     supported = EVP_PKEY_digestsign_supports_digest(pkey, s->ctx->libctx,
3103b077aed3SPierre Pronchery                                                     mdname,
3104b077aed3SPierre Pronchery                                                     s->ctx->propq);
3105b077aed3SPierre Pronchery     if (supported <= 0)
3106da327cd2SJung-uk Kim         return 0;
3107da327cd2SJung-uk Kim 
3108e71b7053SJung-uk Kim     /*
3109b077aed3SPierre Pronchery      * The TLS 1.3 signature_algorithms_cert extension places restrictions
3110b077aed3SPierre Pronchery      * on the sigalg with which the certificate was signed (by its issuer).
3111b077aed3SPierre Pronchery      */
3112b077aed3SPierre Pronchery     if (s->s3.tmp.peer_cert_sigalgs != NULL) {
3113b077aed3SPierre Pronchery         if (!X509_get_signature_info(x, &mdnid, &pknid, NULL, NULL))
3114b077aed3SPierre Pronchery             return 0;
3115b077aed3SPierre Pronchery         for (i = 0; i < s->s3.tmp.peer_cert_sigalgslen; i++) {
3116b077aed3SPierre Pronchery             lu = tls1_lookup_sigalg(s, s->s3.tmp.peer_cert_sigalgs[i]);
3117b077aed3SPierre Pronchery             if (lu == NULL)
3118b077aed3SPierre Pronchery                 continue;
3119b077aed3SPierre Pronchery 
3120b077aed3SPierre Pronchery             /*
3121b077aed3SPierre Pronchery              * This does not differentiate between the
3122e71b7053SJung-uk Kim              * rsa_pss_pss_* and rsa_pss_rsae_* schemes since we do not
3123e71b7053SJung-uk Kim              * have a chain here that lets us look at the key OID in the
3124e71b7053SJung-uk Kim              * signing certificate.
3125e71b7053SJung-uk Kim              */
3126e71b7053SJung-uk Kim             if (mdnid == lu->hash && pknid == lu->sig)
3127e71b7053SJung-uk Kim                 return 1;
3128e71b7053SJung-uk Kim         }
3129e71b7053SJung-uk Kim         return 0;
3130e71b7053SJung-uk Kim     }
3131b077aed3SPierre Pronchery 
3132b077aed3SPierre Pronchery     /*
3133b077aed3SPierre Pronchery      * Without signat_algorithms_cert, any certificate for which we have
3134b077aed3SPierre Pronchery      * a viable public key is permitted.
3135b077aed3SPierre Pronchery      */
3136da327cd2SJung-uk Kim     return 1;
3137da327cd2SJung-uk Kim }
3138da327cd2SJung-uk Kim 
3139da327cd2SJung-uk Kim /*
3140da327cd2SJung-uk Kim  * Returns true if |s| has a usable certificate configured for use
3141da327cd2SJung-uk Kim  * with signature scheme |sig|.
3142da327cd2SJung-uk Kim  * "Usable" includes a check for presence as well as applying
3143da327cd2SJung-uk Kim  * the signature_algorithm_cert restrictions sent by the peer (if any).
3144da327cd2SJung-uk Kim  * Returns false if no usable certificate is found.
3145da327cd2SJung-uk Kim  */
3146da327cd2SJung-uk Kim static int has_usable_cert(SSL *s, const SIGALG_LOOKUP *sig, int idx)
3147da327cd2SJung-uk Kim {
3148da327cd2SJung-uk Kim     /* TLS 1.2 callers can override sig->sig_idx, but not TLS 1.3 callers. */
3149da327cd2SJung-uk Kim     if (idx == -1)
3150da327cd2SJung-uk Kim         idx = sig->sig_idx;
3151da327cd2SJung-uk Kim     if (!ssl_has_cert(s, idx))
3152da327cd2SJung-uk Kim         return 0;
3153da327cd2SJung-uk Kim 
3154da327cd2SJung-uk Kim     return check_cert_usable(s, sig, s->cert->pkeys[idx].x509,
3155da327cd2SJung-uk Kim                              s->cert->pkeys[idx].privatekey);
3156da327cd2SJung-uk Kim }
3157da327cd2SJung-uk Kim 
3158da327cd2SJung-uk Kim /*
3159da327cd2SJung-uk Kim  * Returns true if the supplied cert |x| and key |pkey| is usable with the
3160da327cd2SJung-uk Kim  * specified signature scheme |sig|, or false otherwise.
3161da327cd2SJung-uk Kim  */
3162da327cd2SJung-uk Kim static int is_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x,
3163da327cd2SJung-uk Kim                           EVP_PKEY *pkey)
3164da327cd2SJung-uk Kim {
3165da327cd2SJung-uk Kim     size_t idx;
3166da327cd2SJung-uk Kim 
3167da327cd2SJung-uk Kim     if (ssl_cert_lookup_by_pkey(pkey, &idx) == NULL)
3168da327cd2SJung-uk Kim         return 0;
3169da327cd2SJung-uk Kim 
3170da327cd2SJung-uk Kim     /* Check the key is consistent with the sig alg */
3171da327cd2SJung-uk Kim     if ((int)idx != sig->sig_idx)
3172da327cd2SJung-uk Kim         return 0;
3173da327cd2SJung-uk Kim 
3174da327cd2SJung-uk Kim     return check_cert_usable(s, sig, x, pkey);
3175da327cd2SJung-uk Kim }
3176da327cd2SJung-uk Kim 
3177da327cd2SJung-uk Kim /*
3178da327cd2SJung-uk Kim  * Find a signature scheme that works with the supplied certificate |x| and key
3179da327cd2SJung-uk Kim  * |pkey|. |x| and |pkey| may be NULL in which case we additionally look at our
3180da327cd2SJung-uk Kim  * available certs/keys to find one that works.
3181da327cd2SJung-uk Kim  */
3182da327cd2SJung-uk Kim static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey)
3183da327cd2SJung-uk Kim {
3184da327cd2SJung-uk Kim     const SIGALG_LOOKUP *lu = NULL;
3185da327cd2SJung-uk Kim     size_t i;
3186da327cd2SJung-uk Kim     int curve = -1;
3187da327cd2SJung-uk Kim     EVP_PKEY *tmppkey;
3188da327cd2SJung-uk Kim 
3189da327cd2SJung-uk Kim     /* Look for a shared sigalgs matching possible certificates */
3190da327cd2SJung-uk Kim     for (i = 0; i < s->shared_sigalgslen; i++) {
3191da327cd2SJung-uk Kim         lu = s->shared_sigalgs[i];
3192da327cd2SJung-uk Kim 
3193da327cd2SJung-uk Kim         /* Skip SHA1, SHA224, DSA and RSA if not PSS */
3194da327cd2SJung-uk Kim         if (lu->hash == NID_sha1
3195da327cd2SJung-uk Kim             || lu->hash == NID_sha224
3196da327cd2SJung-uk Kim             || lu->sig == EVP_PKEY_DSA
3197da327cd2SJung-uk Kim             || lu->sig == EVP_PKEY_RSA)
3198da327cd2SJung-uk Kim             continue;
3199da327cd2SJung-uk Kim         /* Check that we have a cert, and signature_algorithms_cert */
3200b077aed3SPierre Pronchery         if (!tls1_lookup_md(s->ctx, lu, NULL))
3201da327cd2SJung-uk Kim             continue;
3202da327cd2SJung-uk Kim         if ((pkey == NULL && !has_usable_cert(s, lu, -1))
3203da327cd2SJung-uk Kim                 || (pkey != NULL && !is_cert_usable(s, lu, x, pkey)))
3204da327cd2SJung-uk Kim             continue;
3205da327cd2SJung-uk Kim 
3206da327cd2SJung-uk Kim         tmppkey = (pkey != NULL) ? pkey
3207da327cd2SJung-uk Kim                                  : s->cert->pkeys[lu->sig_idx].privatekey;
3208da327cd2SJung-uk Kim 
3209da327cd2SJung-uk Kim         if (lu->sig == EVP_PKEY_EC) {
3210b077aed3SPierre Pronchery             if (curve == -1)
3211b077aed3SPierre Pronchery                 curve = ssl_get_EC_curve_nid(tmppkey);
3212da327cd2SJung-uk Kim             if (lu->curve != NID_undef && curve != lu->curve)
3213da327cd2SJung-uk Kim                 continue;
3214da327cd2SJung-uk Kim         } else if (lu->sig == EVP_PKEY_RSA_PSS) {
3215da327cd2SJung-uk Kim             /* validate that key is large enough for the signature algorithm */
3216b077aed3SPierre Pronchery             if (!rsa_pss_check_min_key_size(s->ctx, tmppkey, lu))
3217da327cd2SJung-uk Kim                 continue;
3218da327cd2SJung-uk Kim         }
3219da327cd2SJung-uk Kim         break;
3220da327cd2SJung-uk Kim     }
3221da327cd2SJung-uk Kim 
3222da327cd2SJung-uk Kim     if (i == s->shared_sigalgslen)
3223da327cd2SJung-uk Kim         return NULL;
3224da327cd2SJung-uk Kim 
3225da327cd2SJung-uk Kim     return lu;
3226e71b7053SJung-uk Kim }
3227e71b7053SJung-uk Kim 
3228e71b7053SJung-uk Kim /*
3229e71b7053SJung-uk Kim  * Choose an appropriate signature algorithm based on available certificates
3230e71b7053SJung-uk Kim  * Sets chosen certificate and signature algorithm.
3231e71b7053SJung-uk Kim  *
3232e71b7053SJung-uk Kim  * For servers if we fail to find a required certificate it is a fatal error,
3233e71b7053SJung-uk Kim  * an appropriate error code is set and a TLS alert is sent.
3234e71b7053SJung-uk Kim  *
3235e71b7053SJung-uk Kim  * For clients fatalerrs is set to 0. If a certificate is not suitable it is not
3236e71b7053SJung-uk Kim  * a fatal error: we will either try another certificate or not present one
3237e71b7053SJung-uk Kim  * to the server. In this case no error is set.
3238e71b7053SJung-uk Kim  */
3239e71b7053SJung-uk Kim int tls_choose_sigalg(SSL *s, int fatalerrs)
3240e71b7053SJung-uk Kim {
3241e71b7053SJung-uk Kim     const SIGALG_LOOKUP *lu = NULL;
3242e71b7053SJung-uk Kim     int sig_idx = -1;
3243e71b7053SJung-uk Kim 
3244b077aed3SPierre Pronchery     s->s3.tmp.cert = NULL;
3245b077aed3SPierre Pronchery     s->s3.tmp.sigalg = NULL;
3246e71b7053SJung-uk Kim 
3247e71b7053SJung-uk Kim     if (SSL_IS_TLS13(s)) {
3248da327cd2SJung-uk Kim         lu = find_sig_alg(s, NULL, NULL);
3249da327cd2SJung-uk Kim         if (lu == NULL) {
3250e71b7053SJung-uk Kim             if (!fatalerrs)
3251e71b7053SJung-uk Kim                 return 1;
3252b077aed3SPierre Pronchery             SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
3253e71b7053SJung-uk Kim                      SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM);
3254e71b7053SJung-uk Kim             return 0;
3255e71b7053SJung-uk Kim         }
3256e71b7053SJung-uk Kim     } else {
3257e71b7053SJung-uk Kim         /* If ciphersuite doesn't require a cert nothing to do */
3258b077aed3SPierre Pronchery         if (!(s->s3.tmp.new_cipher->algorithm_auth & SSL_aCERT))
3259e71b7053SJung-uk Kim             return 1;
3260e71b7053SJung-uk Kim         if (!s->server && !ssl_has_cert(s, s->cert->key - s->cert->pkeys))
3261e71b7053SJung-uk Kim                 return 1;
3262e71b7053SJung-uk Kim 
3263e71b7053SJung-uk Kim         if (SSL_USE_SIGALGS(s)) {
3264e71b7053SJung-uk Kim             size_t i;
3265b077aed3SPierre Pronchery             if (s->s3.tmp.peer_sigalgs != NULL) {
3266b077aed3SPierre Pronchery                 int curve = -1;
3267e71b7053SJung-uk Kim 
3268e71b7053SJung-uk Kim                 /* For Suite B need to match signature algorithm to curve */
3269b077aed3SPierre Pronchery                 if (tls1_suiteb(s))
3270b077aed3SPierre Pronchery                     curve = ssl_get_EC_curve_nid(s->cert->pkeys[SSL_PKEY_ECC]
3271b077aed3SPierre Pronchery                                                  .privatekey);
3272e71b7053SJung-uk Kim 
3273e71b7053SJung-uk Kim                 /*
3274e71b7053SJung-uk Kim                  * Find highest preference signature algorithm matching
3275e71b7053SJung-uk Kim                  * cert type
3276e71b7053SJung-uk Kim                  */
3277da327cd2SJung-uk Kim                 for (i = 0; i < s->shared_sigalgslen; i++) {
3278da327cd2SJung-uk Kim                     lu = s->shared_sigalgs[i];
3279e71b7053SJung-uk Kim 
3280e71b7053SJung-uk Kim                     if (s->server) {
3281e71b7053SJung-uk Kim                         if ((sig_idx = tls12_get_cert_sigalg_idx(s, lu)) == -1)
3282e71b7053SJung-uk Kim                             continue;
3283e71b7053SJung-uk Kim                     } else {
3284e71b7053SJung-uk Kim                         int cc_idx = s->cert->key - s->cert->pkeys;
3285e71b7053SJung-uk Kim 
3286e71b7053SJung-uk Kim                         sig_idx = lu->sig_idx;
3287e71b7053SJung-uk Kim                         if (cc_idx != sig_idx)
3288e71b7053SJung-uk Kim                             continue;
3289e71b7053SJung-uk Kim                     }
3290e71b7053SJung-uk Kim                     /* Check that we have a cert, and sig_algs_cert */
3291e71b7053SJung-uk Kim                     if (!has_usable_cert(s, lu, sig_idx))
3292e71b7053SJung-uk Kim                         continue;
3293e71b7053SJung-uk Kim                     if (lu->sig == EVP_PKEY_RSA_PSS) {
3294e71b7053SJung-uk Kim                         /* validate that key is large enough for the signature algorithm */
3295e71b7053SJung-uk Kim                         EVP_PKEY *pkey = s->cert->pkeys[sig_idx].privatekey;
3296e71b7053SJung-uk Kim 
3297b077aed3SPierre Pronchery                         if (!rsa_pss_check_min_key_size(s->ctx, pkey, lu))
3298e71b7053SJung-uk Kim                             continue;
3299e71b7053SJung-uk Kim                     }
3300e71b7053SJung-uk Kim                     if (curve == -1 || lu->curve == curve)
3301e71b7053SJung-uk Kim                         break;
3302e71b7053SJung-uk Kim                 }
330317f01e99SJung-uk Kim #ifndef OPENSSL_NO_GOST
330417f01e99SJung-uk Kim                 /*
330517f01e99SJung-uk Kim                  * Some Windows-based implementations do not send GOST algorithms indication
330617f01e99SJung-uk Kim                  * in supported_algorithms extension, so when we have GOST-based ciphersuite,
330717f01e99SJung-uk Kim                  * we have to assume GOST support.
330817f01e99SJung-uk Kim                  */
3309b077aed3SPierre Pronchery                 if (i == s->shared_sigalgslen && s->s3.tmp.new_cipher->algorithm_auth & (SSL_aGOST01 | SSL_aGOST12)) {
331017f01e99SJung-uk Kim                   if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) {
331117f01e99SJung-uk Kim                     if (!fatalerrs)
331217f01e99SJung-uk Kim                       return 1;
331317f01e99SJung-uk Kim                     SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
331417f01e99SJung-uk Kim                              SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM);
331517f01e99SJung-uk Kim                     return 0;
331617f01e99SJung-uk Kim                   } else {
331717f01e99SJung-uk Kim                     i = 0;
331817f01e99SJung-uk Kim                     sig_idx = lu->sig_idx;
331917f01e99SJung-uk Kim                   }
332017f01e99SJung-uk Kim                 }
332117f01e99SJung-uk Kim #endif
3322da327cd2SJung-uk Kim                 if (i == s->shared_sigalgslen) {
3323e71b7053SJung-uk Kim                     if (!fatalerrs)
3324e71b7053SJung-uk Kim                         return 1;
3325e71b7053SJung-uk Kim                     SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
3326e71b7053SJung-uk Kim                              SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM);
3327e71b7053SJung-uk Kim                     return 0;
3328e71b7053SJung-uk Kim                 }
3329e71b7053SJung-uk Kim             } else {
3330e71b7053SJung-uk Kim                 /*
3331e71b7053SJung-uk Kim                  * If we have no sigalg use defaults
3332e71b7053SJung-uk Kim                  */
3333e71b7053SJung-uk Kim                 const uint16_t *sent_sigs;
3334e71b7053SJung-uk Kim                 size_t sent_sigslen;
3335e71b7053SJung-uk Kim 
3336e71b7053SJung-uk Kim                 if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) {
3337e71b7053SJung-uk Kim                     if (!fatalerrs)
3338e71b7053SJung-uk Kim                         return 1;
3339b077aed3SPierre Pronchery                     SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
3340b077aed3SPierre Pronchery                              SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM);
3341e71b7053SJung-uk Kim                     return 0;
3342e71b7053SJung-uk Kim                 }
3343e71b7053SJung-uk Kim 
3344e71b7053SJung-uk Kim                 /* Check signature matches a type we sent */
3345e71b7053SJung-uk Kim                 sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs);
3346e71b7053SJung-uk Kim                 for (i = 0; i < sent_sigslen; i++, sent_sigs++) {
3347e71b7053SJung-uk Kim                     if (lu->sigalg == *sent_sigs
3348e71b7053SJung-uk Kim                             && has_usable_cert(s, lu, lu->sig_idx))
3349e71b7053SJung-uk Kim                         break;
3350e71b7053SJung-uk Kim                 }
3351e71b7053SJung-uk Kim                 if (i == sent_sigslen) {
3352e71b7053SJung-uk Kim                     if (!fatalerrs)
3353e71b7053SJung-uk Kim                         return 1;
3354b077aed3SPierre Pronchery                     SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
3355e71b7053SJung-uk Kim                              SSL_R_WRONG_SIGNATURE_TYPE);
3356e71b7053SJung-uk Kim                     return 0;
3357e71b7053SJung-uk Kim                 }
3358e71b7053SJung-uk Kim             }
3359e71b7053SJung-uk Kim         } else {
3360e71b7053SJung-uk Kim             if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) {
3361e71b7053SJung-uk Kim                 if (!fatalerrs)
3362e71b7053SJung-uk Kim                     return 1;
3363b077aed3SPierre Pronchery                 SSLfatal(s, SSL_AD_INTERNAL_ERROR,
3364b077aed3SPierre Pronchery                          SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM);
3365e71b7053SJung-uk Kim                 return 0;
3366e71b7053SJung-uk Kim             }
3367e71b7053SJung-uk Kim         }
3368e71b7053SJung-uk Kim     }
3369e71b7053SJung-uk Kim     if (sig_idx == -1)
3370e71b7053SJung-uk Kim         sig_idx = lu->sig_idx;
3371b077aed3SPierre Pronchery     s->s3.tmp.cert = &s->cert->pkeys[sig_idx];
3372b077aed3SPierre Pronchery     s->cert->key = s->s3.tmp.cert;
3373b077aed3SPierre Pronchery     s->s3.tmp.sigalg = lu;
3374e71b7053SJung-uk Kim     return 1;
3375e71b7053SJung-uk Kim }
3376e71b7053SJung-uk Kim 
3377e71b7053SJung-uk Kim int SSL_CTX_set_tlsext_max_fragment_length(SSL_CTX *ctx, uint8_t mode)
3378e71b7053SJung-uk Kim {
3379e71b7053SJung-uk Kim     if (mode != TLSEXT_max_fragment_length_DISABLED
3380e71b7053SJung-uk Kim             && !IS_MAX_FRAGMENT_LENGTH_EXT_VALID(mode)) {
3381b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH);
3382e71b7053SJung-uk Kim         return 0;
3383e71b7053SJung-uk Kim     }
3384e71b7053SJung-uk Kim 
3385e71b7053SJung-uk Kim     ctx->ext.max_fragment_len_mode = mode;
3386e71b7053SJung-uk Kim     return 1;
3387e71b7053SJung-uk Kim }
3388e71b7053SJung-uk Kim 
3389e71b7053SJung-uk Kim int SSL_set_tlsext_max_fragment_length(SSL *ssl, uint8_t mode)
3390e71b7053SJung-uk Kim {
3391e71b7053SJung-uk Kim     if (mode != TLSEXT_max_fragment_length_DISABLED
3392e71b7053SJung-uk Kim             && !IS_MAX_FRAGMENT_LENGTH_EXT_VALID(mode)) {
3393b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH);
3394e71b7053SJung-uk Kim         return 0;
3395e71b7053SJung-uk Kim     }
3396e71b7053SJung-uk Kim 
3397e71b7053SJung-uk Kim     ssl->ext.max_fragment_len_mode = mode;
3398e71b7053SJung-uk Kim     return 1;
3399e71b7053SJung-uk Kim }
3400e71b7053SJung-uk Kim 
3401e71b7053SJung-uk Kim uint8_t SSL_SESSION_get_max_fragment_length(const SSL_SESSION *session)
3402e71b7053SJung-uk Kim {
3403e71b7053SJung-uk Kim     return session->ext.max_fragment_len_mode;
3404e71b7053SJung-uk Kim }
3405b077aed3SPierre Pronchery 
3406b077aed3SPierre Pronchery /*
3407b077aed3SPierre Pronchery  * Helper functions for HMAC access with legacy support included.
3408b077aed3SPierre Pronchery  */
3409b077aed3SPierre Pronchery SSL_HMAC *ssl_hmac_new(const SSL_CTX *ctx)
3410b077aed3SPierre Pronchery {
3411b077aed3SPierre Pronchery     SSL_HMAC *ret = OPENSSL_zalloc(sizeof(*ret));
3412b077aed3SPierre Pronchery     EVP_MAC *mac = NULL;
3413b077aed3SPierre Pronchery 
3414b077aed3SPierre Pronchery     if (ret == NULL)
3415b077aed3SPierre Pronchery         return NULL;
3416b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DEPRECATED_3_0
3417b077aed3SPierre Pronchery     if (ctx->ext.ticket_key_evp_cb == NULL
3418b077aed3SPierre Pronchery             && ctx->ext.ticket_key_cb != NULL) {
3419b077aed3SPierre Pronchery         if (!ssl_hmac_old_new(ret))
3420b077aed3SPierre Pronchery             goto err;
3421b077aed3SPierre Pronchery         return ret;
3422b077aed3SPierre Pronchery     }
3423b077aed3SPierre Pronchery #endif
3424b077aed3SPierre Pronchery     mac = EVP_MAC_fetch(ctx->libctx, "HMAC", ctx->propq);
3425b077aed3SPierre Pronchery     if (mac == NULL || (ret->ctx = EVP_MAC_CTX_new(mac)) == NULL)
3426b077aed3SPierre Pronchery         goto err;
3427b077aed3SPierre Pronchery     EVP_MAC_free(mac);
3428b077aed3SPierre Pronchery     return ret;
3429b077aed3SPierre Pronchery  err:
3430b077aed3SPierre Pronchery     EVP_MAC_CTX_free(ret->ctx);
3431b077aed3SPierre Pronchery     EVP_MAC_free(mac);
3432b077aed3SPierre Pronchery     OPENSSL_free(ret);
3433b077aed3SPierre Pronchery     return NULL;
3434b077aed3SPierre Pronchery }
3435b077aed3SPierre Pronchery 
3436b077aed3SPierre Pronchery void ssl_hmac_free(SSL_HMAC *ctx)
3437b077aed3SPierre Pronchery {
3438b077aed3SPierre Pronchery     if (ctx != NULL) {
3439b077aed3SPierre Pronchery         EVP_MAC_CTX_free(ctx->ctx);
3440b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DEPRECATED_3_0
3441b077aed3SPierre Pronchery         ssl_hmac_old_free(ctx);
3442b077aed3SPierre Pronchery #endif
3443b077aed3SPierre Pronchery         OPENSSL_free(ctx);
3444b077aed3SPierre Pronchery     }
3445b077aed3SPierre Pronchery }
3446b077aed3SPierre Pronchery 
3447b077aed3SPierre Pronchery EVP_MAC_CTX *ssl_hmac_get0_EVP_MAC_CTX(SSL_HMAC *ctx)
3448b077aed3SPierre Pronchery {
3449b077aed3SPierre Pronchery     return ctx->ctx;
3450b077aed3SPierre Pronchery }
3451b077aed3SPierre Pronchery 
3452b077aed3SPierre Pronchery int ssl_hmac_init(SSL_HMAC *ctx, void *key, size_t len, char *md)
3453b077aed3SPierre Pronchery {
3454b077aed3SPierre Pronchery     OSSL_PARAM params[2], *p = params;
3455b077aed3SPierre Pronchery 
3456b077aed3SPierre Pronchery     if (ctx->ctx != NULL) {
3457b077aed3SPierre Pronchery         *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, md, 0);
3458b077aed3SPierre Pronchery         *p = OSSL_PARAM_construct_end();
3459b077aed3SPierre Pronchery         if (EVP_MAC_init(ctx->ctx, key, len, params))
3460b077aed3SPierre Pronchery             return 1;
3461b077aed3SPierre Pronchery     }
3462b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DEPRECATED_3_0
3463b077aed3SPierre Pronchery     if (ctx->old_ctx != NULL)
3464b077aed3SPierre Pronchery         return ssl_hmac_old_init(ctx, key, len, md);
3465b077aed3SPierre Pronchery #endif
3466b077aed3SPierre Pronchery     return 0;
3467b077aed3SPierre Pronchery }
3468b077aed3SPierre Pronchery 
3469b077aed3SPierre Pronchery int ssl_hmac_update(SSL_HMAC *ctx, const unsigned char *data, size_t len)
3470b077aed3SPierre Pronchery {
3471b077aed3SPierre Pronchery     if (ctx->ctx != NULL)
3472b077aed3SPierre Pronchery         return EVP_MAC_update(ctx->ctx, data, len);
3473b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DEPRECATED_3_0
3474b077aed3SPierre Pronchery     if (ctx->old_ctx != NULL)
3475b077aed3SPierre Pronchery         return ssl_hmac_old_update(ctx, data, len);
3476b077aed3SPierre Pronchery #endif
3477b077aed3SPierre Pronchery     return 0;
3478b077aed3SPierre Pronchery }
3479b077aed3SPierre Pronchery 
3480b077aed3SPierre Pronchery int ssl_hmac_final(SSL_HMAC *ctx, unsigned char *md, size_t *len,
3481b077aed3SPierre Pronchery                    size_t max_size)
3482b077aed3SPierre Pronchery {
3483b077aed3SPierre Pronchery     if (ctx->ctx != NULL)
3484b077aed3SPierre Pronchery         return EVP_MAC_final(ctx->ctx, md, len, max_size);
3485b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DEPRECATED_3_0
3486b077aed3SPierre Pronchery     if (ctx->old_ctx != NULL)
3487b077aed3SPierre Pronchery         return ssl_hmac_old_final(ctx, md, len);
3488b077aed3SPierre Pronchery #endif
3489b077aed3SPierre Pronchery     return 0;
3490b077aed3SPierre Pronchery }
3491b077aed3SPierre Pronchery 
3492b077aed3SPierre Pronchery size_t ssl_hmac_size(const SSL_HMAC *ctx)
3493b077aed3SPierre Pronchery {
3494b077aed3SPierre Pronchery     if (ctx->ctx != NULL)
3495b077aed3SPierre Pronchery         return EVP_MAC_CTX_get_mac_size(ctx->ctx);
3496b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DEPRECATED_3_0
3497b077aed3SPierre Pronchery     if (ctx->old_ctx != NULL)
3498b077aed3SPierre Pronchery         return ssl_hmac_old_size(ctx);
3499b077aed3SPierre Pronchery #endif
3500b077aed3SPierre Pronchery     return 0;
3501b077aed3SPierre Pronchery }
3502b077aed3SPierre Pronchery 
3503b077aed3SPierre Pronchery int ssl_get_EC_curve_nid(const EVP_PKEY *pkey)
3504b077aed3SPierre Pronchery {
3505b077aed3SPierre Pronchery     char gname[OSSL_MAX_NAME_SIZE];
3506b077aed3SPierre Pronchery 
3507b077aed3SPierre Pronchery     if (EVP_PKEY_get_group_name(pkey, gname, sizeof(gname), NULL) > 0)
3508b077aed3SPierre Pronchery         return OBJ_txt2nid(gname);
3509b077aed3SPierre Pronchery 
3510b077aed3SPierre Pronchery     return NID_undef;
3511b077aed3SPierre Pronchery }
3512b077aed3SPierre Pronchery 
3513b077aed3SPierre Pronchery __owur int tls13_set_encoded_pub_key(EVP_PKEY *pkey,
3514b077aed3SPierre Pronchery                                      const unsigned char *enckey,
3515b077aed3SPierre Pronchery                                      size_t enckeylen)
3516b077aed3SPierre Pronchery {
3517b077aed3SPierre Pronchery     if (EVP_PKEY_is_a(pkey, "DH")) {
3518b077aed3SPierre Pronchery         int bits = EVP_PKEY_get_bits(pkey);
3519b077aed3SPierre Pronchery 
3520b077aed3SPierre Pronchery         if (bits <= 0 || enckeylen != (size_t)bits / 8)
3521b077aed3SPierre Pronchery             /* the encoded key must be padded to the length of the p */
3522b077aed3SPierre Pronchery             return 0;
3523b077aed3SPierre Pronchery     } else if (EVP_PKEY_is_a(pkey, "EC")) {
3524b077aed3SPierre Pronchery         if (enckeylen < 3 /* point format and at least 1 byte for x and y */
3525b077aed3SPierre Pronchery             || enckey[0] != 0x04)
3526b077aed3SPierre Pronchery             return 0;
3527b077aed3SPierre Pronchery     }
3528b077aed3SPierre Pronchery 
3529b077aed3SPierre Pronchery     return EVP_PKEY_set1_encoded_public_key(pkey, enckey, enckeylen);
3530b077aed3SPierre Pronchery }
3531