39
39
#endif
40
40
41
41
#ifdef _MSVC
42
+ #define S_ISLNK S_ISREG
43
+ #define S_ISREG (m ) (((m) &S_IFMT) == S_IFREG)
42
44
#define strtok_r strtok_s
43
45
#endif
44
46
@@ -112,9 +114,9 @@ CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(CK_VOID_PTR pInitArgs) {
112
114
113
115
CK_C_INITIALIZE_ARGS_PTR init_args = pInitArgs ;
114
116
115
- yh_dbg_init (false, false , 0 , "stderr" );
117
+ yh_dbg_init (0 , 0 , 0 , "stderr" );
116
118
117
- if (pInitArgs != NULL ) {
119
+ if (init_args != NULL ) {
118
120
if ((init_args -> flags & CKF_OS_LOCKING_OK ) == 0 &&
119
121
init_args -> CreateMutex == NULL && init_args -> DestroyMutex == NULL &&
120
122
init_args -> LockMutex == NULL && init_args -> UnlockMutex == NULL ) {
@@ -163,157 +165,179 @@ CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(CK_VOID_PTR pInitArgs) {
163
165
g_ctx .mutex = NULL ;
164
166
}
165
167
166
- struct cmdline_parser_params params = {0 };
168
+ int argc = 1 ;
169
+ char * argv [128 ] = {"yubihsm_pkcs11" };
170
+ char * args = 0 ;
171
+
172
+ if (init_args && init_args -> pReserved ) {
173
+ char * str = args = strdup (init_args -> pReserved );
174
+ char * save = 0 ;
175
+ char * part = 0 ;
176
+ while (argc < (int ) (sizeof (argv ) / sizeof (argv [0 ])) &&
177
+ (part = strtok_r (str , " \r\n\t" , & save ))) {
178
+ size_t len = strlen (part ) + 8 ;
179
+ argv [argc ] = malloc (len );
180
+ snprintf (argv [argc ], len , "--%s" , part );
181
+ DBG_INFO ("Option '%s' added from pReserved" , argv [argc ]);
182
+ argc ++ ;
183
+ str = 0 ;
184
+ }
185
+ }
167
186
187
+ struct cmdline_parser_params params = {0 };
168
188
struct gengetopt_args_info args_info = {0 };
169
189
170
190
cmdline_parser_params_init (& params );
191
+ params .check_required = 0 ;
171
192
172
- params .initialize = 1 ;
173
- params .check_required = 1 ;
193
+ int rc = cmdline_parser_ext (argc , argv , & args_info , & params );
174
194
175
- char * tmp = "" ;
195
+ for (int i = 1 ; i < argc ; i ++ ) {
196
+ free (argv [i ]);
197
+ argv [i ] = 0 ;
198
+ }
176
199
177
- if (cmdline_parser ( 0 , & tmp , & args_info ) != 0 ) {
178
- DBG_ERR ("Unable to initialize ggo structure " );
200
+ if (rc ) {
201
+ DBG_ERR ("Unable to parse pReserved command line " );
179
202
return CKR_FUNCTION_FAILED ;
180
203
}
181
204
182
205
params .initialize = 0 ;
183
206
params .override = 1 ;
184
207
185
- char * args = NULL ;
186
- char * args_parsed = NULL ;
187
-
188
- yh_connector * * connector_list = NULL ;
189
-
190
- if (init_args != NULL && init_args -> pReserved != NULL ) {
191
- args = strdup (init_args -> pReserved );
192
- if (args == NULL ) {
193
- DBG_ERR ("Failed copying reserved string" );
208
+ const char * opts = getenv ("YUBIHSM_PKCS11_OPTS" );
209
+ if (opts ) {
210
+ if (cmdline_parser_string_ext (opts , & args_info , argv [0 ], & params ) != 0 ) {
211
+ DBG_ERR ("Unable to parse YUBIHSM_PKCS11_OPTS" );
194
212
return CKR_FUNCTION_FAILED ;
195
213
}
214
+ }
196
215
197
- char * str = args ;
198
- char * save = NULL ;
199
- char * part ;
200
- while ((part = strtok_r (str , " \r\n\t" , & save ))) {
201
- str = NULL ;
202
- size_t len = args_parsed ? strlen (args_parsed ) : 0 ;
203
- char * new_args = realloc (args_parsed , len + strlen (part ) + 4 );
204
- if (new_args ) {
205
- args_parsed = new_args ;
206
- sprintf (args_parsed + len , "--%s " , part );
207
- } else {
208
- DBG_ERR ("Failed allocating memory for args" );
209
- goto c_i_failure ;
210
- }
216
+ const char * conf = getenv ("YUBIHSM_PKCS11_CONF" );
217
+ if (conf ) {
218
+ char opt [1024 ];
219
+ snprintf (opt , sizeof (opt ), "--config-file=%s" , conf );
220
+ if (cmdline_parser_string_ext (opt , & args_info , argv [0 ], & params ) != 0 ) {
221
+ DBG_ERR ("Unable to parse YUBIHSM_PKCS11_CONF" );
222
+ return CKR_FUNCTION_FAILED ;
211
223
}
224
+ }
212
225
213
- DBG_INFO ( "Now parsing supplied init args as '%s'" , args_parsed ) ;
226
+ params . override = 0 ;
214
227
215
- if (cmdline_parser_string_ext (args_parsed , & args_info ,
216
- "yubihsm_pkcs11 module" , & params ) != 0 ) {
217
- DBG_ERR ("Parsing of the reserved init args '%s' failed" , args );
218
- goto c_i_failure ;
228
+ struct stat sb = {0 };
229
+ if (stat (args_info .config_file_arg , & sb ) == 0 ) {
230
+ if (S_ISREG (sb .st_mode ) || S_ISLNK (sb .st_mode )) {
231
+ DBG_INFO ("Using config file '%s'" , args_info .config_file_arg );
232
+ if (cmdline_parser_config_file (args_info .config_file_arg , & args_info ,
233
+ & params ) != 0 ) {
234
+ DBG_ERR ("Unable to parse configuration file '%s'" ,
235
+ args_info .config_file_arg );
236
+ return CKR_FUNCTION_FAILED ;
237
+ }
238
+ } else {
239
+ DBG_WARN ("Config file '%s' is not a regular file" ,
240
+ args_info .config_file_arg );
219
241
}
220
-
221
- free (args );
222
- args = NULL ;
223
- free (args_parsed );
224
- args_parsed = NULL ;
242
+ } else {
243
+ DBG_WARN ("Couldn't stat config file '%s'" , args_info .config_file_arg );
225
244
}
226
245
227
- // NOTE(thorduri): #TOCTOU
228
- char * config_file = args_info .config_file_arg ;
229
- struct stat sb = {0 };
230
- if (stat (config_file , & sb ) == -1 ) {
231
- config_file = getenv ("YUBIHSM_PKCS11_CONF" );
246
+ if (!args_info .connector_given ) {
247
+ if (cmdline_parser_string_ext ("--connector=" YH_USB_URL_SCHEME , & args_info ,
248
+ argv [0 ], & params ) != 0 ) {
249
+ DBG_ERR ("Unable to parse default connector command line '%s'" , argv [1 ]);
250
+ return CKR_FUNCTION_FAILED ;
251
+ }
232
252
}
233
253
234
- params .override = 0 ;
235
-
236
- if (config_file != NULL &&
237
- cmdline_parser_config_file (config_file , & args_info , & params ) != 0 ) {
238
- DBG_ERR ("Unable to parse configuration file" );
254
+ if (cmdline_parser_required (& args_info , argv [0 ]) != 0 ) {
255
+ DBG_ERR ("Required configuration options missing" );
239
256
return CKR_FUNCTION_FAILED ;
240
257
}
241
258
242
259
yh_dbg_init (args_info .debug_flag , args_info .dinout_flag ,
243
260
args_info .libdebug_flag , args_info .debug_file_arg );
244
261
262
+ DBG_INFO ("Found %u configured connector(s)" , args_info .connector_given );
263
+
245
264
// NOTE(adma): it's better to set the argument optional and check its presence
246
265
// here
247
- if (args_info .connector_given == 0 ) {
248
- DBG_ERR ("No connector defined" );
249
- return CKR_FUNCTION_FAILED ;
250
- }
251
-
252
266
if (yh_init () != YHR_SUCCESS ) {
253
267
DBG_ERR ("Unable to initialize libyubihsm" );
254
268
return CKR_FUNCTION_FAILED ;
255
269
}
256
270
257
- DBG_INFO ("Found %u configured connector(s)" , args_info .connector_given );
258
-
259
- connector_list = calloc (args_info .connector_given , sizeof (yh_connector * ));
271
+ yh_connector * * connector_list =
272
+ calloc (args_info .connector_given , sizeof (yh_connector * ));
260
273
if (connector_list == NULL ) {
261
274
DBG_ERR ("Failed allocating memory" );
262
275
goto c_i_failure ;
263
276
}
264
- size_t n_connectors = 0 ;
277
+
278
+ char * * name_list = calloc (args_info .connector_given , sizeof (char * ));
279
+ if (name_list == NULL ) {
280
+ DBG_ERR ("Failed allocating memory" );
281
+ goto c_i_failure ;
282
+ }
283
+
284
+ unsigned int n = 0 ;
265
285
for (unsigned int i = 0 ; i < args_info .connector_given ; i ++ ) {
266
- if (yh_init_connector (args_info .connector_arg [i ], & connector_list [i ]) !=
286
+ if (yh_init_connector (args_info .connector_arg [i ], & connector_list [n ]) !=
267
287
YHR_SUCCESS ) {
268
- DBG_ERR ("Failed to init connector" );
269
- goto c_i_failure ;
288
+ DBG_ERR ("Failed to init connector '%s'" , args_info . connector_arg [ i ] );
289
+ continue ;
270
290
}
271
291
if (args_info .cacert_given ) {
272
- if (yh_set_connector_option (connector_list [i ], YH_CONNECTOR_HTTPS_CA ,
292
+ if (yh_set_connector_option (connector_list [n ], YH_CONNECTOR_HTTPS_CA ,
273
293
args_info .cacert_arg ) != YHR_SUCCESS ) {
274
294
DBG_ERR ("Failed to set HTTPS CA option" );
275
295
goto c_i_failure ;
276
296
}
277
297
}
278
298
if (args_info .cert_given ) {
279
- if (yh_set_connector_option (connector_list [i ], YH_CONNECTOR_HTTPS_CERT ,
299
+ if (yh_set_connector_option (connector_list [n ], YH_CONNECTOR_HTTPS_CERT ,
280
300
args_info .cert_arg ) != YHR_SUCCESS ) {
281
301
DBG_ERR ("Failed to set HTTPS cert option" );
282
302
goto c_i_failure ;
283
303
}
284
304
}
285
305
if (args_info .key_given ) {
286
- if (yh_set_connector_option (connector_list [i ], YH_CONNECTOR_HTTPS_KEY ,
306
+ if (yh_set_connector_option (connector_list [n ], YH_CONNECTOR_HTTPS_KEY ,
287
307
args_info .key_arg ) != YHR_SUCCESS ) {
288
308
DBG_ERR ("Failed to set HTTPS key option" );
289
309
goto c_i_failure ;
290
310
}
291
311
}
292
312
if (args_info .proxy_given ) {
293
- if (yh_set_connector_option (connector_list [i ], YH_CONNECTOR_PROXY_SERVER ,
313
+ if (yh_set_connector_option (connector_list [n ], YH_CONNECTOR_PROXY_SERVER ,
294
314
args_info .proxy_arg ) != YHR_SUCCESS ) {
295
315
DBG_ERR ("Failed to set proxy server option" );
296
316
goto c_i_failure ;
297
317
}
298
318
}
299
319
if (args_info .noproxy_given ) {
300
- if (yh_set_connector_option (connector_list [i ], YH_CONNECTOR_NOPROXY ,
320
+ if (yh_set_connector_option (connector_list [n ], YH_CONNECTOR_NOPROXY ,
301
321
args_info .noproxy_arg ) != YHR_SUCCESS ) {
302
322
DBG_ERR ("Failed to set noproxy option" );
303
323
goto c_i_failure ;
304
324
}
305
325
}
306
326
307
- if (yh_connect (connector_list [i ], args_info .timeout_arg ) != YHR_SUCCESS ) {
327
+ if (yh_connect (connector_list [n ], args_info .timeout_arg ) != YHR_SUCCESS ) {
308
328
DBG_ERR ("Failed to connect '%s'" , args_info .connector_arg [i ]);
309
- continue ;
329
+ yh_disconnect ( connector_list [ n ]) ;
310
330
} else {
311
- n_connectors ++ ;
331
+ name_list [ n ++ ] = args_info . connector_arg [ i ] ;
312
332
}
313
333
}
314
334
315
- if (add_connectors (& g_ctx , args_info .connector_given , args_info .connector_arg ,
316
- connector_list ) == false) {
335
+ if (n == 0 ) {
336
+ DBG_ERR ("No usable connector found" );
337
+ goto c_i_failure ;
338
+ }
339
+
340
+ if (add_connectors (& g_ctx , n , name_list , connector_list ) == false) {
317
341
DBG_ERR ("Failed building connectors list" );
318
342
goto c_i_failure ;
319
343
}
@@ -330,10 +354,13 @@ CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(CK_VOID_PTR pInitArgs) {
330
354
list_append (& g_ctx .device_pubkeys , pk );
331
355
}
332
356
357
+ free (args );
358
+
333
359
cmdline_parser_free (& args_info );
334
360
free (connector_list );
361
+ free (name_list );
335
362
336
- DBG_INFO ("Found %zu usable connector(s)" , n_connectors );
363
+ DBG_INFO ("Found %u usable connector(s)" , n );
337
364
338
365
DBG_INFO ("Found %d configured device public key(s)" ,
339
366
g_ctx .device_pubkeys .length );
@@ -345,21 +372,21 @@ CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(CK_VOID_PTR pInitArgs) {
345
372
346
373
c_i_failure :
347
374
348
- free (args_parsed );
349
375
free (args );
350
376
351
377
list_iterate (& g_ctx .slots , destroy_slot_mutex );
352
378
list_destroy (& g_ctx .slots );
353
379
list_destroy (& g_ctx .device_pubkeys );
354
380
355
381
if (connector_list ) {
356
- for (unsigned int i = 0 ; i < args_info . connector_given ; i ++ ) {
382
+ for (unsigned int i = 0 ; i < n ; i ++ ) {
357
383
yh_disconnect (connector_list [i ]);
358
384
}
359
385
}
360
386
361
387
cmdline_parser_free (& args_info );
362
388
free (connector_list );
389
+ free (name_list );
363
390
364
391
if (g_ctx .mutex != NULL ) {
365
392
g_ctx .destroy_mutex (g_ctx .mutex );
@@ -441,7 +468,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetInfo)(CK_INFO_PTR pInfo) {
441
468
442
469
CK_DEFINE_FUNCTION (CK_RV , C_GetFunctionList )
443
470
(CK_FUNCTION_LIST_PTR_PTR ppFunctionList ) {
444
- yh_dbg_init (false, false , 0 , "stderr" );
471
+ yh_dbg_init (0 , 0 , 0 , "stderr" );
445
472
446
473
DIN ;
447
474
@@ -1687,7 +1714,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_DestroyObject)
1687
1714
DBG_INFO ("No ECDH session key with ID %08lx was found" , hObject );
1688
1715
}
1689
1716
} else {
1690
- if (((uint8_t )(hObject >> 16 )) == YH_PUBLIC_KEY ) {
1717
+ if (((uint8_t ) (hObject >> 16 )) == YH_PUBLIC_KEY ) {
1691
1718
DBG_INFO ("Trying to delete public key, returning success with noop" );
1692
1719
goto c_do_out ;
1693
1720
}
@@ -2010,7 +2037,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsInit)
2010
2037
break ;
2011
2038
2012
2039
case CKA_CLASS : {
2013
- uint32_t value = * ((CK_ULONG_PTR )(pTemplate [i ].pValue ));
2040
+ uint32_t value = * ((CK_ULONG_PTR ) (pTemplate [i ].pValue ));
2014
2041
switch (value ) {
2015
2042
case CKO_CERTIFICATE :
2016
2043
DBG_INFO ("Filtering for certificate" );
0 commit comments