diff options
author | tb <> | 2022-01-09 15:15:25 +0000 |
---|---|---|
committer | tb <> | 2022-01-09 15:15:25 +0000 |
commit | 12dd2352d38b1ef2237d623bc6b869d169e71567 (patch) | |
tree | b42edbe525fc7c43874d4c14d0981bb1cb4e2d3d /src | |
parent | 98fb653e64884887dde11a1e705e45a6290548d1 (diff) | |
download | openbsd-12dd2352d38b1ef2237d623bc6b869d169e71567.tar.gz openbsd-12dd2352d38b1ef2237d623bc6b869d169e71567.tar.bz2 openbsd-12dd2352d38b1ef2237d623bc6b869d169e71567.zip |
Prepare to provide EVP_MD_CTX{,_set}_pkey_ctx()
This API with very strange ownership handling is used by Ruby 3.1,
unfortunately.
For unclear reasons, it was decided that the caller retains ownership of
the pctx passed in. EVP_PKEY_CTX aren't refcounted, so a flag was added to
make sure that md_ctx->pctx is not freed in EVP_MD_CTX_{cleanup,reset}().
Since EVP_MD_CTX_copy_ex() duplicates the md_ctx->pctx, the flag also needs
to be unset on the duplicated EVP_MD_CTX.
ok inoguchi jsing
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/evp/digest.c | 15 | ||||
-rw-r--r-- | src/lib/libcrypto/evp/evp.h | 6 | ||||
-rw-r--r-- | src/lib/libcrypto/evp/evp_lib.c | 31 | ||||
-rw-r--r-- | src/lib/libcrypto/evp/evp_locl.h | 8 |
4 files changed, 55 insertions, 5 deletions
diff --git a/src/lib/libcrypto/evp/digest.c b/src/lib/libcrypto/evp/digest.c index 59c98b57b8..fd42318044 100644 --- a/src/lib/libcrypto/evp/digest.c +++ b/src/lib/libcrypto/evp/digest.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: digest.c,v 1.32 2021/12/12 21:30:13 tb Exp $ */ | 1 | /* $OpenBSD: digest.c,v 1.33 2022/01/09 15:15:25 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 | * |
@@ -282,6 +282,12 @@ EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) | |||
282 | EVP_MD_CTX_cleanup(out); | 282 | EVP_MD_CTX_cleanup(out); |
283 | memcpy(out, in, sizeof *out); | 283 | memcpy(out, in, sizeof *out); |
284 | 284 | ||
285 | /* | ||
286 | * Because of the EVP_PKEY_CTX_dup() below, EVP_MD_CTX_cleanup() needs | ||
287 | * to free out->pctx in all cases (even if this flag is set on in). | ||
288 | */ | ||
289 | EVP_MD_CTX_clear_flags(out, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); | ||
290 | |||
285 | if (in->md_data && out->digest->ctx_size) { | 291 | if (in->md_data && out->digest->ctx_size) { |
286 | if (tmp_buf) { | 292 | if (tmp_buf) { |
287 | out->md_data = tmp_buf; | 293 | out->md_data = tmp_buf; |
@@ -383,7 +389,12 @@ EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) | |||
383 | if (ctx->digest && ctx->digest->ctx_size && ctx->md_data && | 389 | if (ctx->digest && ctx->digest->ctx_size && ctx->md_data && |
384 | !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) | 390 | !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) |
385 | freezero(ctx->md_data, ctx->digest->ctx_size); | 391 | freezero(ctx->md_data, ctx->digest->ctx_size); |
386 | EVP_PKEY_CTX_free(ctx->pctx); | 392 | /* |
393 | * If EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set, EVP_MD_CTX_set_pkey() was | ||
394 | * called and its strange API contract implies we don't own ctx->pctx. | ||
395 | */ | ||
396 | if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) | ||
397 | EVP_PKEY_CTX_free(ctx->pctx); | ||
387 | #ifndef OPENSSL_NO_ENGINE | 398 | #ifndef OPENSSL_NO_ENGINE |
388 | ENGINE_finish(ctx->engine); | 399 | ENGINE_finish(ctx->engine); |
389 | #endif | 400 | #endif |
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h index b5afa477da..aa5b35f67c 100644 --- a/src/lib/libcrypto/evp/evp.h +++ b/src/lib/libcrypto/evp/evp.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: evp.h,v 1.91 2022/01/07 21:58:17 tb Exp $ */ | 1 | /* $OpenBSD: evp.h,v 1.92 2022/01/09 15:15:25 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 | * |
@@ -497,6 +497,10 @@ unsigned long EVP_MD_flags(const EVP_MD *md); | |||
497 | 497 | ||
498 | const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); | 498 | const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); |
499 | void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx); | 499 | void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx); |
500 | #if defined(LIBRESSL_CRYPTO_INTERANL) || defined(LIBRESSL_NEXT_API) | ||
501 | EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx); | ||
502 | void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx); | ||
503 | #endif | ||
500 | #define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e)) | 504 | #define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e)) |
501 | #define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e)) | 505 | #define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e)) |
502 | #define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e)) | 506 | #define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e)) |
diff --git a/src/lib/libcrypto/evp/evp_lib.c b/src/lib/libcrypto/evp/evp_lib.c index 8070fa45ae..c96813987f 100644 --- a/src/lib/libcrypto/evp/evp_lib.c +++ b/src/lib/libcrypto/evp/evp_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: evp_lib.c,v 1.22 2022/01/07 11:13:54 tb Exp $ */ | 1 | /* $OpenBSD: evp_lib.c,v 1.23 2022/01/09 15:15:25 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 | * |
@@ -385,6 +385,35 @@ EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx) | |||
385 | return ctx->md_data; | 385 | return ctx->md_data; |
386 | } | 386 | } |
387 | 387 | ||
388 | EVP_PKEY_CTX * | ||
389 | EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx) | ||
390 | { | ||
391 | return ctx->pctx; | ||
392 | } | ||
393 | |||
394 | void | ||
395 | EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx) | ||
396 | { | ||
397 | if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) { | ||
398 | EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); | ||
399 | } else { | ||
400 | EVP_PKEY_CTX_free(ctx->pctx); | ||
401 | } | ||
402 | |||
403 | ctx->pctx = pctx; | ||
404 | |||
405 | if (pctx != NULL) { | ||
406 | /* | ||
407 | * For unclear reasons it was decided that the caller keeps | ||
408 | * ownership of pctx. So a flag was invented to make sure we | ||
409 | * don't free it in EVP_MD_CTX_cleanup(). We also need to | ||
410 | * unset it in EVP_MD_CTX_copy_ex(). Fortunately, the flag | ||
411 | * isn't public... | ||
412 | */ | ||
413 | EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); | ||
414 | } | ||
415 | } | ||
416 | |||
388 | void | 417 | void |
389 | EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags) | 418 | EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags) |
390 | { | 419 | { |
diff --git a/src/lib/libcrypto/evp/evp_locl.h b/src/lib/libcrypto/evp/evp_locl.h index ec4cc6d63d..5eef0b244f 100644 --- a/src/lib/libcrypto/evp/evp_locl.h +++ b/src/lib/libcrypto/evp/evp_locl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: evp_locl.h,v 1.17 2021/12/12 21:21:58 tb Exp $ */ | 1 | /* $OpenBSD: evp_locl.h,v 1.18 2022/01/09 15:15:25 tb Exp $ */ |
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
3 | * project 2000. | 3 | * project 2000. |
4 | */ | 4 | */ |
@@ -61,6 +61,12 @@ | |||
61 | 61 | ||
62 | __BEGIN_HIDDEN_DECLS | 62 | __BEGIN_HIDDEN_DECLS |
63 | 63 | ||
64 | /* | ||
65 | * Don't free md_ctx->pctx in EVP_MD_CTX_cleanup(). Needed for ownership | ||
66 | * handling in EVP_MD_CTX_set_pkey_ctx(). | ||
67 | */ | ||
68 | #define EVP_MD_CTX_FLAG_KEEP_PKEY_CTX 0x0400 | ||
69 | |||
64 | /* Macros to code block cipher wrappers */ | 70 | /* Macros to code block cipher wrappers */ |
65 | 71 | ||
66 | /* Wrapper functions for each cipher mode */ | 72 | /* Wrapper functions for each cipher mode */ |