From da22ccf48ff3884f68b57cca13b483679ea233e5 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 24 Nov 2025 10:30:07 +0900 Subject: [PATCH] openssl-util: introduce openssl_extract_public_key() helper function This splits out common logic in keyutil and systemd-measure. Note, previously d2i_PUBKEY_fp() was used, but now it is replaced with d2i_PUBKEY(), as musl seems to not support reading from memstream. --- src/keyutil/keyutil.c | 19 +++---------------- src/measure/measure-tool.c | 22 +++------------------- src/shared/openssl-util.c | 27 +++++++++++++++++++++++++++ src/shared/openssl-util.h | 2 ++ 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/keyutil/keyutil.c b/src/keyutil/keyutil.c index d94d2153c2a..f19718a11f2 100644 --- a/src/keyutil/keyutil.c +++ b/src/keyutil/keyutil.c @@ -10,7 +10,6 @@ #include "fs-util.h" #include "log.h" #include "main-func.h" -#include "memstream-util.h" #include "openssl-util.h" #include "parse-argument.h" #include "pretty-print.h" @@ -303,21 +302,9 @@ static int verb_public(int argc, char *argv[], void *userdata) { if (r < 0) return log_error_errno(r, "Failed to load private key from %s: %m", arg_private_key); - _cleanup_(memstream_done) MemStream m = {}; - FILE *tf = memstream_init(&m); - if (!tf) - return log_oom(); - - if (i2d_PUBKEY_fp(tf, private_key) != 1) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to extract public key from private key file '%s'.", arg_private_key); - - fflush(tf); - rewind(tf); - - if (!d2i_PUBKEY_fp(tf, &public_key)) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to parse extracted public key of private key file '%s'.", arg_private_key); + r = openssl_extract_public_key(private_key, &public_key); + if (r < 0) + return log_error_errno(r, "Failed to extract public key from private key file '%s': %m", arg_private_key); } else return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "One of --certificate=, or --private-key= must be specified"); diff --git a/src/measure/measure-tool.c b/src/measure/measure-tool.c index 0d5ceb9faff..3c8acf64176 100644 --- a/src/measure/measure-tool.c +++ b/src/measure/measure-tool.c @@ -15,7 +15,6 @@ #include "hexdecoct.h" #include "log.h" #include "main-func.h" -#include "memstream-util.h" #include "openssl-util.h" #include "pager.h" #include "parse-argument.h" @@ -890,25 +889,10 @@ static int build_policy_digest(bool sign) { "Failed to extract public key from certificate %s.", arg_certificate); } else if (sign) { - _cleanup_(memstream_done) MemStream m = {}; - FILE *tf; - /* No public key was specified, let's derive it automatically, if we can, when signing */ - - tf = memstream_init(&m); - if (!tf) - return log_oom(); - - if (i2d_PUBKEY_fp(tf, privkey) != 1) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to extract public key from private key file '%s'.", arg_private_key); - - fflush(tf); - rewind(tf); - - if (!d2i_PUBKEY_fp(tf, &pubkey)) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to parse extracted public key of private key file '%s'.", arg_private_key); + r = openssl_extract_public_key(privkey, &pubkey); + if (r < 0) + return log_error_errno(r, "Failed to extract public key from private key file '%s': %m", arg_private_key); } r = pcr_states_allocate(&pcr_states); diff --git a/src/shared/openssl-util.c b/src/shared/openssl-util.c index 8fb23a8f923..b8911c1b303 100644 --- a/src/shared/openssl-util.c +++ b/src/shared/openssl-util.c @@ -1753,6 +1753,33 @@ int openssl_load_private_key( return 0; } + +int openssl_extract_public_key(EVP_PKEY *private_key, EVP_PKEY **ret) { + int r; + + assert(private_key); + assert(ret); + + _cleanup_(memstream_done) MemStream m = {}; + FILE *tf = memstream_init(&m); + if (!tf) + return log_oom(); + + if (i2d_PUBKEY_fp(tf, private_key) != 1) + return -EIO; + + _cleanup_(erase_and_freep) char *buf = NULL; + size_t len; + r = memstream_finalize(&m, &buf, &len); + if (r < 0) + return r; + + const unsigned char *t = (unsigned char*) buf; + if (!d2i_PUBKEY(ret, &t, len)) + return -EIO; + + return 0; +} #endif int parse_openssl_certificate_source_argument( diff --git a/src/shared/openssl-util.h b/src/shared/openssl-util.h index 72b9cfcc902..cb48ea8bfd3 100644 --- a/src/shared/openssl-util.h +++ b/src/shared/openssl-util.h @@ -195,6 +195,8 @@ int openssl_load_private_key( EVP_PKEY **ret_private_key, OpenSSLAskPasswordUI **ret_user_interface); +int openssl_extract_public_key(EVP_PKEY *private_key, EVP_PKEY **ret); + struct OpenSSLAskPasswordUI { AskPasswordRequest request; #ifndef OPENSSL_NO_UI_CONSOLE -- 2.47.3