summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorop <>2023-05-25 07:46:21 +0000
committerop <>2023-05-25 07:46:21 +0000
commitd9e5f520e02c69e7bb007ce9e7466dbf19dad201 (patch)
tree5528bbfa78941f58360ca3ddf165e208510ee895
parent586ba9a5155b6cb379d532ed6383502ab9832610 (diff)
downloadopenbsd-d9e5f520e02c69e7bb007ce9e7466dbf19dad201.tar.gz
openbsd-d9e5f520e02c69e7bb007ce9e7466dbf19dad201.tar.bz2
openbsd-d9e5f520e02c69e7bb007ce9e7466dbf19dad201.zip
Forcibly update the EVP_PKEY's internal key
To aid privilege separation, libtls maintains application-specific data on the key inside the EVP_PKEY abstraction because the EVP API doesn't provide a way to do that on the EVP_PKEY itself. OpenSSL 3 changed behavior of EVP_PKEY_get1_RSA() and related functions. These now return a struct from some cache. Thus, modifying the RSA will no longer modify the EVP_PKEY like it did previously, which was clearly implied to be the case in the older documentation. This is a subtle breaking change that affects several applications. While this is documented, no real solution is provided. The transition plan from one OpenSSL major version to the next one tends to involve many #ifdef in the ecosystem, and the only suggestion provided by the new documentation is to switch to a completely unrelated, new API. Instead, forcibly reset the internal key on EVP_PKEY after modification, this way the change is picked up also by OpenSSL 3. Fixes issue 1171 in OpenSMTPD-portable ok tb@, jsing@
-rw-r--r--src/lib/libtls/tls.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/src/lib/libtls/tls.c b/src/lib/libtls/tls.c
index f3e7148f0d..989339dc03 100644
--- a/src/lib/libtls/tls.c
+++ b/src/lib/libtls/tls.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls.c,v 1.95 2023/05/14 07:26:25 op Exp $ */ 1/* $OpenBSD: tls.c,v 1.96 2023/05/25 07:46:21 op Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -410,12 +410,18 @@ tls_keypair_setup_pkey(struct tls *ctx, struct tls_keypair *keypair, EVP_PKEY *p
410 tls_set_errorx(ctx, "RSA key setup failure"); 410 tls_set_errorx(ctx, "RSA key setup failure");
411 goto err; 411 goto err;
412 } 412 }
413 if (ctx->config->sign_cb == NULL) 413 if (ctx->config->sign_cb != NULL) {
414 break; 414 rsa_method = tls_signer_rsa_method();
415 if ((rsa_method = tls_signer_rsa_method()) == NULL || 415 if (rsa_method == NULL ||
416 RSA_set_ex_data(rsa, 1, ctx->config) == 0 || 416 RSA_set_ex_data(rsa, 1, ctx->config) == 0 ||
417 RSA_set_method(rsa, rsa_method) == 0) { 417 RSA_set_method(rsa, rsa_method) == 0) {
418 tls_set_errorx(ctx, "failed to setup RSA key"); 418 tls_set_errorx(ctx, "failed to setup RSA key");
419 goto err;
420 }
421 }
422 /* Reset the key to work around caching in OpenSSL 3. */
423 if (EVP_PKEY_set1_RSA(pkey, rsa) == 0) {
424 tls_set_errorx(ctx, "failed to set RSA key");
419 goto err; 425 goto err;
420 } 426 }
421 break; 427 break;
@@ -425,12 +431,18 @@ tls_keypair_setup_pkey(struct tls *ctx, struct tls_keypair *keypair, EVP_PKEY *p
425 tls_set_errorx(ctx, "EC key setup failure"); 431 tls_set_errorx(ctx, "EC key setup failure");
426 goto err; 432 goto err;
427 } 433 }
428 if (ctx->config->sign_cb == NULL) 434 if (ctx->config->sign_cb != NULL) {
429 break; 435 ecdsa_method = tls_signer_ecdsa_method();
430 if ((ecdsa_method = tls_signer_ecdsa_method()) == NULL || 436 if (ecdsa_method == NULL ||
431 ECDSA_set_ex_data(eckey, 1, ctx->config) == 0 || 437 ECDSA_set_ex_data(eckey, 1, ctx->config) == 0 ||
432 ECDSA_set_method(eckey, ecdsa_method) == 0) { 438 ECDSA_set_method(eckey, ecdsa_method) == 0) {
433 tls_set_errorx(ctx, "failed to setup EC key"); 439 tls_set_errorx(ctx, "failed to setup EC key");
440 goto err;
441 }
442 }
443 /* Reset the key to work around caching in OpenSSL 3. */
444 if (EVP_PKEY_set1_EC_KEY(pkey, eckey) == 0) {
445 tls_set_errorx(ctx, "failed to set EC key");
434 goto err; 446 goto err;
435 } 447 }
436 break; 448 break;