diff options
| author | tb <> | 2022-06-29 21:10:20 +0000 |
|---|---|---|
| committer | tb <> | 2022-06-29 21:10:20 +0000 |
| commit | 56d0eb949deb113577f9b7359153a45269b2b0df (patch) | |
| tree | 9b991bf3c95ea651a643e838539ba6ea34f05e16 /src/lib/libssl/ssl_seclevel.c | |
| parent | 4c53aa472b7cbe56f7f245cb7b8034a5a4fae614 (diff) | |
| download | openbsd-56d0eb949deb113577f9b7359153a45269b2b0df.tar.gz openbsd-56d0eb949deb113577f9b7359153a45269b2b0df.tar.bz2 openbsd-56d0eb949deb113577f9b7359153a45269b2b0df.zip | |
Add functions that check security level in certs and cert chains.
ok beck jsing
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libssl/ssl_seclevel.c | 143 |
1 files changed, 142 insertions, 1 deletions
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 | } | ||
