Skip to content

Commit

Permalink
sign-file,extract-cert: use pkcs11 provider for OPENSSL MAJOR >= 3
Browse files Browse the repository at this point in the history
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: Jan Stancek <jstancek@redhat.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Tested-by: R Nageswara Sastry <rnsastry@linux.ibm.com>
Reviewed-by: Neal Gompa <neal@gompa.dev>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
  • Loading branch information
jstancek authored and jarkkojs committed Sep 20, 2024
1 parent 467d60e commit 558bdc4
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 58 deletions.
103 changes: 73 additions & 30 deletions certs/extract-cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,18 @@
#include <openssl/bio.h>
#include <openssl/pem.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"

/*
* 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

static __attribute__((noreturn))
Expand Down Expand Up @@ -61,6 +62,66 @@ static void write_cert(X509 *x509)
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)
{
char *cert_src;
Expand Down Expand Up @@ -89,28 +150,10 @@ int main(int argc, char **argv)
fclose(f);
exit(0);
} else if (!strncmp(cert_src, "pkcs11:", 7)) {
ENGINE *e;
struct {
const char *cert_id;
X509 *cert;
} parms;
X509 *cert = load_cert_pkcs11(cert_src);

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");
write_cert(parms.cert);
ERR(!cert, "load_cert_pkcs11 failed");
write_cert(cert);
} else {
BIO *b;
X509 *x509;
Expand Down
93 changes: 65 additions & 28 deletions scripts/sign-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,18 @@
#include <openssl/evp.h>
#include <openssl/pem.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"

/*
* 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
* assume that it's not available and its header file is missing and that we
Expand Down Expand Up @@ -106,28 +107,64 @@ static int pem_pw_cb(char *buf, int len, int w, void *v)
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)) {
ENGINE *e;
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");

ENGINE_load_builtin_engines();
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_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);
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");
private_key = ENGINE_load_private_key(e, private_key_name,
NULL, NULL);
ERR(!private_key, "%s", private_key_name);
else
ERR(1, "ENGINE_init");
if (key_pass)
ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN");
private_key = ENGINE_load_private_key(e, private_key_name, NULL, NULL);
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 {
EVP_PKEY *private_key;
BIO *b;

b = BIO_new_file(private_key_name, "rb");
Expand All @@ -136,9 +173,9 @@ static EVP_PKEY *read_private_key(const char *private_key_name)
NULL);
ERR(!private_key, "%s", private_key_name);
BIO_free(b);
}

return private_key;
return private_key;
}
}

static X509 *read_x509(const char *x509_name)
Expand Down

0 comments on commit 558bdc4

Please sign in to comment.