From 9c6deb5733306025947a1d438a2dd4d44413a58b Mon Sep 17 00:00:00 2001 From: David Seifert Date: Sun, 25 Oct 2026 14:28:29 +0100 Subject: [PATCH] sign-efi-sig-list, efi-updatevar: replace ENGINE key loading with OpenSSL providers The ENGINE API is deprecated since OpenSSL 3.0 and removed in OpenSSL 4, so efitools no longer builds against it. Make read_private_key() load the "default" provider plus the requested one and read the private key through OSSL_STORE, prompting for a pass phrase or PIN via a UI method. The -e option of sign-efi-sig-list becomes -p , and the --engine option of efi-updatevar becomes --provider. The key argument is now an OSSL_STORE URI, e.g. sign-efi-sig-list -p pkcs11 -k 'pkcs11:token=foo;object=bar' ... --- efi-updatevar.c | 10 +++---- include/openssl_sign.h | 4 +-- lib/openssl_sign.c | 59 ++++++++++++++++++++++++++---------------- sign-efi-sig-list.c | 12 ++++----- 4 files changed, 50 insertions(+), 35 deletions(-) diff --git a/efi-updatevar.c b/efi-updatevar.c index 4247105..374a182 100644 --- a/efi-updatevar.c +++ b/efi-updatevar.c @@ -52,7 +52,7 @@ help(const char *progname) "\t-g \tOptional for the X509 Certificate\n" "\t-k \tSecret key file for authorising User Mode updates\n" "\t-d [-]\tDelete the signature list (or just a single within the list)\n" - "\t--engine \tUse engine for private key\n" + "\t--provider \tUse provider for private key\n" ); } @@ -61,7 +61,7 @@ main(int argc, char *argv[]) { char *variables[] = { "PK", "KEK", "db", "dbx" }; char *signedby[] = { "PK", "PK", "KEK", "KEK" }; - char *engine = NULL; + char *provider = NULL; EFI_GUID *owners[] = { &GV_GUID, &GV_GUID, &SIG_DB, &SIG_DB }; EFI_GUID *owner, guid = MOK_OWNER; int i, esl_mode = 0, fd, ret, delsig = -1, delentry = -1; @@ -116,8 +116,8 @@ main(int argc, char *argv[]) sscanf(argv[2], "%d-%d", &delsig, &delentry); argv += 2; argc -= 2; - } else if (strcmp(argv[1], "--engine") == 0) { - engine = argv[2]; + } else if (strcmp(argv[1], "--provider") == 0) { + provider = argv[2]; argv += 2; argc -= 2; } else { @@ -286,7 +286,7 @@ main(int argc, char *argv[]) fprintf(stderr, "Can't update variable%s without a key\n", variable_is_setupmode() ? "" : " in User Mode"); exit(1); } - EVP_PKEY *pkey = read_private_key(engine, key_file); + EVP_PKEY *pkey = read_private_key(provider, key_file); if (!pkey) { fprintf(stderr, "error reading private key %s\n", key_file); exit(1); diff --git a/include/openssl_sign.h b/include/openssl_sign.h index 136ad75..18f8be6 100644 --- a/include/openssl_sign.h +++ b/include/openssl_sign.h @@ -2,9 +2,9 @@ int sign_efi_var(char *payload, int payload_size, char *keyfile, char *certfile, - unsigned char **sig, int *sigsize, char *engine); + unsigned char **sig, int *sigsize, char *provider); int sign_efi_var_ssl(char *payload, int payload_size, EVP_PKEY *pkey, X509 *cert, unsigned char **sig, int *sigsize); EVP_PKEY * -read_private_key(char *engine, char *keyfile); +read_private_key(char *provider, char *keyfile); diff --git a/lib/openssl_sign.c b/lib/openssl_sign.c index 714ce1a..be02fc6 100644 --- a/lib/openssl_sign.c +++ b/lib/openssl_sign.c @@ -7,7 +7,9 @@ #include #include #include -#include +#include +#include +#include #include @@ -33,7 +35,7 @@ sign_efi_var_ssl(char *payload, int payload_size, EVP_PKEY *pkey, X509 *cert, int sign_efi_var(char *payload, int payload_size, char *keyfile, char *certfile, - unsigned char **sig, int *sigsize, char *engine) + unsigned char **sig, int *sigsize, char *provider) { int ret; @@ -60,7 +62,7 @@ sign_efi_var(char *payload, int payload_size, char *keyfile, char *certfile, return 1; } - EVP_PKEY *pkey = read_private_key(engine, keyfile); + EVP_PKEY *pkey = read_private_key(provider, keyfile); if (!pkey) { ERR_print_errors_fp(stdout); fprintf(stderr, "error reading private key %s\n", keyfile); @@ -103,54 +105,67 @@ static int ui_read(UI *ui, UI_STRING *uis) if (UI_get_string_type(uis) != UIT_PROMPT) return 0; - EVP_read_pw_string(password, sizeof(password), "Enter engine key pass phrase:", 0); + EVP_read_pw_string(password, sizeof(password), "Enter key pass phrase:", 0); UI_set_result(ui, uis, password); return 1; } static EVP_PKEY * -read_engine_private_key(char *engine, char *keyfile) +read_provider_private_key(char *provider, char *uri) { UI_METHOD *ui; - ENGINE *e; + OSSL_STORE_CTX *store; + OSSL_STORE_INFO *info; EVP_PKEY *pkey = NULL; - ENGINE_load_builtin_engines(); - e = ENGINE_by_id(engine); - - if (!e) { - fprintf(stderr, "Failed to load engine: %s\n", engine); + /* explicitly loading any provider disables the implicit default + * provider, which we still need for digests and PKCS#7 */ + if (!OSSL_PROVIDER_load(NULL, "default") || + !OSSL_PROVIDER_load(NULL, provider)) { + fprintf(stderr, "Failed to load provider: %s\n", provider); ERR_print_errors_fp(stderr); return NULL; } - ui = UI_create_method("sbsigntools"); + ui = UI_create_method("efitools"); if (!ui) { fprintf(stderr, "Failed to create UI method\n"); ERR_print_errors_fp(stderr); - goto out_free; + return NULL; } UI_method_set_reader(ui, ui_read); - if (!ENGINE_init(e)) { - fprintf(stderr, "Failed to initialize engine %s\n", engine); + store = OSSL_STORE_open(uri, ui, NULL, NULL, NULL); + if (!store) { + fprintf(stderr, "Failed to open key store: %s\n", uri); ERR_print_errors_fp(stderr); goto out_free; } - - pkey = ENGINE_load_private_key(e, keyfile, ui, NULL); - ENGINE_finish(e); + OSSL_STORE_expect(store, OSSL_STORE_INFO_PKEY); + + while (!pkey && !OSSL_STORE_eof(store)) { + info = OSSL_STORE_load(store); + if (!info) { + if (OSSL_STORE_error(store)) + break; + continue; + } + if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) + pkey = OSSL_STORE_INFO_get1_PKEY(info); + OSSL_STORE_INFO_free(info); + } + OSSL_STORE_close(store); out_free: - ENGINE_free(e); + UI_destroy_method(ui); return pkey; } EVP_PKEY * -read_private_key(char *engine, char *keyfile) +read_private_key(char *provider, char *keyfile) { - if (engine) - return read_engine_private_key(engine, keyfile); + if (provider) + return read_provider_private_key(provider, keyfile); else return read_pem_private_key(keyfile); } diff --git a/sign-efi-sig-list.c b/sign-efi-sig-list.c index 94bd7d4..8869b6a 100644 --- a/sign-efi-sig-list.c +++ b/sign-efi-sig-list.c @@ -31,7 +31,7 @@ static void usage(const char *progname) { - printf("Usage: %s [-r] [-m] [-a] [-g ] [-o] [-t ] [-i ] [-c ] [-k ] [-e ] \n", progname); + printf("Usage: %s [-r] [-m] [-a] [-g ] [-o] [-t ] [-i ] [-c ] [-k ] [-p ] \n", progname); } static void @@ -56,7 +56,7 @@ help(const char *progname) "\t-g Use as the signature owner GUID\n" "\t-c is the file containing the signing certificate in PEM format\n" "\t-k is the file containing the key for in PEM format\n" - "\t-e Use openssl engine for the private key\n" + "\t-p Use openssl provider for the private key\n" ); } @@ -67,7 +67,7 @@ main(int argc, char *argv[]) *str, *signedinput = NULL, *timestampstr = NULL; void *out; const char *progname = argv[0]; - char *engine = NULL; + char *provider = NULL; unsigned char *sigbuf; int rsasig = 0, monotonic = 0, varlen, i, outputforsign = 0, outlen, sigsize; @@ -126,8 +126,8 @@ main(int argc, char *argv[]) certfile = argv[2]; argv += 2; argc -= 2; - } else if (strcmp("-e", argv[1]) == 0) { - engine = argv[2]; + } else if (strcmp("-p", argv[1]) == 0) { + provider = argv[2]; argv += 2; argc -= 2; } else { @@ -249,7 +249,7 @@ main(int argc, char *argv[]) exit(1); } if (sign_efi_var(signbuf, signbuflen, keyfile, certfile, - &sigbuf, &sigsize, engine)) + &sigbuf, &sigsize, provider)) exit(1); } printf("Signature of size %d\n", sigsize);