From: Johannes Schneider <[email protected]> The OpenSSL Provider API support routes FIT signing-key loading through OSSL_STORE on OpenSSL >= 3 (USE_PKCS11_PROVIDER), but only for key files: rsa_pem_get_priv_key() fopen()s the path before OSSL_STORE_open(), so a pkcs11: token URI fails with -ENOENT. The legacy engine path that handled tokens is compiled out on OpenSSL >= 3, so FIT signing with a token key silently produces an unsigned FIT (a configuration signature node with no value or hashed-strings).
Load a pkcs11: key URI in the provider path directly through OSSL_STORE and the pkcs11 provider: skip the fopen, append ";type=private" if absent. The PIN travels in the URI (pin-value=); MKIMAGE_SIGN_PIN is unaffected. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Johannes Schneider <[email protected]> Co-developed-by: Eddie Kovsky <[email protected]> Signed-off-by: Eddie Kovsky <[email protected]> --- lib/rsa/rsa-sign.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c index 361ed0647bc6..c39a2a11652f 100644 --- a/lib/rsa/rsa-sign.c +++ b/lib/rsa/rsa-sign.c @@ -92,6 +92,52 @@ static int rsa_pem_get_pub_key(const char *keydir, const char *name, EVP_PKEY ** return -EINVAL; *evpp = NULL; +#ifdef USE_PKCS11_PROVIDER + /* + * A pkcs11: token URI is not a file: load it via OSSL_STORE + the pkcs11 + * provider instead of fopen (PIN in the URI, pin-value=). + */ + if (keydir && !strncmp(keydir, "pkcs11:", 7)) { + char uri[1200]; + OSSL_STORE_CTX *p11_store; + EVP_PKEY *p11_key = NULL; + + if (strstr(keydir, "type=")) + snprintf(uri, sizeof(uri), "%s", keydir); + else + snprintf(uri, sizeof(uri), "%s;type=public", keydir); + + if (!OSSL_PROVIDER_try_load(NULL, "default", true)) + ERR(1, "OSSL_PROVIDER_try_load(default)"); + if (!OSSL_PROVIDER_try_load(NULL, "pkcs11", true)) + ERR(1, "OSSL_PROVIDER_try_load(pkcs11)"); + + p11_store = OSSL_STORE_open(uri, NULL, NULL, NULL, NULL); + ERR(!p11_store, "OSSL_STORE_open(%s)", uri); + while (!OSSL_STORE_eof(p11_store)) { + OSSL_STORE_INFO *info = OSSL_STORE_load(p11_store); + + if (!info) { + if (OSSL_STORE_error(p11_store)) + break; + continue; + } + if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PUBKEY) + p11_key = OSSL_STORE_INFO_get1_PUBKEY(info); + OSSL_STORE_INFO_free(info); + if (p11_key) + break; + } + OSSL_STORE_close(p11_store); + if (!p11_key) { + fprintf(stderr, "No public key found at '%s'\n", uri); + return -EPROTO; + } + *evpp = p11_key; + return 0; + } + +#endif snprintf(path, sizeof(path), "%s/%s.crt", keydir, name); f = fopen(path, "r"); if (!f) { @@ -237,6 +283,52 @@ static int rsa_pem_get_priv_key(const char *keydir, const char *name, return -EINVAL; *evpp = NULL; + +#ifdef USE_PKCS11_PROVIDER + /* + * A pkcs11: token URI is not a file: load it via OSSL_STORE + the pkcs11 + * provider instead of fopen (PIN in the URI, pin-value=). + */ + if (keydir && !strncmp(keydir, "pkcs11:", 7)) { + char uri[1200]; + OSSL_STORE_CTX *p11_store; + EVP_PKEY *p11_key = NULL; + + if (strstr(keydir, "type=")) + snprintf(uri, sizeof(uri), "%s", keydir); + else + snprintf(uri, sizeof(uri), "%s;type=private", keydir); + + if (!OSSL_PROVIDER_try_load(NULL, "default", true)) + ERR(1, "OSSL_PROVIDER_try_load(default)"); + if (!OSSL_PROVIDER_try_load(NULL, "pkcs11", true)) + ERR(1, "OSSL_PROVIDER_try_load(pkcs11)"); + + p11_store = OSSL_STORE_open(uri, NULL, NULL, NULL, NULL); + ERR(!p11_store, "OSSL_STORE_open(%s)", uri); + while (!OSSL_STORE_eof(p11_store)) { + OSSL_STORE_INFO *info = OSSL_STORE_load(p11_store); + + if (!info) { + if (OSSL_STORE_error(p11_store)) + break; + continue; + } + if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) + p11_key = OSSL_STORE_INFO_get1_PKEY(info); + OSSL_STORE_INFO_free(info); + if (p11_key) + break; + } + OSSL_STORE_close(p11_store); + if (!p11_key) { + fprintf(stderr, "No private key found at '%s'\n", uri); + return -EPROTO; + } + *evpp = p11_key; + return 0; + } +#endif if (keydir && name) snprintf(path, sizeof(path), "%s/%s.key", keydir, name); else if (keyfile) -- 2.56.0
