2727#include <openssl/evp.h>
2828#include <openssl/pem.h>
2929#include <openssl/err.h>
30- #include <openssl/engine.h>
31-
32- /*
33- * OpenSSL 3.0 deprecates the OpenSSL's ENGINE API.
34- *
35- * Remove this if/when that API is no longer used
36- */
37- #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
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
40+ #include "ssl-common.h"
3841
3942/*
4043 * Use CMS if we have openssl-1.0.0 or newer available - otherwise we have to
@@ -83,41 +86,6 @@ void format(void)
8386 exit (2 );
8487}
8588
86- static void display_openssl_errors (int l )
87- {
88- const char * file ;
89- char buf [120 ];
90- int e , line ;
91-
92- if (ERR_peek_error () == 0 )
93- return ;
94- fprintf (stderr , "At main.c:%d:\n" , l );
95-
96- while ((e = ERR_get_error_line (& file , & line ))) {
97- ERR_error_string (e , buf );
98- fprintf (stderr , "- SSL %s: %s:%d\n" , buf , file , line );
99- }
100- }
101-
102- static void drain_openssl_errors (void )
103- {
104- const char * file ;
105- int line ;
106-
107- if (ERR_peek_error () == 0 )
108- return ;
109- while (ERR_get_error_line (& file , & line )) {}
110- }
111-
112- #define ERR (cond , fmt , ...) \
113- do { \
114- bool __cond = (cond); \
115- display_openssl_errors(__LINE__); \
116- if (__cond) { \
117- errx(1, fmt, ## __VA_ARGS__); \
118- } \
119- } while(0)
120-
12189static const char * key_pass ;
12290
12391static int pem_pw_cb (char * buf , int len , int w , void * v )
@@ -139,28 +107,64 @@ static int pem_pw_cb(char *buf, int len, int w, void *v)
139107 return pwlen ;
140108}
141109
142- static EVP_PKEY * read_private_key (const char * private_key_name )
110+ static EVP_PKEY * read_private_key_pkcs11 (const char * private_key_name )
143111{
144- EVP_PKEY * private_key ;
112+ EVP_PKEY * private_key = NULL ;
113+ #ifdef USE_PKCS11_PROVIDER
114+ OSSL_STORE_CTX * store ;
145115
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" );
123+
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 ))
148+ drain_openssl_errors (__LINE__ , 1 );
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+ {
146164 if (!strncmp (private_key_name , "pkcs11:" , 7 )) {
147- ENGINE * e ;
148-
149- ENGINE_load_builtin_engines ();
150- drain_openssl_errors ();
151- e = ENGINE_by_id ("pkcs11" );
152- ERR (!e , "Load PKCS#11 ENGINE" );
153- if (ENGINE_init (e ))
154- drain_openssl_errors ();
155- else
156- ERR (1 , "ENGINE_init" );
157- if (key_pass )
158- ERR (!ENGINE_ctrl_cmd_string (e , "PIN" , key_pass , 0 ),
159- "Set PKCS#11 PIN" );
160- private_key = ENGINE_load_private_key (e , private_key_name ,
161- NULL , NULL );
162- ERR (!private_key , "%s" , private_key_name );
165+ return read_private_key_pkcs11 (private_key_name );
163166 } else {
167+ EVP_PKEY * private_key ;
164168 BIO * b ;
165169
166170 b = BIO_new_file (private_key_name , "rb" );
@@ -169,9 +173,9 @@ static EVP_PKEY *read_private_key(const char *private_key_name)
169173 NULL );
170174 ERR (!private_key , "%s" , private_key_name );
171175 BIO_free (b );
172- }
173176
174- return private_key ;
177+ return private_key ;
178+ }
175179}
176180
177181static X509 * read_x509 (const char * x509_name )
@@ -306,7 +310,7 @@ int main(int argc, char **argv)
306310
307311 /* Digest the module data. */
308312 OpenSSL_add_all_digests ();
309- display_openssl_errors (__LINE__ );
313+ drain_openssl_errors (__LINE__ , 0 );
310314 digest_algo = EVP_get_digestbyname (hash_algo );
311315 ERR (!digest_algo , "EVP_get_digestbyname" );
312316
0 commit comments