Files
linux-stable-mirror/certs/extract-cert.c
T
Nathan Chancellor 8a40f357fb extract-cert: Wrap key_pass with '#ifdef USE_PKCS11_ENGINE'
commit 4f96b7c68a upstream.

A recent strengthening of -Wunused-but-set-variable (enabled with -Wall)
in clang under a new subwarning, -Wunused-but-set-global, points out an
unused static global variable in certs/extract-cert.c:

  certs/extract-cert.c:46:20: error: variable 'key_pass' set but not used [-Werror,-Wunused-but-set-global]
     46 | static const char *key_pass;
        |                    ^

After commit 558bdc45df ("sign-file,extract-cert: use pkcs11 provider
for OPENSSL MAJOR >= 3"), key_pass is only used with the OpenSSL engine
API, not the new provider API. Wrap key_pass's declaration and
assignment with '#ifdef USE_PKCS11_ENGINE' so that it is only included
with its use to clear up the warning. While this is a little uglier than
just marking key_pass with the unused attribute, this will make it
easier to clean up all code associated with the use of the engine API if
it were ever removed in the future. While in the area, use a tab for
the key_pass assignment line to match the rest of the file.

Cc: stable@vger.kernel.org
Fixes: 558bdc45df ("sign-file,extract-cert: use pkcs11 provider for OPENSSL MAJOR >= 3")
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Tested-by: Nick Desaulniers <ndesaulniers@google.com>
Link: https://patch.msgid.link/20260325-certs-extract-cert-key_pass-unused-but-set-global-v1-1-ecf94326d532@kernel.org
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-05-07 06:09:34 +02:00

187 lines
4.2 KiB
C

/* Extract X.509 certificate in DER form from PKCS#11 or PEM.
*
* Copyright © 2014-2015 Red Hat, Inc. All Rights Reserved.
* Copyright © 2015 Intel Corporation.
*
* Authors: David Howells <dhowells@redhat.com>
* David Woodhouse <dwmw2@infradead.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the licence, or (at your option) any later version.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <err.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <openssl/err.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"
#define PKEY_ID_PKCS7 2
static __attribute__((noreturn))
void format(void)
{
fprintf(stderr,
"Usage: extract-cert <source> <dest>\n");
exit(2);
}
#ifdef USE_PKCS11_ENGINE
static const char *key_pass;
#endif
static BIO *wb;
static char *cert_dst;
static bool verbose;
static void write_cert(X509 *x509)
{
char buf[200];
if (!wb) {
wb = BIO_new_file(cert_dst, "wb");
ERR(!wb, "%s", cert_dst);
}
X509_NAME_oneline(X509_get_subject_name(x509), buf, sizeof(buf));
ERR(!i2d_X509_bio(wb, x509), "%s", cert_dst);
if (verbose)
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;
char *verbose_env;
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
ERR_clear_error();
verbose_env = getenv("KBUILD_VERBOSE");
if (verbose_env && strchr(verbose_env, '1'))
verbose = true;
#ifdef USE_PKCS11_ENGINE
key_pass = getenv("KBUILD_SIGN_PIN");
#endif
if (argc != 3)
format();
cert_src = argv[1];
cert_dst = argv[2];
if (!cert_src[0]) {
/* Invoked with no input; create empty file */
FILE *f = fopen(cert_dst, "wb");
ERR(!f, "%s", cert_dst);
fclose(f);
exit(0);
} else if (!strncmp(cert_src, "pkcs11:", 7)) {
X509 *cert = load_cert_pkcs11(cert_src);
ERR(!cert, "load_cert_pkcs11 failed");
write_cert(cert);
} else {
BIO *b;
X509 *x509;
b = BIO_new_file(cert_src, "rb");
ERR(!b, "%s", cert_src);
while (1) {
x509 = PEM_read_bio_X509(b, NULL, NULL, NULL);
if (wb && !x509) {
unsigned long err = ERR_peek_last_error();
if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
ERR_clear_error();
break;
}
}
ERR(!x509, "%s", cert_src);
write_cert(x509);
}
}
BIO_free(wb);
return 0;
}