xref: /dflybsd-src/crypto/libressl/ssl/ssl_seclevel.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
1*de0e0e4dSAntonio Huete Jimenez /*	$OpenBSD: ssl_seclevel.c,v 1.25 2022/08/17 18:41:17 tb Exp $ */
2*de0e0e4dSAntonio Huete Jimenez /*
3*de0e0e4dSAntonio Huete Jimenez  * Copyright (c) 2020-2022 Theo Buehler <tb@openbsd.org>
4*de0e0e4dSAntonio Huete Jimenez  *
5*de0e0e4dSAntonio Huete Jimenez  * Permission to use, copy, modify, and distribute this software for any
6*de0e0e4dSAntonio Huete Jimenez  * purpose with or without fee is hereby granted, provided that the above
7*de0e0e4dSAntonio Huete Jimenez  * copyright notice and this permission notice appear in all copies.
8*de0e0e4dSAntonio Huete Jimenez  *
9*de0e0e4dSAntonio Huete Jimenez  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*de0e0e4dSAntonio Huete Jimenez  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*de0e0e4dSAntonio Huete Jimenez  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*de0e0e4dSAntonio Huete Jimenez  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*de0e0e4dSAntonio Huete Jimenez  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*de0e0e4dSAntonio Huete Jimenez  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*de0e0e4dSAntonio Huete Jimenez  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*de0e0e4dSAntonio Huete Jimenez  */
17*de0e0e4dSAntonio Huete Jimenez 
18*de0e0e4dSAntonio Huete Jimenez #include <stddef.h>
19*de0e0e4dSAntonio Huete Jimenez 
20*de0e0e4dSAntonio Huete Jimenez #include <openssl/asn1.h>
21*de0e0e4dSAntonio Huete Jimenez #include <openssl/dh.h>
22*de0e0e4dSAntonio Huete Jimenez #include <openssl/evp.h>
23*de0e0e4dSAntonio Huete Jimenez #include <openssl/objects.h>
24*de0e0e4dSAntonio Huete Jimenez #include <openssl/ossl_typ.h>
25*de0e0e4dSAntonio Huete Jimenez #include <openssl/ssl.h>
26*de0e0e4dSAntonio Huete Jimenez #include <openssl/tls1.h>
27*de0e0e4dSAntonio Huete Jimenez #include <openssl/x509.h>
28*de0e0e4dSAntonio Huete Jimenez #include <openssl/x509v3.h>
29*de0e0e4dSAntonio Huete Jimenez 
30*de0e0e4dSAntonio Huete Jimenez #include "bytestring.h"
31*de0e0e4dSAntonio Huete Jimenez #include "ssl_locl.h"
32*de0e0e4dSAntonio Huete Jimenez 
33*de0e0e4dSAntonio Huete Jimenez static int
ssl_security_normalize_level(const SSL_CTX * ctx,const SSL * ssl,int * out_level)34*de0e0e4dSAntonio Huete Jimenez ssl_security_normalize_level(const SSL_CTX *ctx, const SSL *ssl, int *out_level)
35*de0e0e4dSAntonio Huete Jimenez {
36*de0e0e4dSAntonio Huete Jimenez 	int security_level;
37*de0e0e4dSAntonio Huete Jimenez 
38*de0e0e4dSAntonio Huete Jimenez 	if (ctx != NULL)
39*de0e0e4dSAntonio Huete Jimenez 		security_level = SSL_CTX_get_security_level(ctx);
40*de0e0e4dSAntonio Huete Jimenez 	else
41*de0e0e4dSAntonio Huete Jimenez 		security_level = SSL_get_security_level(ssl);
42*de0e0e4dSAntonio Huete Jimenez 
43*de0e0e4dSAntonio Huete Jimenez 	if (security_level < 0)
44*de0e0e4dSAntonio Huete Jimenez 		security_level = 0;
45*de0e0e4dSAntonio Huete Jimenez 	if (security_level > 5)
46*de0e0e4dSAntonio Huete Jimenez 		security_level = 5;
47*de0e0e4dSAntonio Huete Jimenez 
48*de0e0e4dSAntonio Huete Jimenez 	*out_level = security_level;
49*de0e0e4dSAntonio Huete Jimenez 
50*de0e0e4dSAntonio Huete Jimenez 	return 1;
51*de0e0e4dSAntonio Huete Jimenez }
52*de0e0e4dSAntonio Huete Jimenez 
53*de0e0e4dSAntonio Huete Jimenez static int
ssl_security_level_to_minimum_bits(int security_level,int * out_minimum_bits)54*de0e0e4dSAntonio Huete Jimenez ssl_security_level_to_minimum_bits(int security_level, int *out_minimum_bits)
55*de0e0e4dSAntonio Huete Jimenez {
56*de0e0e4dSAntonio Huete Jimenez 	if (security_level < 0)
57*de0e0e4dSAntonio Huete Jimenez 		return 0;
58*de0e0e4dSAntonio Huete Jimenez 
59*de0e0e4dSAntonio Huete Jimenez 	if (security_level == 0)
60*de0e0e4dSAntonio Huete Jimenez 		*out_minimum_bits = 0;
61*de0e0e4dSAntonio Huete Jimenez 	else if (security_level == 1)
62*de0e0e4dSAntonio Huete Jimenez 		*out_minimum_bits = 80;
63*de0e0e4dSAntonio Huete Jimenez 	else if (security_level == 2)
64*de0e0e4dSAntonio Huete Jimenez 		*out_minimum_bits = 112;
65*de0e0e4dSAntonio Huete Jimenez 	else if (security_level == 3)
66*de0e0e4dSAntonio Huete Jimenez 		*out_minimum_bits = 128;
67*de0e0e4dSAntonio Huete Jimenez 	else if (security_level == 4)
68*de0e0e4dSAntonio Huete Jimenez 		*out_minimum_bits = 192;
69*de0e0e4dSAntonio Huete Jimenez 	else if (security_level >= 5)
70*de0e0e4dSAntonio Huete Jimenez 		*out_minimum_bits = 256;
71*de0e0e4dSAntonio Huete Jimenez 
72*de0e0e4dSAntonio Huete Jimenez 	return 1;
73*de0e0e4dSAntonio Huete Jimenez }
74*de0e0e4dSAntonio Huete Jimenez 
75*de0e0e4dSAntonio Huete Jimenez static int
ssl_security_level_and_minimum_bits(const SSL_CTX * ctx,const SSL * ssl,int * out_level,int * out_minimum_bits)76*de0e0e4dSAntonio Huete Jimenez ssl_security_level_and_minimum_bits(const SSL_CTX *ctx, const SSL *ssl,
77*de0e0e4dSAntonio Huete Jimenez     int *out_level, int *out_minimum_bits)
78*de0e0e4dSAntonio Huete Jimenez {
79*de0e0e4dSAntonio Huete Jimenez 	int security_level = 0, minimum_bits = 0;
80*de0e0e4dSAntonio Huete Jimenez 
81*de0e0e4dSAntonio Huete Jimenez 	if (!ssl_security_normalize_level(ctx, ssl, &security_level))
82*de0e0e4dSAntonio Huete Jimenez 		return 0;
83*de0e0e4dSAntonio Huete Jimenez 	if (!ssl_security_level_to_minimum_bits(security_level, &minimum_bits))
84*de0e0e4dSAntonio Huete Jimenez 		return 0;
85*de0e0e4dSAntonio Huete Jimenez 
86*de0e0e4dSAntonio Huete Jimenez 	if (out_level != NULL)
87*de0e0e4dSAntonio Huete Jimenez 		*out_level = security_level;
88*de0e0e4dSAntonio Huete Jimenez 	if (out_minimum_bits != NULL)
89*de0e0e4dSAntonio Huete Jimenez 		*out_minimum_bits = minimum_bits;
90*de0e0e4dSAntonio Huete Jimenez 
91*de0e0e4dSAntonio Huete Jimenez 	return 1;
92*de0e0e4dSAntonio Huete Jimenez }
93*de0e0e4dSAntonio Huete Jimenez 
94*de0e0e4dSAntonio Huete Jimenez static int
ssl_security_secop_cipher(const SSL_CTX * ctx,const SSL * ssl,int bits,void * arg)95*de0e0e4dSAntonio Huete Jimenez ssl_security_secop_cipher(const SSL_CTX *ctx, const SSL *ssl, int bits,
96*de0e0e4dSAntonio Huete Jimenez     void *arg)
97*de0e0e4dSAntonio Huete Jimenez {
98*de0e0e4dSAntonio Huete Jimenez 	const SSL_CIPHER *cipher = arg;
99*de0e0e4dSAntonio Huete Jimenez 	int security_level, minimum_bits;
100*de0e0e4dSAntonio Huete Jimenez 
101*de0e0e4dSAntonio Huete Jimenez 	if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level,
102*de0e0e4dSAntonio Huete Jimenez 	    &minimum_bits))
103*de0e0e4dSAntonio Huete Jimenez 		return 0;
104*de0e0e4dSAntonio Huete Jimenez 
105*de0e0e4dSAntonio Huete Jimenez 	if (security_level <= 0)
106*de0e0e4dSAntonio Huete Jimenez 		return 1;
107*de0e0e4dSAntonio Huete Jimenez 
108*de0e0e4dSAntonio Huete Jimenez 	if (bits < minimum_bits)
109*de0e0e4dSAntonio Huete Jimenez 		return 0;
110*de0e0e4dSAntonio Huete Jimenez 
111*de0e0e4dSAntonio Huete Jimenez 	/* No unauthenticated ciphersuites. */
112*de0e0e4dSAntonio Huete Jimenez 	if (cipher->algorithm_auth & SSL_aNULL)
113*de0e0e4dSAntonio Huete Jimenez 		return 0;
114*de0e0e4dSAntonio Huete Jimenez 
115*de0e0e4dSAntonio Huete Jimenez 	if (cipher->algorithm_mac & SSL_MD5)
116*de0e0e4dSAntonio Huete Jimenez 		return 0;
117*de0e0e4dSAntonio Huete Jimenez 
118*de0e0e4dSAntonio Huete Jimenez 	if (security_level <= 1)
119*de0e0e4dSAntonio Huete Jimenez 		return 1;
120*de0e0e4dSAntonio Huete Jimenez 
121*de0e0e4dSAntonio Huete Jimenez 	if (cipher->algorithm_enc & SSL_RC4)
122*de0e0e4dSAntonio Huete Jimenez 		return 0;
123*de0e0e4dSAntonio Huete Jimenez 
124*de0e0e4dSAntonio Huete Jimenez 	if (security_level <= 2)
125*de0e0e4dSAntonio Huete Jimenez 		return 1;
126*de0e0e4dSAntonio Huete Jimenez 
127*de0e0e4dSAntonio Huete Jimenez 	/* Security level >= 3 requires a cipher with forward secrecy. */
128*de0e0e4dSAntonio Huete Jimenez 	if ((cipher->algorithm_mkey & (SSL_kDHE | SSL_kECDHE)) == 0 &&
129*de0e0e4dSAntonio Huete Jimenez 	    cipher->algorithm_ssl != SSL_TLSV1_3)
130*de0e0e4dSAntonio Huete Jimenez 		return 0;
131*de0e0e4dSAntonio Huete Jimenez 
132*de0e0e4dSAntonio Huete Jimenez 	if (security_level <= 3)
133*de0e0e4dSAntonio Huete Jimenez 		return 1;
134*de0e0e4dSAntonio Huete Jimenez 
135*de0e0e4dSAntonio Huete Jimenez 	if (cipher->algorithm_mac & SSL_SHA1)
136*de0e0e4dSAntonio Huete Jimenez 		return 0;
137*de0e0e4dSAntonio Huete Jimenez 
138*de0e0e4dSAntonio Huete Jimenez 	return 1;
139*de0e0e4dSAntonio Huete Jimenez }
140*de0e0e4dSAntonio Huete Jimenez 
141*de0e0e4dSAntonio Huete Jimenez static int
ssl_security_secop_version(const SSL_CTX * ctx,const SSL * ssl,int version)142*de0e0e4dSAntonio Huete Jimenez ssl_security_secop_version(const SSL_CTX *ctx, const SSL *ssl, int version)
143*de0e0e4dSAntonio Huete Jimenez {
144*de0e0e4dSAntonio Huete Jimenez 	int min_version = TLS1_2_VERSION;
145*de0e0e4dSAntonio Huete Jimenez 	int security_level;
146*de0e0e4dSAntonio Huete Jimenez 
147*de0e0e4dSAntonio Huete Jimenez 	if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level, NULL))
148*de0e0e4dSAntonio Huete Jimenez 		return 0;
149*de0e0e4dSAntonio Huete Jimenez 
150*de0e0e4dSAntonio Huete Jimenez 	if (security_level < 4)
151*de0e0e4dSAntonio Huete Jimenez 		min_version = TLS1_1_VERSION;
152*de0e0e4dSAntonio Huete Jimenez 	if (security_level < 3)
153*de0e0e4dSAntonio Huete Jimenez 		min_version = TLS1_VERSION;
154*de0e0e4dSAntonio Huete Jimenez 
155*de0e0e4dSAntonio Huete Jimenez 	return ssl_tls_version(version) >= min_version;
156*de0e0e4dSAntonio Huete Jimenez }
157*de0e0e4dSAntonio Huete Jimenez 
158*de0e0e4dSAntonio Huete Jimenez static int
ssl_security_secop_compression(const SSL_CTX * ctx,const SSL * ssl)159*de0e0e4dSAntonio Huete Jimenez ssl_security_secop_compression(const SSL_CTX *ctx, const SSL *ssl)
160*de0e0e4dSAntonio Huete Jimenez {
161*de0e0e4dSAntonio Huete Jimenez 	return 0;
162*de0e0e4dSAntonio Huete Jimenez }
163*de0e0e4dSAntonio Huete Jimenez 
164*de0e0e4dSAntonio Huete Jimenez static int
ssl_security_secop_tickets(const SSL_CTX * ctx,const SSL * ssl)165*de0e0e4dSAntonio Huete Jimenez ssl_security_secop_tickets(const SSL_CTX *ctx, const SSL *ssl)
166*de0e0e4dSAntonio Huete Jimenez {
167*de0e0e4dSAntonio Huete Jimenez 	int security_level;
168*de0e0e4dSAntonio Huete Jimenez 
169*de0e0e4dSAntonio Huete Jimenez 	if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level, NULL))
170*de0e0e4dSAntonio Huete Jimenez 		return 0;
171*de0e0e4dSAntonio Huete Jimenez 
172*de0e0e4dSAntonio Huete Jimenez 	return security_level < 3;
173*de0e0e4dSAntonio Huete Jimenez }
174*de0e0e4dSAntonio Huete Jimenez 
175*de0e0e4dSAntonio Huete Jimenez static int
ssl_security_secop_tmp_dh(const SSL_CTX * ctx,const SSL * ssl,int bits)176*de0e0e4dSAntonio Huete Jimenez ssl_security_secop_tmp_dh(const SSL_CTX *ctx, const SSL *ssl, int bits)
177*de0e0e4dSAntonio Huete Jimenez {
178*de0e0e4dSAntonio Huete Jimenez 	int security_level, minimum_bits;
179*de0e0e4dSAntonio Huete Jimenez 
180*de0e0e4dSAntonio Huete Jimenez 	if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level,
181*de0e0e4dSAntonio Huete Jimenez 	    &minimum_bits))
182*de0e0e4dSAntonio Huete Jimenez 		return 0;
183*de0e0e4dSAntonio Huete Jimenez 
184*de0e0e4dSAntonio Huete Jimenez 	/* Disallow DHE keys weaker than 1024 bits even at security level 0. */
185*de0e0e4dSAntonio Huete Jimenez 	if (security_level <= 0 && bits < 80)
186*de0e0e4dSAntonio Huete Jimenez 		return 0;
187*de0e0e4dSAntonio Huete Jimenez 
188*de0e0e4dSAntonio Huete Jimenez 	return bits >= minimum_bits;
189*de0e0e4dSAntonio Huete Jimenez }
190*de0e0e4dSAntonio Huete Jimenez 
191*de0e0e4dSAntonio Huete Jimenez static int
ssl_security_secop_default(const SSL_CTX * ctx,const SSL * ssl,int bits)192*de0e0e4dSAntonio Huete Jimenez ssl_security_secop_default(const SSL_CTX *ctx, const SSL *ssl, int bits)
193*de0e0e4dSAntonio Huete Jimenez {
194*de0e0e4dSAntonio Huete Jimenez 	int minimum_bits;
195*de0e0e4dSAntonio Huete Jimenez 
196*de0e0e4dSAntonio Huete Jimenez 	if (!ssl_security_level_and_minimum_bits(ctx, ssl, NULL, &minimum_bits))
197*de0e0e4dSAntonio Huete Jimenez 		return 0;
198*de0e0e4dSAntonio Huete Jimenez 
199*de0e0e4dSAntonio Huete Jimenez 	return bits >= minimum_bits;
200*de0e0e4dSAntonio Huete Jimenez }
201*de0e0e4dSAntonio Huete Jimenez 
202*de0e0e4dSAntonio Huete Jimenez int
ssl_security_default_cb(const SSL * ssl,const SSL_CTX * ctx,int secop,int bits,int version,void * cipher,void * ex_data)203*de0e0e4dSAntonio Huete Jimenez ssl_security_default_cb(const SSL *ssl, const SSL_CTX *ctx, int secop, int bits,
204*de0e0e4dSAntonio Huete Jimenez     int version, void *cipher, void *ex_data)
205*de0e0e4dSAntonio Huete Jimenez {
206*de0e0e4dSAntonio Huete Jimenez 	switch (secop) {
207*de0e0e4dSAntonio Huete Jimenez 	case SSL_SECOP_CIPHER_SUPPORTED:
208*de0e0e4dSAntonio Huete Jimenez 	case SSL_SECOP_CIPHER_SHARED:
209*de0e0e4dSAntonio Huete Jimenez 	case SSL_SECOP_CIPHER_CHECK:
210*de0e0e4dSAntonio Huete Jimenez 		return ssl_security_secop_cipher(ctx, ssl, bits, cipher);
211*de0e0e4dSAntonio Huete Jimenez 	case SSL_SECOP_VERSION:
212*de0e0e4dSAntonio Huete Jimenez 		return ssl_security_secop_version(ctx, ssl, version);
213*de0e0e4dSAntonio Huete Jimenez 	case SSL_SECOP_COMPRESSION:
214*de0e0e4dSAntonio Huete Jimenez 		return ssl_security_secop_compression(ctx, ssl);
215*de0e0e4dSAntonio Huete Jimenez 	case SSL_SECOP_TICKET:
216*de0e0e4dSAntonio Huete Jimenez 		return ssl_security_secop_tickets(ctx, ssl);
217*de0e0e4dSAntonio Huete Jimenez 	case SSL_SECOP_TMP_DH:
218*de0e0e4dSAntonio Huete Jimenez 		return ssl_security_secop_tmp_dh(ctx, ssl, bits);
219*de0e0e4dSAntonio Huete Jimenez 	default:
220*de0e0e4dSAntonio Huete Jimenez 		return ssl_security_secop_default(ctx, ssl, bits);
221*de0e0e4dSAntonio Huete Jimenez 	}
222*de0e0e4dSAntonio Huete Jimenez }
223*de0e0e4dSAntonio Huete Jimenez 
224*de0e0e4dSAntonio Huete Jimenez static int
ssl_ctx_security(const SSL_CTX * ctx,int secop,int bits,int nid,void * other)225*de0e0e4dSAntonio Huete Jimenez ssl_ctx_security(const SSL_CTX *ctx, int secop, int bits, int nid, void *other)
226*de0e0e4dSAntonio Huete Jimenez {
227*de0e0e4dSAntonio Huete Jimenez 	return ctx->internal->cert->security_cb(NULL, ctx, secop, bits, nid,
228*de0e0e4dSAntonio Huete Jimenez 	    other, ctx->internal->cert->security_ex_data);
229*de0e0e4dSAntonio Huete Jimenez }
230*de0e0e4dSAntonio Huete Jimenez 
231*de0e0e4dSAntonio Huete Jimenez static int
ssl_security(const SSL * ssl,int secop,int bits,int nid,void * other)232*de0e0e4dSAntonio Huete Jimenez ssl_security(const SSL *ssl, int secop, int bits, int nid, void *other)
233*de0e0e4dSAntonio Huete Jimenez {
234*de0e0e4dSAntonio Huete Jimenez 	return ssl->cert->security_cb(ssl, NULL, secop, bits, nid, other,
235*de0e0e4dSAntonio Huete Jimenez 	    ssl->cert->security_ex_data);
236*de0e0e4dSAntonio Huete Jimenez }
237*de0e0e4dSAntonio Huete Jimenez 
238*de0e0e4dSAntonio Huete Jimenez int
ssl_security_sigalg_check(const SSL * ssl,const EVP_PKEY * pkey)239*de0e0e4dSAntonio Huete Jimenez ssl_security_sigalg_check(const SSL *ssl, const EVP_PKEY *pkey)
240*de0e0e4dSAntonio Huete Jimenez {
241*de0e0e4dSAntonio Huete Jimenez 	int bits;
242*de0e0e4dSAntonio Huete Jimenez 
243*de0e0e4dSAntonio Huete Jimenez 	bits = EVP_PKEY_security_bits(pkey);
244*de0e0e4dSAntonio Huete Jimenez 
245*de0e0e4dSAntonio Huete Jimenez 	return ssl_security(ssl, SSL_SECOP_SIGALG_CHECK, bits, 0, NULL);
246*de0e0e4dSAntonio Huete Jimenez }
247*de0e0e4dSAntonio Huete Jimenez 
248*de0e0e4dSAntonio Huete Jimenez int
ssl_security_tickets(const SSL * ssl)249*de0e0e4dSAntonio Huete Jimenez ssl_security_tickets(const SSL *ssl)
250*de0e0e4dSAntonio Huete Jimenez {
251*de0e0e4dSAntonio Huete Jimenez 	return ssl_security(ssl, SSL_SECOP_TICKET, 0, 0, NULL);
252*de0e0e4dSAntonio Huete Jimenez }
253*de0e0e4dSAntonio Huete Jimenez 
254*de0e0e4dSAntonio Huete Jimenez int
ssl_security_version(const SSL * ssl,int version)255*de0e0e4dSAntonio Huete Jimenez ssl_security_version(const SSL *ssl, int version)
256*de0e0e4dSAntonio Huete Jimenez {
257*de0e0e4dSAntonio Huete Jimenez 	return ssl_security(ssl, SSL_SECOP_VERSION, 0, version, NULL);
258*de0e0e4dSAntonio Huete Jimenez }
259*de0e0e4dSAntonio Huete Jimenez 
260*de0e0e4dSAntonio Huete Jimenez static int
ssl_security_cipher(const SSL * ssl,SSL_CIPHER * cipher,int secop)261*de0e0e4dSAntonio Huete Jimenez ssl_security_cipher(const SSL *ssl, SSL_CIPHER *cipher, int secop)
262*de0e0e4dSAntonio Huete Jimenez {
263*de0e0e4dSAntonio Huete Jimenez 	return ssl_security(ssl, secop, cipher->strength_bits, 0, cipher);
264*de0e0e4dSAntonio Huete Jimenez }
265*de0e0e4dSAntonio Huete Jimenez 
266*de0e0e4dSAntonio Huete Jimenez int
ssl_security_cipher_check(const SSL * ssl,SSL_CIPHER * cipher)267*de0e0e4dSAntonio Huete Jimenez ssl_security_cipher_check(const SSL *ssl, SSL_CIPHER *cipher)
268*de0e0e4dSAntonio Huete Jimenez {
269*de0e0e4dSAntonio Huete Jimenez 	return ssl_security_cipher(ssl, cipher, SSL_SECOP_CIPHER_CHECK);
270*de0e0e4dSAntonio Huete Jimenez }
271*de0e0e4dSAntonio Huete Jimenez 
272*de0e0e4dSAntonio Huete Jimenez int
ssl_security_shared_cipher(const SSL * ssl,SSL_CIPHER * cipher)273*de0e0e4dSAntonio Huete Jimenez ssl_security_shared_cipher(const SSL *ssl, SSL_CIPHER *cipher)
274*de0e0e4dSAntonio Huete Jimenez {
275*de0e0e4dSAntonio Huete Jimenez 	return ssl_security_cipher(ssl, cipher, SSL_SECOP_CIPHER_SHARED);
276*de0e0e4dSAntonio Huete Jimenez }
277*de0e0e4dSAntonio Huete Jimenez 
278*de0e0e4dSAntonio Huete Jimenez int
ssl_security_supported_cipher(const SSL * ssl,SSL_CIPHER * cipher)279*de0e0e4dSAntonio Huete Jimenez ssl_security_supported_cipher(const SSL *ssl, SSL_CIPHER *cipher)
280*de0e0e4dSAntonio Huete Jimenez {
281*de0e0e4dSAntonio Huete Jimenez 	return ssl_security_cipher(ssl, cipher, SSL_SECOP_CIPHER_SUPPORTED);
282*de0e0e4dSAntonio Huete Jimenez }
283*de0e0e4dSAntonio Huete Jimenez 
284*de0e0e4dSAntonio Huete Jimenez int
ssl_ctx_security_dh(const SSL_CTX * ctx,DH * dh)285*de0e0e4dSAntonio Huete Jimenez ssl_ctx_security_dh(const SSL_CTX *ctx, DH *dh)
286*de0e0e4dSAntonio Huete Jimenez {
287*de0e0e4dSAntonio Huete Jimenez 	int bits;
288*de0e0e4dSAntonio Huete Jimenez 
289*de0e0e4dSAntonio Huete Jimenez 	bits = DH_security_bits(dh);
290*de0e0e4dSAntonio Huete Jimenez 
291*de0e0e4dSAntonio Huete Jimenez 	return ssl_ctx_security(ctx, SSL_SECOP_TMP_DH, bits, 0, dh);
292*de0e0e4dSAntonio Huete Jimenez }
293*de0e0e4dSAntonio Huete Jimenez 
294*de0e0e4dSAntonio Huete Jimenez int
ssl_security_dh(const SSL * ssl,DH * dh)295*de0e0e4dSAntonio Huete Jimenez ssl_security_dh(const SSL *ssl, DH *dh)
296*de0e0e4dSAntonio Huete Jimenez {
297*de0e0e4dSAntonio Huete Jimenez 	int bits;
298*de0e0e4dSAntonio Huete Jimenez 
299*de0e0e4dSAntonio Huete Jimenez 	bits = DH_security_bits(dh);
300*de0e0e4dSAntonio Huete Jimenez 
301*de0e0e4dSAntonio Huete Jimenez 	return ssl_security(ssl, SSL_SECOP_TMP_DH, bits, 0, dh);
302*de0e0e4dSAntonio Huete Jimenez }
303*de0e0e4dSAntonio Huete Jimenez 
304*de0e0e4dSAntonio Huete Jimenez static int
ssl_cert_pubkey_security_bits(const X509 * x509)305*de0e0e4dSAntonio Huete Jimenez ssl_cert_pubkey_security_bits(const X509 *x509)
306*de0e0e4dSAntonio Huete Jimenez {
307*de0e0e4dSAntonio Huete Jimenez 	EVP_PKEY *pkey;
308*de0e0e4dSAntonio Huete Jimenez 
309*de0e0e4dSAntonio Huete Jimenez 	if ((pkey = X509_get0_pubkey(x509)) == NULL)
310*de0e0e4dSAntonio Huete Jimenez 		return -1;
311*de0e0e4dSAntonio Huete Jimenez 
312*de0e0e4dSAntonio Huete Jimenez 	/*
313*de0e0e4dSAntonio Huete Jimenez 	 * XXX: DSA_security_bits() returns -1 on keys without parameters and
314*de0e0e4dSAntonio Huete Jimenez 	 * makes the default security callback fail.
315*de0e0e4dSAntonio Huete Jimenez 	 */
316*de0e0e4dSAntonio Huete Jimenez 
317*de0e0e4dSAntonio Huete Jimenez 	return EVP_PKEY_security_bits(pkey);
318*de0e0e4dSAntonio Huete Jimenez }
319*de0e0e4dSAntonio Huete Jimenez 
320*de0e0e4dSAntonio Huete Jimenez static int
ssl_security_cert_key(const SSL_CTX * ctx,const SSL * ssl,X509 * x509,int secop)321*de0e0e4dSAntonio Huete Jimenez ssl_security_cert_key(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, int secop)
322*de0e0e4dSAntonio Huete Jimenez {
323*de0e0e4dSAntonio Huete Jimenez 	int security_bits;
324*de0e0e4dSAntonio Huete Jimenez 
325*de0e0e4dSAntonio Huete Jimenez 	security_bits = ssl_cert_pubkey_security_bits(x509);
326*de0e0e4dSAntonio Huete Jimenez 
327*de0e0e4dSAntonio Huete Jimenez 	if (ssl != NULL)
328*de0e0e4dSAntonio Huete Jimenez 		return ssl_security(ssl, secop, security_bits, 0, x509);
329*de0e0e4dSAntonio Huete Jimenez 
330*de0e0e4dSAntonio Huete Jimenez 	return ssl_ctx_security(ctx, secop, security_bits, 0, x509);
331*de0e0e4dSAntonio Huete Jimenez }
332*de0e0e4dSAntonio Huete Jimenez 
333*de0e0e4dSAntonio Huete Jimenez static int
ssl_cert_signature_md_nid(X509 * x509)334*de0e0e4dSAntonio Huete Jimenez ssl_cert_signature_md_nid(X509 *x509)
335*de0e0e4dSAntonio Huete Jimenez {
336*de0e0e4dSAntonio Huete Jimenez 	int md_nid, signature_nid;
337*de0e0e4dSAntonio Huete Jimenez 
338*de0e0e4dSAntonio Huete Jimenez 	if ((signature_nid = X509_get_signature_nid(x509)) == NID_undef)
339*de0e0e4dSAntonio Huete Jimenez 		return NID_undef;
340*de0e0e4dSAntonio Huete Jimenez 
341*de0e0e4dSAntonio Huete Jimenez 	if (!OBJ_find_sigid_algs(signature_nid, &md_nid, NULL))
342*de0e0e4dSAntonio Huete Jimenez 		return NID_undef;
343*de0e0e4dSAntonio Huete Jimenez 
344*de0e0e4dSAntonio Huete Jimenez 	return md_nid;
345*de0e0e4dSAntonio Huete Jimenez }
346*de0e0e4dSAntonio Huete Jimenez 
347*de0e0e4dSAntonio Huete Jimenez static int
ssl_cert_md_nid_security_bits(int md_nid)348*de0e0e4dSAntonio Huete Jimenez ssl_cert_md_nid_security_bits(int md_nid)
349*de0e0e4dSAntonio Huete Jimenez {
350*de0e0e4dSAntonio Huete Jimenez 	const EVP_MD *md;
351*de0e0e4dSAntonio Huete Jimenez 
352*de0e0e4dSAntonio Huete Jimenez 	if (md_nid == NID_undef)
353*de0e0e4dSAntonio Huete Jimenez 		return -1;
354*de0e0e4dSAntonio Huete Jimenez 
355*de0e0e4dSAntonio Huete Jimenez 	if ((md = EVP_get_digestbynid(md_nid)) == NULL)
356*de0e0e4dSAntonio Huete Jimenez 		return -1;
357*de0e0e4dSAntonio Huete Jimenez 
358*de0e0e4dSAntonio Huete Jimenez 	/* Assume 4 bits of collision resistance for each hash octet. */
359*de0e0e4dSAntonio Huete Jimenez 	return EVP_MD_size(md) * 4;
360*de0e0e4dSAntonio Huete Jimenez }
361*de0e0e4dSAntonio Huete Jimenez 
362*de0e0e4dSAntonio Huete Jimenez static int
ssl_security_cert_sig(const SSL_CTX * ctx,const SSL * ssl,X509 * x509,int secop)363*de0e0e4dSAntonio Huete Jimenez ssl_security_cert_sig(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, int secop)
364*de0e0e4dSAntonio Huete Jimenez {
365*de0e0e4dSAntonio Huete Jimenez 	int md_nid, security_bits;
366*de0e0e4dSAntonio Huete Jimenez 
367*de0e0e4dSAntonio Huete Jimenez 	/* Don't check signature if self signed. */
368*de0e0e4dSAntonio Huete Jimenez 	if ((X509_get_extension_flags(x509) & EXFLAG_SS) != 0)
369*de0e0e4dSAntonio Huete Jimenez 		return 1;
370*de0e0e4dSAntonio Huete Jimenez 
371*de0e0e4dSAntonio Huete Jimenez 	md_nid = ssl_cert_signature_md_nid(x509);
372*de0e0e4dSAntonio Huete Jimenez 	security_bits = ssl_cert_md_nid_security_bits(md_nid);
373*de0e0e4dSAntonio Huete Jimenez 
374*de0e0e4dSAntonio Huete Jimenez 	if (ssl != NULL)
375*de0e0e4dSAntonio Huete Jimenez 		return ssl_security(ssl, secop, security_bits, md_nid, x509);
376*de0e0e4dSAntonio Huete Jimenez 
377*de0e0e4dSAntonio Huete Jimenez 	return ssl_ctx_security(ctx, secop, security_bits, md_nid, x509);
378*de0e0e4dSAntonio Huete Jimenez }
379*de0e0e4dSAntonio Huete Jimenez 
380*de0e0e4dSAntonio Huete Jimenez int
ssl_security_cert(const SSL_CTX * ctx,const SSL * ssl,X509 * x509,int is_ee,int * out_error)381*de0e0e4dSAntonio Huete Jimenez ssl_security_cert(const SSL_CTX *ctx, const SSL *ssl, X509 *x509,
382*de0e0e4dSAntonio Huete Jimenez     int is_ee, int *out_error)
383*de0e0e4dSAntonio Huete Jimenez {
384*de0e0e4dSAntonio Huete Jimenez 	int key_error, operation;
385*de0e0e4dSAntonio Huete Jimenez 
386*de0e0e4dSAntonio Huete Jimenez 	*out_error = 0;
387*de0e0e4dSAntonio Huete Jimenez 
388*de0e0e4dSAntonio Huete Jimenez 	if (is_ee) {
389*de0e0e4dSAntonio Huete Jimenez 		operation = SSL_SECOP_EE_KEY;
390*de0e0e4dSAntonio Huete Jimenez 		key_error = SSL_R_EE_KEY_TOO_SMALL;
391*de0e0e4dSAntonio Huete Jimenez 	} else {
392*de0e0e4dSAntonio Huete Jimenez 		operation = SSL_SECOP_CA_KEY;
393*de0e0e4dSAntonio Huete Jimenez 		key_error = SSL_R_CA_KEY_TOO_SMALL;
394*de0e0e4dSAntonio Huete Jimenez 	}
395*de0e0e4dSAntonio Huete Jimenez 
396*de0e0e4dSAntonio Huete Jimenez 	if (!ssl_security_cert_key(ctx, ssl, x509, operation)) {
397*de0e0e4dSAntonio Huete Jimenez 		*out_error = key_error;
398*de0e0e4dSAntonio Huete Jimenez 		return 0;
399*de0e0e4dSAntonio Huete Jimenez 	}
400*de0e0e4dSAntonio Huete Jimenez 
401*de0e0e4dSAntonio Huete Jimenez 	if (!ssl_security_cert_sig(ctx, ssl, x509, SSL_SECOP_CA_MD)) {
402*de0e0e4dSAntonio Huete Jimenez 		*out_error = SSL_R_CA_MD_TOO_WEAK;
403*de0e0e4dSAntonio Huete Jimenez 		return 0;
404*de0e0e4dSAntonio Huete Jimenez 	}
405*de0e0e4dSAntonio Huete Jimenez 
406*de0e0e4dSAntonio Huete Jimenez 	return 1;
407*de0e0e4dSAntonio Huete Jimenez }
408*de0e0e4dSAntonio Huete Jimenez 
409*de0e0e4dSAntonio Huete Jimenez /*
410*de0e0e4dSAntonio Huete Jimenez  * Check security of a chain. If |sk| includes the end entity certificate
411*de0e0e4dSAntonio Huete Jimenez  * then |x509| must be NULL.
412*de0e0e4dSAntonio Huete Jimenez  */
413*de0e0e4dSAntonio Huete Jimenez int
ssl_security_cert_chain(const SSL * ssl,STACK_OF (X509)* sk,X509 * x509,int * out_error)414*de0e0e4dSAntonio Huete Jimenez ssl_security_cert_chain(const SSL *ssl, STACK_OF(X509) *sk, X509 *x509,
415*de0e0e4dSAntonio Huete Jimenez     int *out_error)
416*de0e0e4dSAntonio Huete Jimenez {
417*de0e0e4dSAntonio Huete Jimenez 	int start_idx = 0;
418*de0e0e4dSAntonio Huete Jimenez 	int is_ee;
419*de0e0e4dSAntonio Huete Jimenez 	int i;
420*de0e0e4dSAntonio Huete Jimenez 
421*de0e0e4dSAntonio Huete Jimenez 	if (x509 == NULL) {
422*de0e0e4dSAntonio Huete Jimenez 		x509 = sk_X509_value(sk, 0);
423*de0e0e4dSAntonio Huete Jimenez 		start_idx = 1;
424*de0e0e4dSAntonio Huete Jimenez 	}
425*de0e0e4dSAntonio Huete Jimenez 
426*de0e0e4dSAntonio Huete Jimenez 	is_ee = 1;
427*de0e0e4dSAntonio Huete Jimenez 	if (!ssl_security_cert(NULL, ssl, x509, is_ee, out_error))
428*de0e0e4dSAntonio Huete Jimenez 		return 0;
429*de0e0e4dSAntonio Huete Jimenez 
430*de0e0e4dSAntonio Huete Jimenez 	is_ee = 0;
431*de0e0e4dSAntonio Huete Jimenez 	for (i = start_idx; i < sk_X509_num(sk); i++) {
432*de0e0e4dSAntonio Huete Jimenez 		x509 = sk_X509_value(sk, i);
433*de0e0e4dSAntonio Huete Jimenez 
434*de0e0e4dSAntonio Huete Jimenez 		if (!ssl_security_cert(NULL, ssl, x509, is_ee, out_error))
435*de0e0e4dSAntonio Huete Jimenez 			return 0;
436*de0e0e4dSAntonio Huete Jimenez 	}
437*de0e0e4dSAntonio Huete Jimenez 
438*de0e0e4dSAntonio Huete Jimenez 	return 1;
439*de0e0e4dSAntonio Huete Jimenez }
440*de0e0e4dSAntonio Huete Jimenez 
441*de0e0e4dSAntonio Huete Jimenez static int
ssl_security_group(const SSL * ssl,uint16_t group_id,int secop)442*de0e0e4dSAntonio Huete Jimenez ssl_security_group(const SSL *ssl, uint16_t group_id, int secop)
443*de0e0e4dSAntonio Huete Jimenez {
444*de0e0e4dSAntonio Huete Jimenez 	CBB cbb;
445*de0e0e4dSAntonio Huete Jimenez 	int bits, nid;
446*de0e0e4dSAntonio Huete Jimenez 	uint8_t group[2];
447*de0e0e4dSAntonio Huete Jimenez 
448*de0e0e4dSAntonio Huete Jimenez 	if (!tls1_ec_group_id2bits(group_id, &bits))
449*de0e0e4dSAntonio Huete Jimenez 		return 0;
450*de0e0e4dSAntonio Huete Jimenez 	if (!tls1_ec_group_id2nid(group_id, &nid))
451*de0e0e4dSAntonio Huete Jimenez 		return 0;
452*de0e0e4dSAntonio Huete Jimenez 
453*de0e0e4dSAntonio Huete Jimenez 	if (!CBB_init_fixed(&cbb, group, sizeof(group)))
454*de0e0e4dSAntonio Huete Jimenez 		return 0;
455*de0e0e4dSAntonio Huete Jimenez 	if (!CBB_add_u16(&cbb, group_id))
456*de0e0e4dSAntonio Huete Jimenez 		return 0;
457*de0e0e4dSAntonio Huete Jimenez 	if (!CBB_finish(&cbb, NULL, NULL))
458*de0e0e4dSAntonio Huete Jimenez 		return 0;
459*de0e0e4dSAntonio Huete Jimenez 
460*de0e0e4dSAntonio Huete Jimenez 	return ssl_security(ssl, secop, bits, nid, group);
461*de0e0e4dSAntonio Huete Jimenez }
462*de0e0e4dSAntonio Huete Jimenez 
463*de0e0e4dSAntonio Huete Jimenez int
ssl_security_shared_group(const SSL * ssl,uint16_t group_id)464*de0e0e4dSAntonio Huete Jimenez ssl_security_shared_group(const SSL *ssl, uint16_t group_id)
465*de0e0e4dSAntonio Huete Jimenez {
466*de0e0e4dSAntonio Huete Jimenez 	return ssl_security_group(ssl, group_id, SSL_SECOP_CURVE_SHARED);
467*de0e0e4dSAntonio Huete Jimenez }
468*de0e0e4dSAntonio Huete Jimenez 
469*de0e0e4dSAntonio Huete Jimenez int
ssl_security_supported_group(const SSL * ssl,uint16_t group_id)470*de0e0e4dSAntonio Huete Jimenez ssl_security_supported_group(const SSL *ssl, uint16_t group_id)
471*de0e0e4dSAntonio Huete Jimenez {
472*de0e0e4dSAntonio Huete Jimenez 	return ssl_security_group(ssl, group_id, SSL_SECOP_CURVE_SUPPORTED);
473*de0e0e4dSAntonio Huete Jimenez }
474