27
27
#include <openssl/evp.h>
28
28
#include <openssl/pem.h>
29
29
#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
32
40
#include "ssl-common.h"
33
41
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
-
41
42
/*
42
43
* Use CMS if we have openssl-1.0.0 or newer available - otherwise we have to
43
44
* 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)
106
107
return pwlen;
107
108
}
108
109
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)
110
111
{
111
- EVP_PKEY *private_key;
112
+ EVP_PKEY *private_key = NULL;
113
+ #ifdef USE_PKCS11_PROVIDER
114
+ OSSL_STORE_CTX *store;
112
115
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");
115
123
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))
117
148
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);
130
166
} else {
167
+ EVP_PKEY *private_key;
131
168
BIO *b;
132
169
133
170
b = BIO_new_file(private_key_name, "rb");
@@ -136,9 +173,9 @@ static EVP_PKEY *read_private_key(const char *private_key_name)
136
173
NULL);
137
174
ERR(!private_key, "%s", private_key_name);
138
175
BIO_free(b);
139
- }
140
176
141
- return private_key;
177
+ return private_key;
178
+ }
142
179
}
143
180
144
181
static X509 *read_x509(const char *x509_name)
0 commit comments