Skip to content

Commit 66ae00e

Browse files
committed
Refactor C_Initialize
1 parent 8e0ef2b commit 66ae00e

File tree

3 files changed

+114
-97
lines changed

3 files changed

+114
-97
lines changed

common/debug.h

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,22 @@
2424
#include <winsock.h>
2525
#endif
2626

27-
#ifdef __linux__
2827
#define ANSI_RED "\x1b[31m"
2928
#define ANSI_GREEN "\x1b[32m"
3029
#define ANSI_YELLOW "\x1b[33m"
3130
#define ANSI_BLUE "\x1b[34m"
3231
#define ANSI_MAGENTA "\x1b[35m"
3332
#define ANSI_CYAN "\x1b[36m"
3433
#define ANSI_RESET "\x1b[0m"
35-
#else
36-
#define ANSI_RED ""
37-
#define ANSI_GREEN ""
38-
#define ANSI_YELLOW ""
39-
#define ANSI_BLUE ""
40-
#define ANSI_MAGENTA ""
41-
#define ANSI_CYAN ""
42-
#define ANSI_RESET ""
43-
#endif
44-
45-
#define __FILENAME__ \
46-
(strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
4734

4835
#ifdef _MSVC
4936
#define localtime_r(a, b) localtime_s(b, a)
5037
#define gettimeofday(a, b) gettimeofday_win(a)
38+
#define __FILENAME__ \
39+
(strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
40+
#else
41+
#define __FILENAME__ \
42+
(strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
5143
#endif
5244

5345
#define D(var, file, col, who, lev, ...) \

pkcs11/yubihsm_pkcs11.c

Lines changed: 106 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
#endif
4040

4141
#ifdef _MSVC
42+
#define S_ISLNK S_ISREG
43+
#define S_ISREG(m) (((m) &S_IFMT) == S_IFREG)
4244
#define strtok_r strtok_s
4345
#endif
4446

@@ -112,9 +114,9 @@ CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(CK_VOID_PTR pInitArgs) {
112114

113115
CK_C_INITIALIZE_ARGS_PTR init_args = pInitArgs;
114116

115-
yh_dbg_init(false, false, 0, "stderr");
117+
yh_dbg_init(0, 0, 0, "stderr");
116118

117-
if (pInitArgs != NULL) {
119+
if (init_args != NULL) {
118120
if ((init_args->flags & CKF_OS_LOCKING_OK) == 0 &&
119121
init_args->CreateMutex == NULL && init_args->DestroyMutex == NULL &&
120122
init_args->LockMutex == NULL && init_args->UnlockMutex == NULL) {
@@ -163,157 +165,179 @@ CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(CK_VOID_PTR pInitArgs) {
163165
g_ctx.mutex = NULL;
164166
}
165167

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+
}
167186

187+
struct cmdline_parser_params params = {0};
168188
struct gengetopt_args_info args_info = {0};
169189

170190
cmdline_parser_params_init(&params);
191+
params.check_required = 0;
171192

172-
params.initialize = 1;
173-
params.check_required = 1;
193+
int rc = cmdline_parser_ext(argc, argv, &args_info, &params);
174194

175-
char *tmp = "";
195+
for (int i = 1; i < argc; i++) {
196+
free(argv[i]);
197+
argv[i] = 0;
198+
}
176199

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");
179202
return CKR_FUNCTION_FAILED;
180203
}
181204

182205
params.initialize = 0;
183206
params.override = 1;
184207

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");
194212
return CKR_FUNCTION_FAILED;
195213
}
214+
}
196215

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;
211223
}
224+
}
212225

213-
DBG_INFO("Now parsing supplied init args as '%s'", args_parsed);
226+
params.override = 0;
214227

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);
219241
}
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);
225244
}
226245

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+
}
232252
}
233253

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");
239256
return CKR_FUNCTION_FAILED;
240257
}
241258

242259
yh_dbg_init(args_info.debug_flag, args_info.dinout_flag,
243260
args_info.libdebug_flag, args_info.debug_file_arg);
244261

262+
DBG_INFO("Found %u configured connector(s)", args_info.connector_given);
263+
245264
// NOTE(adma): it's better to set the argument optional and check its presence
246265
// here
247-
if (args_info.connector_given == 0) {
248-
DBG_ERR("No connector defined");
249-
return CKR_FUNCTION_FAILED;
250-
}
251-
252266
if (yh_init() != YHR_SUCCESS) {
253267
DBG_ERR("Unable to initialize libyubihsm");
254268
return CKR_FUNCTION_FAILED;
255269
}
256270

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 *));
260273
if (connector_list == NULL) {
261274
DBG_ERR("Failed allocating memory");
262275
goto c_i_failure;
263276
}
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;
265285
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]) !=
267287
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;
270290
}
271291
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,
273293
args_info.cacert_arg) != YHR_SUCCESS) {
274294
DBG_ERR("Failed to set HTTPS CA option");
275295
goto c_i_failure;
276296
}
277297
}
278298
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,
280300
args_info.cert_arg) != YHR_SUCCESS) {
281301
DBG_ERR("Failed to set HTTPS cert option");
282302
goto c_i_failure;
283303
}
284304
}
285305
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,
287307
args_info.key_arg) != YHR_SUCCESS) {
288308
DBG_ERR("Failed to set HTTPS key option");
289309
goto c_i_failure;
290310
}
291311
}
292312
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,
294314
args_info.proxy_arg) != YHR_SUCCESS) {
295315
DBG_ERR("Failed to set proxy server option");
296316
goto c_i_failure;
297317
}
298318
}
299319
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,
301321
args_info.noproxy_arg) != YHR_SUCCESS) {
302322
DBG_ERR("Failed to set noproxy option");
303323
goto c_i_failure;
304324
}
305325
}
306326

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) {
308328
DBG_ERR("Failed to connect '%s'", args_info.connector_arg[i]);
309-
continue;
329+
yh_disconnect(connector_list[n]);
310330
} else {
311-
n_connectors++;
331+
name_list[n++] = args_info.connector_arg[i];
312332
}
313333
}
314334

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) {
317341
DBG_ERR("Failed building connectors list");
318342
goto c_i_failure;
319343
}
@@ -330,10 +354,13 @@ CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(CK_VOID_PTR pInitArgs) {
330354
list_append(&g_ctx.device_pubkeys, pk);
331355
}
332356

357+
free(args);
358+
333359
cmdline_parser_free(&args_info);
334360
free(connector_list);
361+
free(name_list);
335362

336-
DBG_INFO("Found %zu usable connector(s)", n_connectors);
363+
DBG_INFO("Found %u usable connector(s)", n);
337364

338365
DBG_INFO("Found %d configured device public key(s)",
339366
g_ctx.device_pubkeys.length);
@@ -345,21 +372,21 @@ CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(CK_VOID_PTR pInitArgs) {
345372

346373
c_i_failure:
347374

348-
free(args_parsed);
349375
free(args);
350376

351377
list_iterate(&g_ctx.slots, destroy_slot_mutex);
352378
list_destroy(&g_ctx.slots);
353379
list_destroy(&g_ctx.device_pubkeys);
354380

355381
if (connector_list) {
356-
for (unsigned int i = 0; i < args_info.connector_given; i++) {
382+
for (unsigned int i = 0; i < n; i++) {
357383
yh_disconnect(connector_list[i]);
358384
}
359385
}
360386

361387
cmdline_parser_free(&args_info);
362388
free(connector_list);
389+
free(name_list);
363390

364391
if (g_ctx.mutex != NULL) {
365392
g_ctx.destroy_mutex(g_ctx.mutex);
@@ -441,7 +468,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetInfo)(CK_INFO_PTR pInfo) {
441468

442469
CK_DEFINE_FUNCTION(CK_RV, C_GetFunctionList)
443470
(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) {
444-
yh_dbg_init(false, false, 0, "stderr");
471+
yh_dbg_init(0, 0, 0, "stderr");
445472

446473
DIN;
447474

@@ -1687,7 +1714,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_DestroyObject)
16871714
DBG_INFO("No ECDH session key with ID %08lx was found", hObject);
16881715
}
16891716
} else {
1690-
if (((uint8_t)(hObject >> 16)) == YH_PUBLIC_KEY) {
1717+
if (((uint8_t) (hObject >> 16)) == YH_PUBLIC_KEY) {
16911718
DBG_INFO("Trying to delete public key, returning success with noop");
16921719
goto c_do_out;
16931720
}
@@ -2010,7 +2037,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsInit)
20102037
break;
20112038

20122039
case CKA_CLASS: {
2013-
uint32_t value = *((CK_ULONG_PTR)(pTemplate[i].pValue));
2040+
uint32_t value = *((CK_ULONG_PTR) (pTemplate[i].pValue));
20142041
switch (value) {
20152042
case CKO_CERTIFICATE:
20162043
DBG_INFO("Filtering for certificate");

0 commit comments

Comments
 (0)