Skip to content

Commit 558bdc4

Browse files
jstancekjarkkojs
authored andcommitted
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: Jan Stancek <[email protected]> Reviewed-by: Jarkko Sakkinen <[email protected]> Tested-by: R Nageswara Sastry <[email protected]> Reviewed-by: Neal Gompa <[email protected]> Signed-off-by: Jarkko Sakkinen <[email protected]>
1 parent 467d60e commit 558bdc4

File tree

2 files changed

+138
-58
lines changed

2 files changed

+138
-58
lines changed

certs/extract-cert.c

+73-30
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,18 @@
2121
#include <openssl/bio.h>
2222
#include <openssl/pem.h>
2323
#include <openssl/err.h>
24-
#include <openssl/engine.h>
25-
24+
#if OPENSSL_VERSION_MAJOR >= 3
25+
# define USE_PKCS11_PROVIDER
26+
# include <openssl/provider.h>
27+
# include <openssl/store.h>
28+
#else
29+
# if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0)
30+
# define USE_PKCS11_ENGINE
31+
# include <openssl/engine.h>
32+
# endif
33+
#endif
2634
#include "ssl-common.h"
2735

28-
/*
29-
* OpenSSL 3.0 deprecates the OpenSSL's ENGINE API.
30-
*
31-
* Remove this if/when that API is no longer used
32-
*/
33-
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
34-
3536
#define PKEY_ID_PKCS7 2
3637

3738
static __attribute__((noreturn))
@@ -61,6 +62,66 @@ static void write_cert(X509 *x509)
6162
fprintf(stderr, "Extracted cert: %s\n", buf);
6263
}
6364

65+
static X509 *load_cert_pkcs11(const char *cert_src)
66+
{
67+
X509 *cert = NULL;
68+
#ifdef USE_PKCS11_PROVIDER
69+
OSSL_STORE_CTX *store;
70+
71+
if (!OSSL_PROVIDER_try_load(NULL, "pkcs11", true))
72+
ERR(1, "OSSL_PROVIDER_try_load(pkcs11)");
73+
if (!OSSL_PROVIDER_try_load(NULL, "default", true))
74+
ERR(1, "OSSL_PROVIDER_try_load(default)");
75+
76+
store = OSSL_STORE_open(cert_src, NULL, NULL, NULL, NULL);
77+
ERR(!store, "OSSL_STORE_open");
78+
79+
while (!OSSL_STORE_eof(store)) {
80+
OSSL_STORE_INFO *info = OSSL_STORE_load(store);
81+
82+
if (!info) {
83+
drain_openssl_errors(__LINE__, 0);
84+
continue;
85+
}
86+
if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_CERT) {
87+
cert = OSSL_STORE_INFO_get1_CERT(info);
88+
ERR(!cert, "OSSL_STORE_INFO_get1_CERT");
89+
}
90+
OSSL_STORE_INFO_free(info);
91+
if (cert)
92+
break;
93+
}
94+
OSSL_STORE_close(store);
95+
#elif defined(USE_PKCS11_ENGINE)
96+
ENGINE *e;
97+
struct {
98+
const char *cert_id;
99+
X509 *cert;
100+
} parms;
101+
102+
parms.cert_id = cert_src;
103+
parms.cert = NULL;
104+
105+
ENGINE_load_builtin_engines();
106+
drain_openssl_errors(__LINE__, 1);
107+
e = ENGINE_by_id("pkcs11");
108+
ERR(!e, "Load PKCS#11 ENGINE");
109+
if (ENGINE_init(e))
110+
drain_openssl_errors(__LINE__, 1);
111+
else
112+
ERR(1, "ENGINE_init");
113+
if (key_pass)
114+
ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN");
115+
ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &parms, NULL, 1);
116+
ERR(!parms.cert, "Get X.509 from PKCS#11");
117+
cert = parms.cert;
118+
#else
119+
fprintf(stderr, "no pkcs11 engine/provider available\n");
120+
exit(1);
121+
#endif
122+
return cert;
123+
}
124+
64125
int main(int argc, char **argv)
65126
{
66127
char *cert_src;
@@ -89,28 +150,10 @@ int main(int argc, char **argv)
89150
fclose(f);
90151
exit(0);
91152
} else if (!strncmp(cert_src, "pkcs11:", 7)) {
92-
ENGINE *e;
93-
struct {
94-
const char *cert_id;
95-
X509 *cert;
96-
} parms;
153+
X509 *cert = load_cert_pkcs11(cert_src);
97154

98-
parms.cert_id = cert_src;
99-
parms.cert = NULL;
100-
101-
ENGINE_load_builtin_engines();
102-
drain_openssl_errors(__LINE__, 1);
103-
e = ENGINE_by_id("pkcs11");
104-
ERR(!e, "Load PKCS#11 ENGINE");
105-
if (ENGINE_init(e))
106-
drain_openssl_errors(__LINE__, 1);
107-
else
108-
ERR(1, "ENGINE_init");
109-
if (key_pass)
110-
ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN");
111-
ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &parms, NULL, 1);
112-
ERR(!parms.cert, "Get X.509 from PKCS#11");
113-
write_cert(parms.cert);
155+
ERR(!cert, "load_cert_pkcs11 failed");
156+
write_cert(cert);
114157
} else {
115158
BIO *b;
116159
X509 *x509;

scripts/sign-file.c

+65-28
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,18 @@
2727
#include <openssl/evp.h>
2828
#include <openssl/pem.h>
2929
#include <openssl/err.h>
30-
#include <openssl/engine.h>
31-
30+
#if OPENSSL_VERSION_MAJOR >= 3
31+
# define USE_PKCS11_PROVIDER
32+
# include <openssl/provider.h>
33+
# include <openssl/store.h>
34+
#else
35+
# if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0)
36+
# define USE_PKCS11_ENGINE
37+
# include <openssl/engine.h>
38+
# endif
39+
#endif
3240
#include "ssl-common.h"
3341

34-
/*
35-
* OpenSSL 3.0 deprecates the OpenSSL's ENGINE API.
36-
*
37-
* Remove this if/when that API is no longer used
38-
*/
39-
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
40-
4142
/*
4243
* Use CMS if we have openssl-1.0.0 or newer available - otherwise we have to
4344
* assume that it's not available and its header file is missing and that we
@@ -106,28 +107,64 @@ static int pem_pw_cb(char *buf, int len, int w, void *v)
106107
return pwlen;
107108
}
108109

109-
static EVP_PKEY *read_private_key(const char *private_key_name)
110+
static EVP_PKEY *read_private_key_pkcs11(const char *private_key_name)
110111
{
111-
EVP_PKEY *private_key;
112+
EVP_PKEY *private_key = NULL;
113+
#ifdef USE_PKCS11_PROVIDER
114+
OSSL_STORE_CTX *store;
112115

113-
if (!strncmp(private_key_name, "pkcs11:", 7)) {
114-
ENGINE *e;
116+
if (!OSSL_PROVIDER_try_load(NULL, "pkcs11", true))
117+
ERR(1, "OSSL_PROVIDER_try_load(pkcs11)");
118+
if (!OSSL_PROVIDER_try_load(NULL, "default", true))
119+
ERR(1, "OSSL_PROVIDER_try_load(default)");
120+
121+
store = OSSL_STORE_open(private_key_name, NULL, NULL, NULL, NULL);
122+
ERR(!store, "OSSL_STORE_open");
115123

116-
ENGINE_load_builtin_engines();
124+
while (!OSSL_STORE_eof(store)) {
125+
OSSL_STORE_INFO *info = OSSL_STORE_load(store);
126+
127+
if (!info) {
128+
drain_openssl_errors(__LINE__, 0);
129+
continue;
130+
}
131+
if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) {
132+
private_key = OSSL_STORE_INFO_get1_PKEY(info);
133+
ERR(!private_key, "OSSL_STORE_INFO_get1_PKEY");
134+
}
135+
OSSL_STORE_INFO_free(info);
136+
if (private_key)
137+
break;
138+
}
139+
OSSL_STORE_close(store);
140+
#elif defined(USE_PKCS11_ENGINE)
141+
ENGINE *e;
142+
143+
ENGINE_load_builtin_engines();
144+
drain_openssl_errors(__LINE__, 1);
145+
e = ENGINE_by_id("pkcs11");
146+
ERR(!e, "Load PKCS#11 ENGINE");
147+
if (ENGINE_init(e))
117148
drain_openssl_errors(__LINE__, 1);
118-
e = ENGINE_by_id("pkcs11");
119-
ERR(!e, "Load PKCS#11 ENGINE");
120-
if (ENGINE_init(e))
121-
drain_openssl_errors(__LINE__, 1);
122-
else
123-
ERR(1, "ENGINE_init");
124-
if (key_pass)
125-
ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0),
126-
"Set PKCS#11 PIN");
127-
private_key = ENGINE_load_private_key(e, private_key_name,
128-
NULL, NULL);
129-
ERR(!private_key, "%s", private_key_name);
149+
else
150+
ERR(1, "ENGINE_init");
151+
if (key_pass)
152+
ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN");
153+
private_key = ENGINE_load_private_key(e, private_key_name, NULL, NULL);
154+
ERR(!private_key, "%s", private_key_name);
155+
#else
156+
fprintf(stderr, "no pkcs11 engine/provider available\n");
157+
exit(1);
158+
#endif
159+
return private_key;
160+
}
161+
162+
static EVP_PKEY *read_private_key(const char *private_key_name)
163+
{
164+
if (!strncmp(private_key_name, "pkcs11:", 7)) {
165+
return read_private_key_pkcs11(private_key_name);
130166
} else {
167+
EVP_PKEY *private_key;
131168
BIO *b;
132169

133170
b = BIO_new_file(private_key_name, "rb");
@@ -136,9 +173,9 @@ static EVP_PKEY *read_private_key(const char *private_key_name)
136173
NULL);
137174
ERR(!private_key, "%s", private_key_name);
138175
BIO_free(b);
139-
}
140176

141-
return private_key;
177+
return private_key;
178+
}
142179
}
143180

144181
static X509 *read_x509(const char *x509_name)

0 commit comments

Comments
 (0)