diff options
Diffstat (limited to '')
-rw-r--r-- | src/lib/libssl/ssl_seclevel.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/src/lib/libssl/ssl_seclevel.c b/src/lib/libssl/ssl_seclevel.c index 6a5d16bfaa..1448368e71 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.28 2024/05/09 07:12:03 tb Exp $ */ | 1 | /* $OpenBSD: ssl_seclevel.c,v 1.29 2024/10/17 06:19:06 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2020-2022 Theo Buehler <tb@openbsd.org> | 3 | * Copyright (c) 2020-2022 Theo Buehler <tb@openbsd.org> |
4 | * | 4 | * |
@@ -331,45 +331,49 @@ ssl_security_cert_key(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, int secop) | |||
331 | } | 331 | } |
332 | 332 | ||
333 | static int | 333 | static int |
334 | ssl_cert_signature_md_nid(X509 *x509) | 334 | ssl_security_cert_sig_security_bits(X509 *x509, int *out_md_nid) |
335 | { | 335 | { |
336 | int md_nid, signature_nid; | 336 | int pkey_nid, security_bits; |
337 | uint32_t flags; | ||
337 | 338 | ||
338 | if ((signature_nid = X509_get_signature_nid(x509)) == NID_undef) | 339 | *out_md_nid = NID_undef; |
339 | return NID_undef; | ||
340 | 340 | ||
341 | if (!OBJ_find_sigid_algs(signature_nid, &md_nid, NULL)) | 341 | /* |
342 | return NID_undef; | 342 | * Returning -1 security bits makes the default security callback fail |
343 | 343 | * to match bonkers behavior in OpenSSL. This in turn lets a security | |
344 | return md_nid; | 344 | * callback override such failures. |
345 | } | 345 | */ |
346 | 346 | if (!X509_get_signature_info(x509, out_md_nid, &pkey_nid, &security_bits, | |
347 | static int | 347 | &flags)) |
348 | ssl_cert_md_nid_security_bits(int md_nid) | ||
349 | { | ||
350 | const EVP_MD *md; | ||
351 | |||
352 | if (md_nid == NID_undef) | ||
353 | return -1; | 348 | return -1; |
354 | 349 | /* | |
355 | if ((md = EVP_get_digestbynid(md_nid)) == NULL) | 350 | * OpenSSL doesn't check flags. Test RSA-PSS certs we were provided have |
351 | * a salt length distinct from hash length and thus fail this check. | ||
352 | */ | ||
353 | if ((flags & X509_SIG_INFO_TLS) == 0) | ||
356 | return -1; | 354 | return -1; |
357 | 355 | ||
358 | /* Assume 4 bits of collision resistance for each hash octet. */ | 356 | /* Weird OpenSSL behavior only relevant for EdDSA certs in LibreSSL. */ |
359 | return EVP_MD_size(md) * 4; | 357 | if (*out_md_nid == NID_undef) |
358 | *out_md_nid = pkey_nid; | ||
359 | |||
360 | return security_bits; | ||
360 | } | 361 | } |
361 | 362 | ||
362 | static int | 363 | static int |
363 | ssl_security_cert_sig(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, int secop) | 364 | ssl_security_cert_sig(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, int secop) |
364 | { | 365 | { |
365 | int md_nid, security_bits; | 366 | int md_nid = NID_undef, security_bits = -1; |
366 | 367 | ||
367 | /* Don't check signature if self signed. */ | 368 | /* Don't check signature if self signed. */ |
368 | if ((X509_get_extension_flags(x509) & EXFLAG_SS) != 0) | 369 | if ((X509_get_extension_flags(x509) & EXFLAG_SS) != 0) |
369 | return 1; | 370 | return 1; |
370 | 371 | ||
371 | md_nid = ssl_cert_signature_md_nid(x509); | 372 | /* |
372 | security_bits = ssl_cert_md_nid_security_bits(md_nid); | 373 | * The default security callback fails on -1 security bits. It ignores |
374 | * the md_nid (aka version) argument we pass from here. | ||
375 | */ | ||
376 | security_bits = ssl_security_cert_sig_security_bits(x509, &md_nid); | ||
373 | 377 | ||
374 | if (ssl != NULL) | 378 | if (ssl != NULL) |
375 | return ssl_security(ssl, secop, security_bits, md_nid, x509); | 379 | return ssl_security(ssl, secop, security_bits, md_nid, x509); |