/* * sql_common.h * ------------ * * Common definitions and SQL support code for Cryptech PKCS #11 engine. * * We could split the functions out of this into a separate .c file, * but there's no real point in doing so, and it's simpler to keep it * all in one file, the build process is complex enough already. * * Author: Rob Austein * Copyright (c) 2015, SUNET * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _SQL_COMMON_H_ #define _SQL_COMMON_H_ #include #include #include #include #include #include /* * Placeholders for PIN length limits. Figure out real values later. * Minimum length here is much too short, we allow it for now because * some test programs fail if we insist on a reasonable length. */ #warning Figure out PIN length limits #define P11_MIN_PIN_LENGTH 4 #define P11_MAX_PIN_LENGTH 4096 /* * Debugging control. */ #ifndef DEBUG_SQL #define DEBUG_SQL 1 #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 /* * SQL database. */ static sqlite3 *sqldb = NULL; /* * 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()) /* * 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; } #endif /* _SQL_COMMON_H_ */ /* * Local variables: * indent-tabs-mode: nil * End: */