mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-10-15 06:17:16 +00:00
imx-cst: restore PKCS#11 signing on OpenSSL 4 via the provider
0015-fix-openssl-4-engine-api-removal made CST build against OpenSSL 4 by
stubbing out the removed ENGINE API, but left PKCS#11-backed signing broken:
ENGINE_by_id("pkcs11") returns NULL, so engine_ctx_init() fails. Add a patch
that reimplements the pkcs11 certificate and key loading on OSSL_STORE and the
pkcs11 provider (pkcs11-provider), restoring HSM/token-backed signing on
OpenSSL 4. OpenSSL 3 builds are unaffected.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Johannes Schneider <johannes.schneider@leica-geosystems.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
This commit is contained in:
1 parent
cf030e73b8
commit
3de9f29b7f
2 files changed
+237
No files matched your search
+236
@@ -0,0 +1,236 @@
|
||||
From: Johannes Schneider <johannes.schneider@leica-geosystems.com>
|
||||
Subject: cst: port pkcs11 signing from the OpenSSL ENGINE to a provider
|
||||
|
||||
OpenSSL 4.0 removed the ENGINE API, so CST's pkcs11-backed signing stops
|
||||
working: ENGINE_by_id("pkcs11") returns NULL and engine_ctx_init() fails.
|
||||
|
||||
Reimplement the pkcs11 certificate and key loading on OSSL_STORE and the
|
||||
pkcs11 provider. engine_ctx_init() loads the default and pkcs11 providers --
|
||||
default explicitly, because activating any provider stops OpenSSL
|
||||
auto-loading default, which would drop the EVP digest and signature algorithms
|
||||
the signer needs. ENGINE_load_certificate()/ENGINE_load_key() open the pkcs11
|
||||
URI through OSSL_STORE and return the X509 / EVP_PKEY, feeding the existing CMS
|
||||
and EVP signing unchanged. The public entry points keep their names and
|
||||
signatures; the ENGINE * argument is now vestigial. The PIN travels in the URI
|
||||
(pin-value=).
|
||||
|
||||
Upstream-Status: Pending
|
||||
Assisted-by: Claude:claude-opus-4-8
|
||||
Signed-off-by: Johannes Schneider <johannes.schneider@leica-geosystems.com>
|
||||
---
|
||||
Builds on the engine-stub change already in this recipe's series
|
||||
(0015-fix-openssl-4-engine-api-removal), which only makes the file compile and
|
||||
noted that pkcs11-backed signing was still unavailable on OpenSSL 4; this
|
||||
restores it.
|
||||
--- a/src/lib/back_end/engine.c
|
||||
+++ b/src/lib/back_end/engine.c
|
||||
@@ -7,8 +7,9 @@
|
||||
/*
|
||||
* OpenSSL 4.0 removed the ENGINE API. <openssl/engine.h> still declares
|
||||
* it for source compatibility, and defining OPENSSL_ENGINE_STUBS turns the
|
||||
- * declarations into inline no-ops so this file keeps linking. The pkcs11
|
||||
- * engine simply does not exist there, which engine_ctx_init() reports.
|
||||
+ * declarations into inline no-ops so this file keeps linking. Signing no
|
||||
+ * longer uses an engine (see engine_ctx_init); the vestigial ENGINE * only
|
||||
+ * keeps the public entry points' signatures unchanged.
|
||||
*/
|
||||
#define OPENSSL_ENGINE_STUBS
|
||||
|
||||
@@ -19,6 +20,8 @@
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/evp.h>
|
||||
+#include <openssl/provider.h>
|
||||
+#include <openssl/store.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if CST_WITH_PKCS11
|
||||
@@ -31,6 +34,76 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
+/* Load default and pkcs11 once; "default" explicitly, or activating pkcs11 stops OpenSSL auto-loading it and the signer loses its EVP algorithms. */
|
||||
+static int load_providers(void)
|
||||
+{
|
||||
+ static int loaded;
|
||||
+
|
||||
+ if (loaded)
|
||||
+ return 1;
|
||||
+
|
||||
+ if (!OSSL_PROVIDER_load(NULL, "default")) {
|
||||
+ fprintf(stderr, "ERROR: cannot load the default OpenSSL provider\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (!OSSL_PROVIDER_load(NULL, "pkcs11")) {
|
||||
+ fprintf(stderr, "ERROR: cannot load the pkcs11 OpenSSL provider; "
|
||||
+ "is pkcs11-provider installed and OPENSSL_MODULES set?\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ loaded = 1;
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+/* Load a certificate and/or key from a PKCS#11 (or any OSSL_STORE) URI; returns 1 only if every requested object was found. */
|
||||
+static int store_load(const char *uri, X509 **cert_out, EVP_PKEY **key_out)
|
||||
+{
|
||||
+ OSSL_STORE_CTX *store = NULL;
|
||||
+ int ok = 0;
|
||||
+
|
||||
+ if (!uri)
|
||||
+ return 0;
|
||||
+
|
||||
+ store = OSSL_STORE_open(uri, NULL, NULL, NULL, NULL);
|
||||
+ if (!store) {
|
||||
+ fprintf(stderr, "ERROR: cannot open PKCS#11 store for %s\n", uri);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ while (!OSSL_STORE_eof(store)) {
|
||||
+ OSSL_STORE_INFO *info = OSSL_STORE_load(store);
|
||||
+
|
||||
+ if (!info) {
|
||||
+ /* NULL means EOF or a non-fatal error; break on the error flag, or a bad object spins forever (eof stays 0). */
|
||||
+ if (OSSL_STORE_error(store))
|
||||
+ break;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ switch (OSSL_STORE_INFO_get_type(info)) {
|
||||
+ case OSSL_STORE_INFO_CERT:
|
||||
+ if (cert_out && !*cert_out)
|
||||
+ *cert_out = OSSL_STORE_INFO_get1_CERT(info);
|
||||
+ break;
|
||||
+ case OSSL_STORE_INFO_PKEY:
|
||||
+ if (key_out && !*key_out)
|
||||
+ *key_out = OSSL_STORE_INFO_get1_PKEY(info);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ OSSL_STORE_INFO_free(info);
|
||||
+
|
||||
+ if ((!cert_out || *cert_out) && (!key_out || *key_out))
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ OSSL_STORE_close(store);
|
||||
+ ok = (!cert_out || *cert_out) && (!key_out || *key_out);
|
||||
+ return ok;
|
||||
+}
|
||||
+
|
||||
struct engine_ctx *engine_ctx_new(void)
|
||||
{
|
||||
struct engine_ctx *ctx = NULL;
|
||||
@@ -41,16 +114,13 @@
|
||||
|
||||
int32_t engine_ctx_destroy(struct engine_ctx *ctx)
|
||||
{
|
||||
- if (ctx) {
|
||||
- ENGINE_free(ctx->engine);
|
||||
+ if (ctx)
|
||||
OPENSSL_free(ctx);
|
||||
- }
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t engine_ctx_init(struct engine_ctx *ctx)
|
||||
{
|
||||
- dynamic_fns fns;
|
||||
/* OpenSSL Initialization */
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS |
|
||||
@@ -66,60 +136,46 @@
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
- ENGINE_load_builtin_engines();
|
||||
-
|
||||
- ctx->engine = ENGINE_by_id("pkcs11");
|
||||
-
|
||||
- if (!ctx->engine) {
|
||||
- fprintf(stderr, "ERROR: cannot load the pkcs11 OpenSSL engine\n");
|
||||
-#if OPENSSL_VERSION_MAJOR >= 4
|
||||
- fprintf(stderr,
|
||||
- "ERROR: OpenSSL 4.0 removed ENGINE support, so PKCS#11 "
|
||||
- "backed signing is unavailable\n");
|
||||
-#endif
|
||||
+ if (!load_providers())
|
||||
return 0;
|
||||
- }
|
||||
|
||||
-#ifdef DEBUG
|
||||
- ENGINE_ctrl_cmd_string(ctx->engine, "VERBOSE", NULL, 0);
|
||||
-#endif
|
||||
-
|
||||
- if (!ENGINE_init(ctx->engine)) {
|
||||
- ENGINE_free(ctx->engine);
|
||||
- return 0;
|
||||
- }
|
||||
+ ctx->engine = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t engine_ctx_finish(struct engine_ctx *ctx)
|
||||
{
|
||||
- if (ctx)
|
||||
- ENGINE_finish(ctx->engine);
|
||||
+ (void)ctx;
|
||||
return 1;
|
||||
}
|
||||
|
||||
X509 *ENGINE_load_certificate(ENGINE *e, const char *cert_ref)
|
||||
{
|
||||
- struct {
|
||||
- const char *s_slot_cert_id;
|
||||
- X509 *cert;
|
||||
- } params = {0};
|
||||
+ X509 *cert = NULL;
|
||||
|
||||
- params.s_slot_cert_id = cert_ref;
|
||||
- params.cert = NULL;
|
||||
+ (void)e;
|
||||
|
||||
- if (!ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, ¶ms, NULL, 1)) {
|
||||
+ if (!store_load(cert_ref, &cert, NULL)) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- return params.cert;
|
||||
+ return cert;
|
||||
}
|
||||
|
||||
EVP_PKEY *ENGINE_load_key(ENGINE *e, const char *key_ref)
|
||||
{
|
||||
- return ENGINE_load_private_key(e, key_ref, 0, 0);
|
||||
+ EVP_PKEY *key = NULL;
|
||||
+
|
||||
+ (void)e;
|
||||
+
|
||||
+ if (!store_load(key_ref, NULL, &key)) {
|
||||
+ ERR_print_errors_fp(stderr);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return key;
|
||||
}
|
||||
|
||||
X509 *engine_read_certificate(const char *cert_ref)
|
||||
@@ -161,14 +217,8 @@
|
||||
#endif
|
||||
|
||||
out:
|
||||
- if (ctx) {
|
||||
- /*
|
||||
- * Destroy the context: ctx_finish is not called here since
|
||||
- * ENGINE_finish cleanups the engine instance. Calling ctx_destroy
|
||||
- * next will lead to null pointer dereference.
|
||||
- */
|
||||
+ if (ctx)
|
||||
engine_ctx_destroy(ctx);
|
||||
- }
|
||||
|
||||
if (error)
|
||||
ERR_print_errors_fp(stderr);
|
||||
@@ -29,6 +29,7 @@ SRC_URI = "\
|
||||
file://0014-fix-pointer-sign-errors-with-clang.patch \
|
||||
file://0015-fix-openssl-4-engine-api-removal.patch \
|
||||
file://0016-fix-openssl-4-const-subject-name.patch \
|
||||
file://0017-cst-port-pkcs11-signing-from-engine-to-provider.patch \
|
||||
"
|
||||
SRC_URI[sha256sum] = "fd92a1a9faa10fb81bbf752c7ee1e257f17e1ec4c2964f8a47adf8a3eaa7df41"
|
||||
|
||||
|
||||
Reference in new issue
Block a user