summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2022-06-29 21:10:20 +0000
committertb <>2022-06-29 21:10:20 +0000
commit607440e43ab60de5b766fe1c327fee120629c3e5 (patch)
tree9b991bf3c95ea651a643e838539ba6ea34f05e16
parent9f44bbceaed6292b842455e640f3de2978aba6e2 (diff)
downloadopenbsd-607440e43ab60de5b766fe1c327fee120629c3e5.tar.gz
openbsd-607440e43ab60de5b766fe1c327fee120629c3e5.tar.bz2
openbsd-607440e43ab60de5b766fe1c327fee120629c3e5.zip
Add functions that check security level in certs and cert chains.
ok beck jsing
-rw-r--r--src/lib/libssl/ssl_locl.h6
-rw-r--r--src/lib/libssl/ssl_seclevel.c143
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,
1300int ssl_security(const SSL *ssl, int op, int bits, int nid, void *other); 1300int ssl_security(const SSL *ssl, int op, int bits, int nid, void *other);
1301int ssl_ctx_security_dh(const SSL_CTX *ctx, DH *dh); 1301int ssl_ctx_security_dh(const SSL_CTX *ctx, DH *dh);
1302int ssl_security_dh(const SSL *ssl, DH *dh); 1302int ssl_security_dh(const SSL *ssl, DH *dh);
1303int ssl_security_cert(const SSL_CTX *ctx, const SSL *ssl, X509 *x509,
1304 int is_peer, int *out_error);
1305int ssl_security_cert_chain(const SSL *ssl, STACK_OF(X509) *sk,
1306 X509 *x509, int *out_error);
1303 1307
1304int ssl_get_new_session(SSL *s, int session); 1308int ssl_get_new_session(SSL *s, int session);
1305int ssl_get_prev_session(SSL *s, CBS *session_id, CBS *ext_block, 1309int 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)
257static int
258ssl_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
273static int
274ssl_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
286static int
287ssl_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
300static int
301ssl_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
315static int
316ssl_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
330int
331ssl_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 */
365int
366ssl_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}