1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
|
From 9c6deb5733306025947a1d438a2dd4d44413a58b Mon Sep 17 00:00:00 2001
From: David Seifert <soap@gentoo.org>
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 <engine> option of sign-efi-sig-list becomes -p <provider>, 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 <guid>\tOptional <guid> for the X509 Certificate\n"
"\t-k <key>\tSecret key file for authorising User Mode updates\n"
"\t-d <list>[-<entry>]\tDelete the signature list <list> (or just a single <entry> within the list)\n"
- "\t--engine <eng>\tUse engine <eng> for private key\n"
+ "\t--provider <prov>\tUse provider <prov> 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 <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/sha.h>
-#include <openssl/engine.h>
+#include <openssl/provider.h>
+#include <openssl/store.h>
+#include <openssl/ui.h>
#include <openssl_sign.h>
@@ -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 <guid>] [-o] [-t <timestamp>] [-i <infile>] [-c <crt file>] [-k <key file>] [-e <engine>] <var> <efi sig list file> <output file>\n", progname);
+ printf("Usage: %s [-r] [-m] [-a] [-g <guid>] [-o] [-t <timestamp>] [-i <infile>] [-c <crt file>] [-k <key file>] [-p <provider>] <var> <efi sig list file> <output file>\n", progname);
}
static void
@@ -56,7 +56,7 @@ help(const char *progname)
"\t-g <guid> Use <guid> as the signature owner GUID\n"
"\t-c <crt> <crt> is the file containing the signing certificate in PEM format\n"
"\t-k <key> <key> is the file containing the key for <crt> in PEM format\n"
- "\t-e <engine> Use openssl engine <engine> for the private key\n"
+ "\t-p <provider> Use openssl provider <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);
|