diff options
author | tb <> | 2022-06-29 21:10:20 +0000 |
---|---|---|
committer | tb <> | 2022-06-29 21:10:20 +0000 |
commit | 607440e43ab60de5b766fe1c327fee120629c3e5 (patch) | |
tree | 9b991bf3c95ea651a643e838539ba6ea34f05e16 /src | |
parent | 9f44bbceaed6292b842455e640f3de2978aba6e2 (diff) | |
download | openbsd-607440e43ab60de5b766fe1c327fee120629c3e5.tar.gz openbsd-607440e43ab60de5b766fe1c327fee120629c3e5.tar.bz2 openbsd-607440e43ab60de5b766fe1c327fee120629c3e5.zip |
Add functions that check security level in certs and cert chains.
ok beck jsing
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 6 | ||||
-rw-r--r-- | src/lib/libssl/ssl_seclevel.c | 143 |
2 files changed, 147 insertions, 2 deletions
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index d979baf301..161a8407af 100644 --- a/src/lib/libssl/ssl_locl.h +++ b/src/lib/libssl/ssl_locl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_locl.h,v 1.403 2022/06/29 20:04:28 tb Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.404 2022/06/29 21:10:20 tb Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -1300,6 +1300,10 @@ int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid, | |||
1300 | int ssl_security(const SSL *ssl, int op, int bits, int nid, void *other); | 1300 | int ssl_security(const SSL *ssl, int op, int bits, int nid, void *other); |
1301 | int ssl_ctx_security_dh(const SSL_CTX *ctx, DH *dh); | 1301 | int ssl_ctx_security_dh(const SSL_CTX *ctx, DH *dh); |
1302 | int ssl_security_dh(const SSL *ssl, DH *dh); | 1302 | int ssl_security_dh(const SSL *ssl, DH *dh); |
1303 | int ssl_security_cert(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, | ||
1304 | int is_peer, int *out_error); | ||
1305 | int ssl_security_cert_chain(const SSL *ssl, STACK_OF(X509) *sk, | ||
1306 | X509 *x509, int *out_error); | ||
1303 | 1307 | ||
1304 | int ssl_get_new_session(SSL *s, int session); | 1308 | int ssl_get_new_session(SSL *s, int session); |
1305 | int ssl_get_prev_session(SSL *s, CBS *session_id, CBS *ext_block, | 1309 | int ssl_get_prev_session(SSL *s, CBS *session_id, CBS *ext_block, |
diff --git a/src/lib/libssl/ssl_seclevel.c b/src/lib/libssl/ssl_seclevel.c index 1db2a2dbcd..b24999498c 100644 --- a/src/lib/libssl/ssl_seclevel.c +++ b/src/lib/libssl/ssl_seclevel.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_seclevel.c,v 1.8 2022/06/29 11:59:23 tb Exp $ */ | 1 | /* $OpenBSD: ssl_seclevel.c,v 1.9 2022/06/29 21:10:20 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2020 Theo Buehler <tb@openbsd.org> | 3 | * Copyright (c) 2020 Theo Buehler <tb@openbsd.org> |
4 | * | 4 | * |
@@ -17,10 +17,15 @@ | |||
17 | 17 | ||
18 | #include <stddef.h> | 18 | #include <stddef.h> |
19 | 19 | ||
20 | #include <openssl/asn1.h> | ||
20 | #include <openssl/dh.h> | 21 | #include <openssl/dh.h> |
22 | #include <openssl/evp.h> | ||
23 | #include <openssl/obj_mac.h> | ||
24 | #include <openssl/objects.h> | ||
21 | #include <openssl/ossl_typ.h> | 25 | #include <openssl/ossl_typ.h> |
22 | #include <openssl/ssl.h> | 26 | #include <openssl/ssl.h> |
23 | #include <openssl/tls1.h> | 27 | #include <openssl/tls1.h> |
28 | #include <openssl/x509.h> | ||
24 | 29 | ||
25 | #include "ssl_locl.h" | 30 | #include "ssl_locl.h" |
26 | 31 | ||
@@ -247,3 +252,139 @@ ssl_security_dh(const SSL *ssl, DH *dh) | |||
247 | return 1; | 252 | return 1; |
248 | #endif | 253 | #endif |
249 | } | 254 | } |
255 | |||
256 | #if defined(LIBRESSL_HAS_SECURITY_LEVEL) | ||
257 | static int | ||
258 | ssl_cert_pubkey_security_bits(const X509 *x509) | ||
259 | { | ||
260 | EVP_PKEY *pkey; | ||
261 | |||
262 | if ((pkey = X509_get0_pubkey(x509)) == NULL) | ||
263 | return -1; | ||
264 | |||
265 | /* | ||
266 | * XXX: DSA_security_bits() returns -1 on keys without parameters and | ||
267 | * cause the default security callback to fail. | ||
268 | */ | ||
269 | |||
270 | return EVP_PKEY_security_bits(pkey); | ||
271 | } | ||
272 | |||
273 | static int | ||
274 | ssl_security_cert_key(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, int op) | ||
275 | { | ||
276 | int security_bits; | ||
277 | |||
278 | security_bits = ssl_cert_pubkey_security_bits(x509); | ||
279 | |||
280 | if (ssl != NULL) | ||
281 | return ssl_security(ssl, op, security_bits, 0, x509); | ||
282 | |||
283 | return ssl_ctx_security(ctx, op, security_bits, 0, x509); | ||
284 | } | ||
285 | |||
286 | static int | ||
287 | ssl_cert_signature_md_nid(const X509 *x509) | ||
288 | { | ||
289 | int md_nid, signature_nid; | ||
290 | |||
291 | if ((signature_nid = X509_get_signature_nid(x509)) == NID_undef) | ||
292 | return NID_undef; | ||
293 | |||
294 | if (!OBJ_find_sigid_algs(signature_nid, &md_nid, NULL)) | ||
295 | return NID_undef; | ||
296 | |||
297 | return md_nid; | ||
298 | } | ||
299 | |||
300 | static int | ||
301 | ssl_cert_md_nid_security_bits(int md_nid) | ||
302 | { | ||
303 | const EVP_MD *md; | ||
304 | |||
305 | if (md_nid == NID_undef) | ||
306 | return -1; | ||
307 | |||
308 | if ((md = EVP_get_digestbynid(md_nid)) == NULL) | ||
309 | return -1; | ||
310 | |||
311 | /* Assume 4 bits of collision resistance for each hash octet. */ | ||
312 | return EVP_MD_size(md) * 4; | ||
313 | } | ||
314 | |||
315 | static int | ||
316 | ssl_security_cert_sig(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, int op) | ||
317 | { | ||
318 | int md_nid, security_bits; | ||
319 | |||
320 | md_nid = ssl_cert_signature_md_nid(x509); | ||
321 | security_bits = ssl_cert_md_nid_security_bits(md_nid); | ||
322 | |||
323 | if (ssl != NULL) | ||
324 | return ssl_security(ssl, op, security_bits, md_nid, x509); | ||
325 | |||
326 | return ssl_ctx_security(ctx, op, security_bits, md_nid, x509); | ||
327 | } | ||
328 | #endif | ||
329 | |||
330 | int | ||
331 | ssl_security_cert(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, | ||
332 | int is_ee, int *out_error) | ||
333 | { | ||
334 | #if defined(LIBRESSL_HAS_SECURITY_LEVEL) | ||
335 | int key_error, operation; | ||
336 | |||
337 | *out_error = 0; | ||
338 | |||
339 | if (is_ee) { | ||
340 | operation = SSL_SECOP_EE_KEY; | ||
341 | key_error = SSL_R_EE_KEY_TOO_SMALL; | ||
342 | } else { | ||
343 | operation = SSL_SECOP_CA_KEY; | ||
344 | key_error = SSL_R_CA_KEY_TOO_SMALL; | ||
345 | } | ||
346 | |||
347 | if (!ssl_security_cert_key(ctx, ssl, x509, operation)) { | ||
348 | *out_error = key_error; | ||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | if (!ssl_security_cert_sig(ctx, ssl, x509, SSL_SECOP_CA_MD)) { | ||
353 | *out_error = SSL_R_CA_MD_TOO_WEAK; | ||
354 | return 0; | ||
355 | } | ||
356 | |||
357 | #endif | ||
358 | return 1; | ||
359 | } | ||
360 | |||
361 | /* | ||
362 | * Check security of a chain. If |sk| includes the end entity certificate | ||
363 | * then |x509| must be NULL. | ||
364 | */ | ||
365 | int | ||
366 | ssl_security_cert_chain(const SSL *ssl, STACK_OF(X509) *sk, X509 *x509, | ||
367 | int *out_error) | ||
368 | { | ||
369 | int start_idx = 0; | ||
370 | int is_ee; | ||
371 | int i; | ||
372 | |||
373 | if (x509 == NULL) { | ||
374 | x509 = sk_X509_value(sk, 0); | ||
375 | start_idx = 1; | ||
376 | } | ||
377 | |||
378 | if (!ssl_security_cert(NULL, ssl, x509, is_ee = 1, out_error)) | ||
379 | return 0; | ||
380 | |||
381 | for (i = start_idx; i < sk_X509_num(sk); i++) { | ||
382 | x509 = sk_X509_value(sk, i); | ||
383 | |||
384 | if (!ssl_security_cert(NULL, ssl, x509, is_ee = 0, | ||
385 | out_error)) | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | return 1; | ||
390 | } | ||