From c45562762aab7e874eac71792f9eebb5185ee47d Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Wed, 1 Jul 2015 16:30:51 -0400 Subject: Add p11util program to do things like fiddling with the BPKDF2 iteration count, setting PINs, and so forth. Factor some SQL utility code out to a separate file so we can reuse it for p11util. --- pkcs11.c | 229 ++++----------------------------------------------------------- 1 file changed, 14 insertions(+), 215 deletions(-) (limited to 'pkcs11.c') diff --git a/pkcs11.c b/pkcs11.c index 74886b8..a653ecf 100644 --- a/pkcs11.c +++ b/pkcs11.c @@ -2,12 +2,8 @@ * pkcs11.c * -------- * - * This is a partial implementation of PKCS #11 on top of Cryptlib on - * top of a HAL connecting to the Cryptech FPGA cores. - * - * This is still at a very early stage and should not (yet?) be used - * for any serious purpose. Among other things, it's not yet entirely - * clear whether this approach really is workable. + * This is a partial implementation of PKCS #11 on top of the Cryptech + * libhal library connecting to the Cryptech FPGA cores. * * Author: Rob Austein * Copyright (c) 2015, SUNET @@ -44,8 +40,6 @@ #include #include -#include - #include /* @@ -64,7 +58,9 @@ #endif #include "pkcs11.h" + #include "attributes.h" +#include "sql_common.h" /* * This PKCS #11 implementation is hardwired with one slot, the token @@ -75,19 +71,7 @@ #define P11_ONE_AND_ONLY_SLOT 0 /* - * Placeholders for PIN length limits. Figure out real values later. - */ - -#warning Figure out PIN length limits -#define P11_MIN_PIN_LENGTH 16 -#define P11_MAX_PIN_LENGTH 4096 - -/* - * Version numbers. Placeholders for now. Cryptlib has a version - * number, but from PKCS #11's point of view, Cryptlib is part of the - * "hardware", and we're probably going to need something other than - * Cryptlib's version number for the hardware, because we have to - * represent the version number of the attached Cryptech FPGA cores. + * Version numbers. Placeholders for now. * * Software version number is just the version of this PKCS #11 * implementation. Probably. @@ -103,10 +87,6 @@ * Debugging control. */ -#ifndef DEBUG_SQL -#define DEBUG_SQL 1 -#endif - #ifndef DEBUG_HAL #define DEBUG_HAL 1 #endif @@ -115,15 +95,6 @@ #define DEBUG_PKCS11 2 #endif -/* - * Default filename for SQL database lives. Can be overriden at - * runtime by setting PKCS11_DATABASE environment variable. - */ - -#ifndef SQL_DATABASE -#define SQL_DATABASE ".cryptech-pkcs11.db" -#endif - /* * Whether to include POSIX-specific features. */ @@ -234,12 +205,6 @@ static enum { static p11_session_t *p11_sessions; -/* - * SQL database. - */ - -static sqlite3 *sqldb = NULL; - /* * Next PKCS #11 handle to allocate. We use a single handle space for * both session and object handles, and we just keep incrementing @@ -322,32 +287,6 @@ static pid_t initialized_pid; #endif /* DEBUG_PKCS11 > 1 */ -/* - * Error checking for SQLite calls. - */ - -#if DEBUG_SQL - -#define sql_whine(_expr_) \ - (fprintf(stderr, "%s:%u: %s returned %s\n", \ - __FILE__, __LINE__, #_expr_, sqlite3_errmsg(sqldb)), \ - sql_breakpoint()) - -#else /* DEBUG_SQL */ - -#define sql_whine(_expr_) \ - ((void) 0) - -#endif /* DEBUG_SQL */ - -#define sql_check(_good_, _expr_) \ - ((_expr_) == (_good_) ? 1 : (sql_whine(_expr_), 0)) - -#define sql_check_ok(_expr_) sql_check(SQLITE_OK, _expr_) -#define sql_check_row(_expr_) sql_check(SQLITE_ROW, _expr_) -#define sql_check_done(_expr_) sql_check(SQLITE_DONE, _expr_) -#define sql_whine_step() sql_whine(sqlite3_step()) - /* * Error checking for libhal calls. */ @@ -538,153 +477,6 @@ static CK_RV posix_mutex_unlock(CK_VOID_PTR pMutex) -/* - * SQL utilities. - */ - -/* - * Hook on which to hang a debugger breakpoint on SQL errors. - */ - -#if DEBUG_SQL -static void sql_breakpoint(void) -{ - fprintf(stderr, "[sql_breakpoint]\n"); -} -#endif - -/* - * Execute SQL code that doesn't require a prepared query. - */ - -static int sql_exec(const char *cmd) -{ - char *msg = NULL; - - if (sql_check_ok(sqlite3_exec(sqldb, cmd, NULL, NULL, &msg))) - return 1; - -#if DEBUG_SQL - if (msg != NULL) - fprintf(stderr, "[%s]\n", msg); -#endif - - return 0; -} - -/* - * Initialize SQL. This includes loading our schema, portions of - * which live in the temp (memory) database thus always need to be - * created on startup. - */ - -static int sql_init(void) -{ - static const char schema[] = -#include "schema.h" - ; - - assert(sqldb == NULL); - - const char * const env = getenv("PKCS11_DATABASE"); - const char * const home = getenv("HOME"); - const char * const base = SQL_DATABASE; - int ok; - - if (env != NULL) { - ok = sql_check_ok(sqlite3_open(env, &sqldb)); - } - - else if (home == NULL) { - ok = sql_check_ok(sqlite3_open(base, &sqldb)); - } - - else { - char fn[strlen(home) + strlen(base) + 2]; - snprintf(fn, sizeof(fn), "%s/%s", home, base); - ok = sql_check_ok(sqlite3_open(fn, &sqldb)); - } - - return ok && sql_exec(schema); -} - -/* - * Shut down SQL. - * - * Yes, this can return failure, although it's not clear what we're - * meant to do about that if the application is going to shut down - * regardless of what we do. I guess we could loop retrying a few - * times for errors like SQLITE_BUSY, but that's about it. - */ - -static int sql_fini(void) -{ - if (!sql_check_ok(sqlite3_close(sqldb))) - return 0; - - sqldb = NULL; - return 1; -} - -/* - * GCC attribute declaration to help catch format string errors, - * ignored by other compilers. - */ - -#ifdef __GNUC__ -static int sql_prepare(sqlite3_stmt **q, - const char *format, ...) - __attribute__ ((format (printf, 2, 3))); -#endif - -/* - * Prepare an SQLite3 query, using vsnprintf() to format the query. - * - * WARNING WARNING WARNING WARNING - * - * Do not use this formatting mechanism for anything involving - * user-supplied data. It's only intended to handle things like - * selecting between two parallel table structures or queries using - * manifest constants that are only available in C header files. - */ - -static int sql_prepare(sqlite3_stmt **q, const char *format, ...) -{ - char buffer[2048]; - va_list ap; - size_t n; - - va_start(ap, format); - n = vsnprintf(buffer, sizeof(buffer), format, ap); - va_end(ap); - - if (n >= sizeof(buffer)) - return SQLITE_TOOBIG; - - return sqlite3_prepare_v2(sqldb, buffer, -1, q, NULL); -} - -/* - * This idiom occurs frequently, bundle it so we have the option of - * doing it along with the normal conditional control flow that SQL - * queries seem to follow. - */ - -static int sql_finalize_and_clear(sqlite3_stmt **q) -{ - assert(q != NULL); - - int err = sqlite3_finalize(*q); - - if (err != SQLITE_OK) - return err; - - *q = NULL; - return SQLITE_OK; -} - - - /* * Initialize KEK. If we had proper hardware support the KEK would be * living in special RAM where we could wipe it if anything triggered @@ -906,6 +698,8 @@ static int p11_attribute_get(const CK_OBJECT_HANDLE object_handle, * Wrappers to set and get CK_BBOOL and CK_ULONG values. */ +#if 0 + static int p11_attribute_set_bbool(const CK_OBJECT_HANDLE object_handle, const CK_ATTRIBUTE_TYPE type, const CK_BBOOL value) { return p11_attribute_set(object_handle, type, &value, sizeof(value)); @@ -916,6 +710,8 @@ static int p11_attribute_set_ulong(const CK_OBJECT_HANDLE object_handle, const C return p11_attribute_set(object_handle, type, &value, sizeof(value)); } +#endif + static int p11_attribute_get_bbool(const CK_OBJECT_HANDLE object_handle, const CK_ATTRIBUTE_TYPE type, CK_BBOOL *value) { CK_ULONG length; @@ -1960,7 +1756,9 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session, for (i = 0; i < ulPublicKeyAttributeCount; i++) { const CK_ATTRIBUTE_TYPE type = pPublicKeyTemplate[i].type; const void * const val = pPublicKeyTemplate[i].pValue; +#if 0 const size_t len = pPublicKeyTemplate[i].ulValueLen; +#endif assert(val != NULL); @@ -1982,7 +1780,9 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session, for (i = 0; i < ulPrivateKeyAttributeCount; i++) { const CK_ATTRIBUTE_TYPE type = pPrivateKeyTemplate[i].type; const void * const val = pPrivateKeyTemplate[i].pValue; +#if 0 const size_t len = pPrivateKeyTemplate[i].ulValueLen; +#endif assert (val != NULL); @@ -2453,7 +2253,6 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, /* * No real idea (yet) how we get many of the following parameters. - * See cryptlib's CRYPT_DEVINFO_* attributes for some hints. * * pInfo->label is supposed to be set when the token is initialized. * Not yet sure what that means in our context, but need something @@ -2627,7 +2426,7 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession, ENTER_PUBLIC_FUNCTION(C_Login); static const char pin_query_format[] = - " SELECT pbkdf2_iterations, %s_pin, %s_pin_salt from global"; + " SELECT pbkdf2_iterations, %s_pin, %s_pin_salt FROM global"; p11_session_t *session; sqlite3_stmt *q = NULL; -- cgit v1.2.3