From: Antti Lyytinen Date: Wed, 10 Dec 2014 12:14:27 +0000 (+0200) Subject: Secure storage #3 X-Git-Tag: DEV.ENGINE_PKCS11-01.03.00.00^0 X-Git-Url: https://git.ti.com/gitweb?p=keystone-linux%2Fengine-pkcs11.git;a=commitdiff_plain;h=0b14500b0ea8b37453b6d93aac02278465e7e732 Secure storage #3 --- diff --git a/src/engine_pkcs11.c b/src/engine_pkcs11.c index 17a5fc3..b79fb47 100644 --- a/src/engine_pkcs11.c +++ b/src/engine_pkcs11.c @@ -38,22 +38,24 @@ #include #include +#include #include #include #include #include #include #include "engine_pkcs11.h" +#include #ifdef _WIN32 #define strncasecmp strnicmp #endif -#define fail(msg) { fprintf(stderr,msg); return NULL;} +#define fail(msg) { Log(LOG_ERR,msg); return NULL;} /** The maximum length of an internally-allocated PIN */ #define MAX_PIN_LENGTH 32 - +#define FLAGS_LEN 64 /* Maximum size of a token object */ #define MAX_OBJECT_SIZE 5000 @@ -160,6 +162,21 @@ static char *module = NULL; static char *init_args = NULL; +static void Log(int const loglevel, char const * const format, ...) +{ + char tmp[256]; + va_list args; + + va_start(args, format); + vsnprintf(tmp, 256, format, args); + va_end(args); + + // log it + syslog(loglevel, "engine_pkcs11: %s", tmp); + fprintf(stdout, "%s\n", tmp); +} + + int set_module(const char *modulename) { module = modulename ? strdup(modulename) : NULL; @@ -232,12 +249,12 @@ static int get_pin(UI_METHOD * ui_method, void *callback_data) if (!UI_add_input_string (ui, "PKCS#11 token PIN: ", 0, pin, 1, MAX_PIN_LENGTH)) { - fprintf(stderr, "UI_add_input_string failed\n"); + Log(LOG_ERR, "UI_add_input_string failed"); UI_free(ui); return 0; } if (UI_process(ui)) { - fprintf(stderr, "UI_process failed\n"); + Log(LOG_ERR, "UI_process failed"); UI_free(ui); return 0; } @@ -263,7 +280,7 @@ static void free_pkcs11_ctx() int pkcs11_finish(ENGINE * engine) { if (verbose) { - fprintf(stderr, "engine finish\n"); + Log(LOG_INFO, "engine finish"); } free_pkcs11_ctx(); @@ -280,12 +297,12 @@ int pkcs11_finish(ENGINE * engine) int pkcs11_init(ENGINE * engine) { if (verbose) { - fprintf(stderr, "initializing engine\n"); + Log(LOG_INFO, "initializing engine"); } ctx = PKCS11_CTX_new(); PKCS11_CTX_init_args(ctx, init_args); if (PKCS11_CTX_load(ctx, module) < 0) { - fprintf(stderr, "unable to load module %s\n", module); + Log(LOG_ERR, "unable to load module %s", module); return 0; } return 1; @@ -332,8 +349,8 @@ static int hex_to_bin(const char *in, unsigned char *out, size_t * outlen) else if ('A' <= c && c <= 'F') c = c - 'A' + 10; else { - fprintf(stderr, - "hex_to_bin(): invalid char '%c' in hex string\n", + Log(LOG_ERR, + "hex_to_bin(): invalid char '%c' in hex string", c); *outlen = 0; return 0; @@ -343,7 +360,7 @@ static int hex_to_bin(const char *in, unsigned char *out, size_t * outlen) if (*in == ':') in++; if (left <= 0) { - fprintf(stderr, "hex_to_bin(): hex string too long\n"); + Log(LOG_ERR, "hex_to_bin(): hex string too long"); *outlen = 0; return 0; } @@ -355,6 +372,30 @@ static int hex_to_bin(const char *in, unsigned char *out, size_t * outlen) return 1; } +static int str_to_dec(char const * const inPtr, int *dst) { + int ret = 1; + long val; + + char *endptr; + + errno = 0; /* To distinguish success/failure after call */ + val = strtol(inPtr, &endptr, 10); + + /* Check for various possible errors */ + if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0)) { + Log(LOG_ERR, "String to dec conversion failed"); + ret = 0; + } + if (endptr == inPtr) { + Log(LOG_ERR, "No digits were found"); + ret = 0; + } + if(ret) { + *dst = (int)val; + } + return ret; +} + /* parse string containing slot and id information */ static int parse_slot_id_string(const char *slot_id, int *slot, @@ -374,7 +415,7 @@ static int parse_slot_id_string(const char *slot_id, int *slot, if (strspn(slot_id, HEXDIGITS) == strlen(slot_id)) { /* ah, easiest case: only hex. */ if ((strlen(slot_id) + 1) / 2 > *id_len) { - fprintf(stderr, "id string too long!\n"); + Log(LOG_ERR, "id string too long!"); return 0; } *slot = 0; @@ -382,11 +423,11 @@ static int parse_slot_id_string(const char *slot_id, int *slot, } /* second: slot:id. slot is an digital int. */ - if (sscanf(slot_id, "%d", &n) == 1) { + if (str_to_dec(slot_id, &n) == 1) { i = strspn(slot_id, DIGITS); if (slot_id[i] != ':') { - fprintf(stderr, "could not parse string!\n"); + Log(LOG_ERR, "could not parse string!"); return 0; } i++; @@ -396,12 +437,12 @@ static int parse_slot_id_string(const char *slot_id, int *slot, return 1; } if (strspn(slot_id + i, HEXDIGITS) + i != strlen(slot_id)) { - fprintf(stderr, "could not parse string!\n"); + Log(LOG_ERR, "could not parse string!"); return 0; } /* ah, rest is hex */ if ((strlen(slot_id) - i + 1) / 2 > *id_len) { - fprintf(stderr, "id string too long!\n"); + Log(LOG_ERR, "id string too long!"); return 0; } *slot = n; @@ -411,12 +452,12 @@ static int parse_slot_id_string(const char *slot_id, int *slot, /* third: id_ */ if (strncmp(slot_id, "id_", 3) == 0) { if (strspn(slot_id + 3, HEXDIGITS) + 3 != strlen(slot_id)) { - fprintf(stderr, "could not parse string!\n"); + Log(LOG_ERR, "could not parse string!"); return 0; } /* ah, rest is hex */ if ((strlen(slot_id) - 3 + 1) / 2 > *id_len) { - fprintf(stderr, "id string too long!\n"); + Log(LOG_ERR, "id string too long!"); return 0; } *slot = 0; @@ -432,13 +473,13 @@ static int parse_slot_id_string(const char *slot_id, int *slot, /* last try: it has to be slot_ and then "-id_" */ if (strncmp(slot_id, "slot_", 5) != 0) { - fprintf(stderr, "format not recognized!\n"); + Log(LOG_ERR, "format not recognized!"); return 0; } /* slot is an digital int. */ - if (sscanf(slot_id + 5, "%d", &n) != 1) { - fprintf(stderr, "slot number not deciphered!\n"); + if (str_to_dec(slot_id + 5, &n) != 1) { + Log(LOG_ERR, "slot number not deciphered!"); return 0; } @@ -451,7 +492,7 @@ static int parse_slot_id_string(const char *slot_id, int *slot, } if (slot_id[i + 5] != '-') { - fprintf(stderr, "could not parse string!\n"); + Log(LOG_ERR, "could not parse string!"); return 0; } @@ -461,12 +502,12 @@ static int parse_slot_id_string(const char *slot_id, int *slot, if (strncmp(slot_id + i, "id_", 3) == 0) { if (strspn(slot_id + i + 3, HEXDIGITS) + 3 + i != strlen(slot_id)) { - fprintf(stderr, "could not parse string!\n"); + Log(LOG_ERR, "could not parse string!"); return 0; } /* ah, rest is hex */ if ((strlen(slot_id) - i - 3 + 1) / 2 > *id_len) { - fprintf(stderr, "id string too long!\n"); + Log(LOG_ERR, "id string too long!"); return 0; } *slot = n; @@ -479,7 +520,7 @@ static int parse_slot_id_string(const char *slot_id, int *slot, return (*label = strdup(slot_id + i + 6)) != NULL; } - fprintf(stderr, "could not parse string!\n"); + Log(LOG_ERR, "could not parse string!"); return 0; } @@ -503,7 +544,7 @@ static X509 *pkcs11_load_cert PKCS11_CERT *certs, *selected_cert = NULL; X509 *x509 = NULL; unsigned int slot_count, cert_count, n, m; - char flags[64]; + char flags[FLAGS_LEN]; int local_init = 0; if (ctx == NULL) { @@ -511,11 +552,11 @@ static X509 *pkcs11_load_cert local_init = 1; } - if (PKCS11_enumerate_slots(ctx, &slot_list, &slot_count) < 0) - fail("failed to enumerate slots\n"); - + if (PKCS11_enumerate_slots(ctx, &slot_list, &slot_count) < 0) { + fail("failed to enumerate slots"); + } if (verbose) { - fprintf(stderr, "Found %u slot%s\n", slot_count, + Log(LOG_INFO, "Found %u slot%s", slot_count, (slot_count <= 1) ? "" : "s"); } @@ -524,15 +565,15 @@ static X509 *pkcs11_load_cert flags[0] = '\0'; if (slot->token) { if (!slot->token->initialized) - strcat(flags, "uninitialized, "); + strncat(flags, "uninitialized, ", (FLAGS_LEN - strlen(flags) - 1)); else if (!slot->token->userPinSet) - strcat(flags, "no pin, "); + strncat(flags, "no pin, ", (FLAGS_LEN - strlen(flags) - 1)); if (slot->token->loginRequired) - strcat(flags, "login, "); + strncat(flags, "login, ", (FLAGS_LEN - strlen(flags) - 1)); if (slot->token->readOnly) - strcat(flags, "ro, "); + strncat(flags, "ro, ", (FLAGS_LEN - strlen(flags) - 1)); } else { - strcpy(flags, "no token"); + strncpy(flags, "no token", sizeof(flags)); } if ((m = strlen(flags)) != 0) { flags[m - 2] = '\0'; @@ -544,49 +585,48 @@ static X509 *pkcs11_load_cert } if (verbose) { - fprintf(stderr, "[%lu] %-25.25s %-16s", + Log(LOG_INFO, "[%lu] %-25.25s %-16s", PKCS11_get_slotid_from_slot(slot), slot->description, flags); if (slot->token) { - fprintf(stderr, " (%s)", + Log(LOG_INFO, " (%s)", slot->token->label[0] ? slot->token->label : "no label"); } - fprintf(stderr, "\n"); } } if (found_slot) { slot = found_slot; } else { - fprintf(stderr, "Invalid slot number: %d\n", (int)slot_nr); + Log(LOG_ERR, "Invalid slot number: %d", (int)slot_nr); goto err_out; } tok = slot->token; if (tok == NULL) { - fprintf(stderr, "Found empty token; \n"); + Log(LOG_ERR, "Found empty token; "); goto err_out; } if (verbose) { - fprintf(stderr, "Found slot: %s\n", slot->description); - fprintf(stderr, "Found token: %s\n", slot->token->label); + Log(LOG_INFO, "Found slot: %s", slot->description); + Log(LOG_INFO, "Found token: %s", slot->token->label); } if ((tok->loginRequired) && (do_login(slot))) { - fprintf(stderr, "failed to login\n"); + Log(LOG_ERR, "failed to login"); goto err_out; } if (PKCS11_enumerate_certs(tok, &certs, &cert_count)) { - fprintf(stderr, "unable to enumerate certificates\n"); + Log(LOG_ERR, "unable to enumerate certificates"); goto err_out; } if (verbose) { - fprintf(stderr, "Found %u cert%s:\n", cert_count, + Log(LOG_INFO, "Found %u cert%s:", cert_count, (cert_count <= 1) ? "" : "s"); } @@ -639,7 +679,7 @@ static X509 *pkcs11_load_cert } if (selected_cert == NULL) { - fprintf(stderr, "certificate not found.\n"); + Log(LOG_ERR, "certificate not found."); goto err_out; } @@ -667,7 +707,7 @@ err_out: out: if (local_init) { - free_pkcs11_ctx(e); + free_pkcs11_ctx(); } return x509; } @@ -726,7 +766,7 @@ static EVP_PKEY *pkcs11_load_key PKCS11_CERT *certs; EVP_PKEY *pk = NULL; unsigned int slot_count, cert_count, key_count, n, m; - char flags[64]; + char flags[FLAGS_LEN]; int local_init = 0; if (ctx == NULL) { @@ -735,10 +775,10 @@ static EVP_PKEY *pkcs11_load_key } if (PKCS11_enumerate_slots(ctx, &slot_list, &slot_count) < 0) - fail("failed to enumerate slots\n"); + fail("failed to enumerate slots"); if (verbose) { - fprintf(stderr, "Found %u slot%s\n", slot_count, + Log(LOG_INFO, "Found %u slot%s", slot_count, (slot_count <= 1) ? "" : "s"); } @@ -747,15 +787,15 @@ static EVP_PKEY *pkcs11_load_key flags[0] = '\0'; if (slot->token) { if (!slot->token->initialized) - strcat(flags, "uninitialized, "); + strncat(flags, "uninitialized, ", FLAGS_LEN - strlen(flags) - 1); else if (!slot->token->userPinSet) - strcat(flags, "no pin, "); + strncat(flags, "no pin, ", FLAGS_LEN - strlen(flags) - 1); if (slot->token->loginRequired) - strcat(flags, "login, "); + strncat(flags, "login, ", FLAGS_LEN - strlen(flags) - 1); if (slot->token->readOnly) - strcat(flags, "ro, "); + strncat(flags, "ro, ", FLAGS_LEN - strlen(flags) - 1); } else { - strcpy(flags, "no token"); + strncpy(flags, "no token", sizeof(flags)); } if ((m = strlen(flags)) != 0) { flags[m - 2] = '\0'; @@ -767,67 +807,65 @@ static EVP_PKEY *pkcs11_load_key } if (verbose) { - fprintf(stderr, "[%lu] %-25.25s %-16s", + Log(LOG_INFO, "[%lu] %-25.25s %-16s", PKCS11_get_slotid_from_slot(slot), slot->description, flags); if (slot->token) { - fprintf(stderr, " (%s)", + Log(LOG_INFO, " (%s)", slot->token->label[0] ? slot->token->label : "no label"); } - fprintf(stderr, "\n"); } } if (slot_nr == -1) { if (!(slot = PKCS11_find_token(ctx, slot_list, slot_count))) - fail("didn't find any tokens\n"); + fail("didn't find any tokens"); } else if (found_slot) { slot = found_slot; } else { - fprintf(stderr, "Invalid slot number: %d\n", slot_nr); + Log(LOG_ERR, "Invalid slot number: %d", slot_nr); PKCS11_release_all_slots(ctx, slot_list, slot_count); goto out; } tok = slot->token; if (tok == NULL) { - fprintf(stderr, "Found empty token; \n"); + Log(LOG_INFO, "Found empty token; "); PKCS11_release_all_slots(ctx, slot_list, slot_count); goto out; } if (isPrivate && !tok->userPinSet && !tok->readOnly) { - fprintf(stderr, "Found slot without user PIN\n"); + Log(LOG_INFO, "Found slot without user PIN"); PKCS11_release_all_slots(ctx, slot_list, slot_count); goto out; } if (verbose) { - fprintf(stderr, "Found slot: %s\n", slot->description); - fprintf(stderr, "Found token: %s\n", slot->token->label); + Log(LOG_INFO, "Found slot: %s", slot->description); + Log(LOG_INFO, "Found token: %s", slot->token->label); } #ifdef DEBUG if (PKCS11_enumerate_certs(tok, &certs, &cert_count)) - fail("unable to enumerate certificates\n"); + fail("unable to enumerate certificates"); if (verbose) { - fprintf(stderr, "Found %u certificate%s:\n", cert_count, + Log(LOG_INFO, "Found %u certificate%s:", cert_count, (cert_count <= 1) ? "" : "s"); for (n = 0; n < cert_count; n++) { PKCS11_CERT *c = certs + n; char *dn = NULL; - fprintf(stderr, " %2u %s", n + 1, c->label); + Log(LOG_INFO, " %2u %s", n + 1, c->label); if (c->x509) dn = X509_NAME_oneline(X509_get_subject_name (c->x509), NULL, 0); if (dn) { - fprintf(stderr, " (%s)", dn); + Log(LOG_INFO, " (%s)", dn); OPENSSL_free(dn); } - fprintf(stderr, "\n"); } } #endif @@ -870,7 +908,7 @@ static EVP_PKEY *pkcs11_load_key pin = NULL; pin_length = 0; } - fail("Login failed\n"); + fail("Login failed"); } /* Login successful, PIN retained in case further logins are required. This will occur on subsequent calls to the @@ -891,14 +929,14 @@ static EVP_PKEY *pkcs11_load_key /* Make sure there is at least one private key on the token */ if (PKCS11_enumerate_keys(tok, &keys, &key_count)) { - fail("unable to enumerate keys\n"); + fail("unable to enumerate keys"); } if (key_count == 0) { - fail("No keys found.\n"); + fail("No keys found."); } if (verbose) { - fprintf(stderr, "Found %u key%s:\n", key_count, + Log(LOG_INFO, "Found %u key%s:", key_count, (key_count <= 1) ? "" : "s"); } if ((key_id_len != 0) || (key_label != NULL)) { @@ -906,7 +944,7 @@ static EVP_PKEY *pkcs11_load_key PKCS11_KEY *k = keys + n; if (verbose) { - fprintf(stderr, " %2u %c%c %s\n", n + 1, + Log(LOG_INFO, " %2u %c%c %s", n + 1, k->isPrivate ? 'P' : ' ', k->needLogin ? 'L' : ' ', k->label); } @@ -929,7 +967,7 @@ static EVP_PKEY *pkcs11_load_key } if (selected_key == NULL) { - fprintf(stderr, "key not found.\n"); + Log(LOG_ERR, "key not found."); goto out; } @@ -941,7 +979,7 @@ static EVP_PKEY *pkcs11_load_key out: if (local_init) { - free_pkcs11_ctx(e); + free_pkcs11_ctx(); } return pk; @@ -960,21 +998,21 @@ EVP_PKEY *pkcs11_load_public_key(ENGINE * e, const char *s_key_id, n = parse_key_string(s_key_id, &slot_nr, key_id, &key_id_len, &key_label, NULL); if (n) { - fprintf(stderr, - "supported format: slot_:id_:label_