Commit 558bdc45 authored by Jan Stancek's avatar Jan Stancek Committed by Jarkko Sakkinen

sign-file,extract-cert: use pkcs11 provider for OPENSSL MAJOR >= 3

ENGINE API has been deprecated since OpenSSL version 3.0 [1].
Distros have started dropping support from headers and in future
it will likely disappear also from library.

It has been superseded by the PROVIDER API, so use it instead
for OPENSSL MAJOR >= 3.

[1] https://github.com/openssl/openssl/blob/master/README-ENGINES.md

[jarkko: fixed up alignment issues reported by checkpatch.pl --strict]
Signed-off-by: default avatarJan Stancek <jstancek@redhat.com>
Reviewed-by: default avatarJarkko Sakkinen <jarkko@kernel.org>
Tested-by: default avatarR Nageswara Sastry <rnsastry@linux.ibm.com>
Reviewed-by: default avatarNeal Gompa <neal@gompa.dev>
Signed-off-by: default avatarJarkko Sakkinen <jarkko@kernel.org>
parent 467d60ed
...@@ -21,17 +21,18 @@ ...@@ -21,17 +21,18 @@
#include <openssl/bio.h> #include <openssl/bio.h>
#include <openssl/pem.h> #include <openssl/pem.h>
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/engine.h> #if OPENSSL_VERSION_MAJOR >= 3
# define USE_PKCS11_PROVIDER
# include <openssl/provider.h>
# include <openssl/store.h>
#else
# if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0)
# define USE_PKCS11_ENGINE
# include <openssl/engine.h>
# endif
#endif
#include "ssl-common.h" #include "ssl-common.h"
/*
* OpenSSL 3.0 deprecates the OpenSSL's ENGINE API.
*
* Remove this if/when that API is no longer used
*/
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#define PKEY_ID_PKCS7 2 #define PKEY_ID_PKCS7 2
static __attribute__((noreturn)) static __attribute__((noreturn))
...@@ -61,6 +62,66 @@ static void write_cert(X509 *x509) ...@@ -61,6 +62,66 @@ static void write_cert(X509 *x509)
fprintf(stderr, "Extracted cert: %s\n", buf); fprintf(stderr, "Extracted cert: %s\n", buf);
} }
static X509 *load_cert_pkcs11(const char *cert_src)
{
X509 *cert = NULL;
#ifdef USE_PKCS11_PROVIDER
OSSL_STORE_CTX *store;
if (!OSSL_PROVIDER_try_load(NULL, "pkcs11", true))
ERR(1, "OSSL_PROVIDER_try_load(pkcs11)");
if (!OSSL_PROVIDER_try_load(NULL, "default", true))
ERR(1, "OSSL_PROVIDER_try_load(default)");
store = OSSL_STORE_open(cert_src, NULL, NULL, NULL, NULL);
ERR(!store, "OSSL_STORE_open");
while (!OSSL_STORE_eof(store)) {
OSSL_STORE_INFO *info = OSSL_STORE_load(store);
if (!info) {
drain_openssl_errors(__LINE__, 0);
continue;
}
if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_CERT) {
cert = OSSL_STORE_INFO_get1_CERT(info);
ERR(!cert, "OSSL_STORE_INFO_get1_CERT");
}
OSSL_STORE_INFO_free(info);
if (cert)
break;
}
OSSL_STORE_close(store);
#elif defined(USE_PKCS11_ENGINE)
ENGINE *e;
struct {
const char *cert_id;
X509 *cert;
} parms;
parms.cert_id = cert_src;
parms.cert = NULL;
ENGINE_load_builtin_engines();
drain_openssl_errors(__LINE__, 1);
e = ENGINE_by_id("pkcs11");
ERR(!e, "Load PKCS#11 ENGINE");
if (ENGINE_init(e))
drain_openssl_errors(__LINE__, 1);
else
ERR(1, "ENGINE_init");
if (key_pass)
ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN");
ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &parms, NULL, 1);
ERR(!parms.cert, "Get X.509 from PKCS#11");
cert = parms.cert;
#else
fprintf(stderr, "no pkcs11 engine/provider available\n");
exit(1);
#endif
return cert;
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
char *cert_src; char *cert_src;
...@@ -89,28 +150,10 @@ int main(int argc, char **argv) ...@@ -89,28 +150,10 @@ int main(int argc, char **argv)
fclose(f); fclose(f);
exit(0); exit(0);
} else if (!strncmp(cert_src, "pkcs11:", 7)) { } else if (!strncmp(cert_src, "pkcs11:", 7)) {
ENGINE *e; X509 *cert = load_cert_pkcs11(cert_src);
struct {
const char *cert_id;
X509 *cert;
} parms;
parms.cert_id = cert_src;
parms.cert = NULL;
ENGINE_load_builtin_engines(); ERR(!cert, "load_cert_pkcs11 failed");
drain_openssl_errors(__LINE__, 1); write_cert(cert);
e = ENGINE_by_id("pkcs11");
ERR(!e, "Load PKCS#11 ENGINE");
if (ENGINE_init(e))
drain_openssl_errors(__LINE__, 1);
else
ERR(1, "ENGINE_init");
if (key_pass)
ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN");
ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &parms, NULL, 1);
ERR(!parms.cert, "Get X.509 from PKCS#11");
write_cert(parms.cert);
} else { } else {
BIO *b; BIO *b;
X509 *x509; X509 *x509;
......
...@@ -27,17 +27,18 @@ ...@@ -27,17 +27,18 @@
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/pem.h> #include <openssl/pem.h>
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/engine.h> #if OPENSSL_VERSION_MAJOR >= 3
# define USE_PKCS11_PROVIDER
# include <openssl/provider.h>
# include <openssl/store.h>
#else
# if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0)
# define USE_PKCS11_ENGINE
# include <openssl/engine.h>
# endif
#endif
#include "ssl-common.h" #include "ssl-common.h"
/*
* OpenSSL 3.0 deprecates the OpenSSL's ENGINE API.
*
* Remove this if/when that API is no longer used
*/
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
/* /*
* Use CMS if we have openssl-1.0.0 or newer available - otherwise we have to * Use CMS if we have openssl-1.0.0 or newer available - otherwise we have to
* assume that it's not available and its header file is missing and that we * assume that it's not available and its header file is missing and that we
...@@ -106,11 +107,37 @@ static int pem_pw_cb(char *buf, int len, int w, void *v) ...@@ -106,11 +107,37 @@ static int pem_pw_cb(char *buf, int len, int w, void *v)
return pwlen; return pwlen;
} }
static EVP_PKEY *read_private_key(const char *private_key_name) static EVP_PKEY *read_private_key_pkcs11(const char *private_key_name)
{ {
EVP_PKEY *private_key; EVP_PKEY *private_key = NULL;
#ifdef USE_PKCS11_PROVIDER
OSSL_STORE_CTX *store;
if (!strncmp(private_key_name, "pkcs11:", 7)) { if (!OSSL_PROVIDER_try_load(NULL, "pkcs11", true))
ERR(1, "OSSL_PROVIDER_try_load(pkcs11)");
if (!OSSL_PROVIDER_try_load(NULL, "default", true))
ERR(1, "OSSL_PROVIDER_try_load(default)");
store = OSSL_STORE_open(private_key_name, NULL, NULL, NULL, NULL);
ERR(!store, "OSSL_STORE_open");
while (!OSSL_STORE_eof(store)) {
OSSL_STORE_INFO *info = OSSL_STORE_load(store);
if (!info) {
drain_openssl_errors(__LINE__, 0);
continue;
}
if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) {
private_key = OSSL_STORE_INFO_get1_PKEY(info);
ERR(!private_key, "OSSL_STORE_INFO_get1_PKEY");
}
OSSL_STORE_INFO_free(info);
if (private_key)
break;
}
OSSL_STORE_close(store);
#elif defined(USE_PKCS11_ENGINE)
ENGINE *e; ENGINE *e;
ENGINE_load_builtin_engines(); ENGINE_load_builtin_engines();
...@@ -122,12 +149,22 @@ static EVP_PKEY *read_private_key(const char *private_key_name) ...@@ -122,12 +149,22 @@ static EVP_PKEY *read_private_key(const char *private_key_name)
else else
ERR(1, "ENGINE_init"); ERR(1, "ENGINE_init");
if (key_pass) if (key_pass)
ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN");
"Set PKCS#11 PIN"); private_key = ENGINE_load_private_key(e, private_key_name, NULL, NULL);
private_key = ENGINE_load_private_key(e, private_key_name,
NULL, NULL);
ERR(!private_key, "%s", private_key_name); ERR(!private_key, "%s", private_key_name);
#else
fprintf(stderr, "no pkcs11 engine/provider available\n");
exit(1);
#endif
return private_key;
}
static EVP_PKEY *read_private_key(const char *private_key_name)
{
if (!strncmp(private_key_name, "pkcs11:", 7)) {
return read_private_key_pkcs11(private_key_name);
} else { } else {
EVP_PKEY *private_key;
BIO *b; BIO *b;
b = BIO_new_file(private_key_name, "rb"); b = BIO_new_file(private_key_name, "rb");
...@@ -136,9 +173,9 @@ static EVP_PKEY *read_private_key(const char *private_key_name) ...@@ -136,9 +173,9 @@ static EVP_PKEY *read_private_key(const char *private_key_name)
NULL); NULL);
ERR(!private_key, "%s", private_key_name); ERR(!private_key, "%s", private_key_name);
BIO_free(b); BIO_free(b);
}
return private_key; return private_key;
}
} }
static X509 *read_x509(const char *x509_name) static X509 *read_x509(const char *x509_name)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment