security/nss/lib/softoken/sdb.c

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     4 /*
     5  * This file implements PKCS 11 on top of our existing security modules
     6  *
     7  * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
     8  *   This implementation has two slots:
     9  *	slot 1 is our generic crypto support. It does not require login.
    10  *   It supports Public Key ops, and all they bulk ciphers and hashes. 
    11  *   It can also support Private Key ops for imported Private keys. It does 
    12  *   not have any token storage.
    13  *	slot 2 is our private key support. It requires a login before use. It
    14  *   can store Private Keys and Certs as token objects. Currently only private
    15  *   keys and their associated Certificates are saved on the token.
    16  *
    17  *   In this implementation, session objects are only visible to the session
    18  *   that created or generated them.
    19  */
    21 #include "sdb.h"
    22 #include "pkcs11t.h"
    23 #include "seccomon.h"
    24 #include <sqlite3.h>
    25 #include "prthread.h"
    26 #include "prio.h"
    27 #include <stdio.h>
    28 #include "secport.h"
    29 #include "prmon.h"
    30 #include "prenv.h"
    31 #include "prprf.h"
    32 #include "prsystem.h" /* for PR_GetDirectorySeparator() */
    33 #include <sys/stat.h>
    34 #if defined(_WIN32)
    35 #include <io.h>
    36 #include <windows.h>
    37 #elif defined(XP_UNIX)
    38 #include <unistd.h>
    39 #endif
    41 #ifdef SQLITE_UNSAFE_THREADS
    42 #include "prlock.h"
    43 /*
    44  * SQLite can be compiled to be thread safe or not.
    45  * turn on SQLITE_UNSAFE_THREADS if the OS does not support
    46  * a thread safe version of sqlite.
    47  */
    48 static PRLock *sqlite_lock = NULL;
    50 #define LOCK_SQLITE()  PR_Lock(sqlite_lock);
    51 #define UNLOCK_SQLITE()  PR_Unlock(sqlite_lock);
    52 #else
    53 #define LOCK_SQLITE()  
    54 #define UNLOCK_SQLITE()  
    55 #endif
    57 typedef enum {
    58 	SDB_CERT = 1,
    59 	SDB_KEY = 2
    60 } sdbDataType;
    62 /*
    63  * defines controlling how long we wait to acquire locks.
    64  *
    65  * SDB_SQLITE_BUSY_TIMEOUT specifies how long (in milliseconds)
    66  *  sqlite will wait on lock. If that timeout expires, sqlite will
    67  *  return SQLITE_BUSY.
    68  * SDB_BUSY_RETRY_TIME specifies how many seconds the sdb_ code waits
    69  *  after receiving a busy before retrying.
    70  * SDB_MAX_BUSY_RETRIES specifies how many times the sdb_ will retry on
    71  *  a busy condition.
    72  *
    73  * SDB_SQLITE_BUSY_TIMEOUT affects all opertions, both manual 
    74  *   (prepare/step/reset/finalize) and automatic (sqlite3_exec()).
    75  * SDB_BUSY_RETRY_TIME and SDB_MAX_BUSY_RETRIES only affect manual operations
    76  * 
    77  * total wait time for automatic operations: 
    78  *   1 second (SDB_SQLITE_BUSY_TIMEOUT/1000).
    79  * total wait time for manual operations: 
    80  *   (1 second + 5 seconds) * 10 = 60 seconds.
    81  * (SDB_SQLITE_BUSY_TIMEOUT/1000 + SDB_BUSY_RETRY_TIME)*SDB_MAX_BUSY_RETRIES
    82  */
    83 #define SDB_SQLITE_BUSY_TIMEOUT 1000 /* milliseconds */
    84 #define SDB_BUSY_RETRY_TIME        5 /* seconds */
    85 #define SDB_MAX_BUSY_RETRIES      10
    87 /*
    88  * Note on use of sqlReadDB: Only one thread at a time may have an actual
    89  * operation going on given sqlite3 * database. An operation is defined as
    90  * the time from a sqlite3_prepare() until the sqlite3_finalize().
    91  * Multiple sqlite3 * databases can be open and have simultaneous operations
    92  * going. We use the sqlXactDB for all write operations. This database
    93  * is only opened when we first create a transaction and closed when the
    94  * transaction is complete. sqlReadDB is open when we first opened the database
    95  * and is used for all read operation. It's use is protected by a monitor. This
    96  * is because an operation can span the use of FindObjectsInit() through the
    97  * call to FindObjectsFinal(). In the intermediate time it is possible to call
    98  * other operations like NSC_GetAttributeValue */
   100 struct SDBPrivateStr {
   101     char *sqlDBName;		/* invariant, path to this database */
   102     sqlite3 *sqlXactDB;		/* access protected by dbMon, use protected
   103                                  * by the transaction. Current transaction db*/
   104     PRThread *sqlXactThread;	/* protected by dbMon,
   105 			         * current transaction thread */
   106     sqlite3 *sqlReadDB;		/* use protected by dbMon, value invariant */
   107     PRIntervalTime lastUpdateTime;  /* last time the cache was updated */
   108     PRIntervalTime updateInterval;  /* how long the cache can go before it 
   109                                      * must be updated again */
   110     sdbDataType type;		/* invariant, database type */
   111     char *table;	        /* invariant, SQL table which contains the db */
   112     char *cacheTable;	        /* invariant, SQL table cache of db */
   113     PRMonitor *dbMon;		/* invariant, monitor to protect 
   114 				 * sqlXact* fields, and use of the sqlReadDB */
   115 };
   117 typedef struct SDBPrivateStr SDBPrivate;
   119 /*
   120  * known attributes
   121  */
   122 static const CK_ATTRIBUTE_TYPE known_attributes[] = {
   123     CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_LABEL, CKA_APPLICATION,
   124     CKA_VALUE, CKA_OBJECT_ID, CKA_CERTIFICATE_TYPE, CKA_ISSUER,
   125     CKA_SERIAL_NUMBER, CKA_AC_ISSUER, CKA_OWNER, CKA_ATTR_TYPES, CKA_TRUSTED,
   126     CKA_CERTIFICATE_CATEGORY, CKA_JAVA_MIDP_SECURITY_DOMAIN, CKA_URL,
   127     CKA_HASH_OF_SUBJECT_PUBLIC_KEY, CKA_HASH_OF_ISSUER_PUBLIC_KEY,
   128     CKA_CHECK_VALUE, CKA_KEY_TYPE, CKA_SUBJECT, CKA_ID, CKA_SENSITIVE,
   129     CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP, CKA_SIGN, CKA_SIGN_RECOVER,
   130     CKA_VERIFY, CKA_VERIFY_RECOVER, CKA_DERIVE, CKA_START_DATE, CKA_END_DATE,
   131     CKA_MODULUS, CKA_MODULUS_BITS, CKA_PUBLIC_EXPONENT, CKA_PRIVATE_EXPONENT,
   132     CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT,
   133     CKA_PRIME, CKA_SUBPRIME, CKA_BASE, CKA_PRIME_BITS, 
   134     CKA_SUB_PRIME_BITS, CKA_VALUE_BITS, CKA_VALUE_LEN, CKA_EXTRACTABLE,
   135     CKA_LOCAL, CKA_NEVER_EXTRACTABLE, CKA_ALWAYS_SENSITIVE,
   136     CKA_KEY_GEN_MECHANISM, CKA_MODIFIABLE, CKA_EC_PARAMS,
   137     CKA_EC_POINT, CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
   138     CKA_ALWAYS_AUTHENTICATE, CKA_WRAP_WITH_TRUSTED, CKA_WRAP_TEMPLATE,
   139     CKA_UNWRAP_TEMPLATE, CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT,
   140     CKA_HAS_RESET, CKA_PIXEL_X, CKA_PIXEL_Y, CKA_RESOLUTION, CKA_CHAR_ROWS,
   141     CKA_CHAR_COLUMNS, CKA_COLOR, CKA_BITS_PER_PIXEL, CKA_CHAR_SETS,
   142     CKA_ENCODING_METHODS, CKA_MIME_TYPES, CKA_MECHANISM_TYPE,
   143     CKA_REQUIRED_CMS_ATTRIBUTES, CKA_DEFAULT_CMS_ATTRIBUTES,
   144     CKA_SUPPORTED_CMS_ATTRIBUTES, CKA_NETSCAPE_URL, CKA_NETSCAPE_EMAIL,
   145     CKA_NETSCAPE_SMIME_INFO, CKA_NETSCAPE_SMIME_TIMESTAMP,
   146     CKA_NETSCAPE_PKCS8_SALT, CKA_NETSCAPE_PASSWORD_CHECK, CKA_NETSCAPE_EXPIRES,
   147     CKA_NETSCAPE_KRL, CKA_NETSCAPE_PQG_COUNTER, CKA_NETSCAPE_PQG_SEED,
   148     CKA_NETSCAPE_PQG_H, CKA_NETSCAPE_PQG_SEED_BITS, CKA_NETSCAPE_MODULE_SPEC,
   149     CKA_TRUST_DIGITAL_SIGNATURE, CKA_TRUST_NON_REPUDIATION,
   150     CKA_TRUST_KEY_ENCIPHERMENT, CKA_TRUST_DATA_ENCIPHERMENT,
   151     CKA_TRUST_KEY_AGREEMENT, CKA_TRUST_KEY_CERT_SIGN, CKA_TRUST_CRL_SIGN,
   152     CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH, CKA_TRUST_CODE_SIGNING,
   153     CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_IPSEC_END_SYSTEM,
   154     CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER, CKA_TRUST_TIME_STAMPING,
   155     CKA_TRUST_STEP_UP_APPROVED, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH,
   156     CKA_NETSCAPE_DB, CKA_NETSCAPE_TRUST, CKA_NSS_OVERRIDE_EXTENSIONS
   157 };
   159 static int known_attributes_size= sizeof(known_attributes)/
   160 			   sizeof(known_attributes[0]);
   162 /* Magic for an explicit NULL. NOTE: ideally this should be
   163  * out of band data. Since it's not completely out of band, pick
   164  * a value that has no meaning to any existing PKCS #11 attributes.
   165  * This value is 1) not a valid string (imbedded '\0'). 2) not a U_LONG
   166  * or a normal key (too short). 3) not a bool (too long). 4) not an RSA
   167  * public exponent (too many bits).
   168  */
   169 const unsigned char SQLITE_EXPLICIT_NULL[] = { 0xa5, 0x0, 0x5a };
   170 #define SQLITE_EXPLICIT_NULL_LEN 3
   172 /*
   173  * determine when we've completed our tasks
   174  */
   175 static int 
   176 sdb_done(int err, int *count)
   177 {
   178     /* allow as many rows as the database wants to give */
   179     if (err == SQLITE_ROW) {
   180 	*count = 0;
   181 	return 0;
   182     }
   183     if (err != SQLITE_BUSY) {
   184 	return 1;
   185     }
   186     /* err == SQLITE_BUSY, Dont' retry forever in this case */
   187     if (++(*count) >= SDB_MAX_BUSY_RETRIES) {
   188 	return 1;
   189     }
   190     return 0;
   191 }
   193 /*
   194  * find out where sqlite stores the temp tables. We do this by replicating
   195  * the logic from sqlite.
   196  */
   197 #if defined(_WIN32)
   198 static char *
   199 sdb_getFallbackTempDir(void)
   200 {
   201     /* sqlite uses sqlite3_temp_directory if it is not NULL. We don't have
   202      * access to sqlite3_temp_directory because it is not exported from
   203      * sqlite3.dll. Assume sqlite3_win32_set_directory isn't called and
   204      * sqlite3_temp_directory is NULL.
   205      */
   206     char path[MAX_PATH];
   207     DWORD rv;
   208     size_t len;
   210     rv = GetTempPathA(MAX_PATH, path);
   211     if (rv > MAX_PATH || rv == 0)
   212         return NULL;
   213     len = strlen(path);
   214     if (len == 0)
   215         return NULL;
   216     /* The returned string ends with a backslash, for example, "C:\TEMP\". */
   217     if (path[len - 1] == '\\')
   218         path[len - 1] = '\0';
   219     return PORT_Strdup(path);
   220 }
   221 #elif defined(XP_UNIX)
   222 static char *
   223 sdb_getFallbackTempDir(void)
   224 {
   225     const char *azDirs[] = {
   226         NULL,
   227         NULL,
   228         "/var/tmp",
   229         "/usr/tmp",
   230         "/tmp",
   231         NULL     /* List terminator */
   232     };
   233     unsigned int i;
   234     struct stat buf;
   235     const char *zDir = NULL;
   237     azDirs[0] = sqlite3_temp_directory;
   238     azDirs[1] = getenv("TMPDIR");
   240     for (i = 0; i < PR_ARRAY_SIZE(azDirs); i++) {
   241         zDir = azDirs[i];
   242         if (zDir == NULL) continue;
   243         if (stat(zDir, &buf)) continue;
   244         if (!S_ISDIR(buf.st_mode)) continue;
   245         if (access(zDir, 07)) continue;
   246         break;
   247     }
   249     if (zDir == NULL)
   250         return NULL;
   251     return PORT_Strdup(zDir);
   252 }
   253 #else
   254 #error "sdb_getFallbackTempDir not implemented"
   255 #endif
   257 #ifndef SQLITE_FCNTL_TEMPFILENAME
   258 /* SQLITE_FCNTL_TEMPFILENAME was added in SQLite 3.7.15 */
   259 #define SQLITE_FCNTL_TEMPFILENAME 16
   260 #endif
   262 static char *
   263 sdb_getTempDir(sqlite3 *sqlDB)
   264 {
   265     int sqlrv;
   266     char *result = NULL;
   267     char *tempName = NULL;
   268     char *foundSeparator = NULL;
   270     /* Obtain temporary filename in sqlite's directory for temporary tables */
   271     sqlrv = sqlite3_file_control(sqlDB, 0, SQLITE_FCNTL_TEMPFILENAME,
   272 				 (void*)&tempName);
   273     if (sqlrv == SQLITE_NOTFOUND) {
   274 	/* SQLITE_FCNTL_TEMPFILENAME not implemented because we are using
   275 	 * an older SQLite. */
   276 	return sdb_getFallbackTempDir();
   277     }
   278     if (sqlrv != SQLITE_OK) {
   279 	return NULL;
   280     }
   282     /* We'll extract the temporary directory from tempName */
   283     foundSeparator = PORT_Strrchr(tempName, PR_GetDirectorySeparator());
   284     if (foundSeparator) {
   285 	/* We shorten the temp filename string to contain only
   286 	  * the directory name (including the trailing separator).
   287 	  * We know the byte after the foundSeparator position is
   288 	  * safe to use, in the shortest scenario it contains the
   289 	  * end-of-string byte.
   290 	  * By keeping the separator at the found position, it will
   291 	  * even work if tempDir consists of the separator, only.
   292 	  * (In this case the toplevel directory will be used for
   293 	  * access speed testing). */
   294 	++foundSeparator;
   295 	*foundSeparator = 0;
   297 	/* Now we copy the directory name for our caller */
   298 	result = PORT_Strdup(tempName);
   299     }
   301     sqlite3_free(tempName);
   302     return result;
   303 }
   305 /*
   306  * Map SQL_LITE errors to PKCS #11 errors as best we can.
   307  */
   308 static CK_RV
   309 sdb_mapSQLError(sdbDataType type, int sqlerr)
   310 {
   311     switch (sqlerr) {
   312     /* good matches */
   313     case SQLITE_OK:
   314     case SQLITE_DONE:
   315 	return CKR_OK;
   316     case SQLITE_NOMEM:
   317 	return CKR_HOST_MEMORY;
   318     case SQLITE_READONLY:
   319 	return CKR_TOKEN_WRITE_PROTECTED;
   320     /* close matches */
   321     case SQLITE_AUTH:
   322     case SQLITE_PERM:
   323 	/*return CKR_USER_NOT_LOGGED_IN; */
   324     case SQLITE_CANTOPEN:
   325     case SQLITE_NOTFOUND:
   326 	/* NSS distiguishes between failure to open the cert and the key db */
   327 	return type == SDB_CERT ? 
   328 		CKR_NETSCAPE_CERTDB_FAILED : CKR_NETSCAPE_KEYDB_FAILED;
   329     case SQLITE_IOERR:
   330 	return CKR_DEVICE_ERROR;
   331     default:
   332 	break;
   333     }
   334     return CKR_GENERAL_ERROR;
   335 }
   338 /*
   339  * build up database name from a directory, prefix, name, version and flags.
   340  */
   341 static char *sdb_BuildFileName(const char * directory, 
   342 			const char *prefix, const char *type, 
   343 			int version)
   344 {
   345     char *dbname = NULL;
   346     /* build the full dbname */
   347     dbname = sqlite3_mprintf("%s%c%s%s%d.db", directory,
   348 			     (int)(unsigned char)PR_GetDirectorySeparator(),
   349 			     prefix, type, version);
   350     return dbname;
   351 }
   354 /*
   355  * find out how expensive the access system call is for non-existant files
   356  * in the given directory.  Return the number of operations done in 33 ms.
   357  */
   358 static PRUint32
   359 sdb_measureAccess(const char *directory)
   360 {
   361     PRUint32 i;
   362     PRIntervalTime time;
   363     PRIntervalTime delta;
   364     PRIntervalTime duration = PR_MillisecondsToInterval(33);
   365     const char *doesntExistName = "_dOeSnotExist_.db";
   366     char *temp, *tempStartOfFilename;
   367     size_t maxTempLen, maxFileNameLen, directoryLength;
   369     /* no directory, just return one */
   370     if (directory == NULL) {
   371 	return 1;
   372     }
   374     /* our calculation assumes time is a 4 bytes == 32 bit integer */
   375     PORT_Assert(sizeof(time) == 4);
   377     directoryLength = strlen(directory);
   379     maxTempLen = directoryLength + strlen(doesntExistName)
   380 		 + 1 /* potential additional separator char */
   381 		 + 11 /* max chars for 32 bit int plus potential sign */
   382 		 + 1; /* zero terminator */
   384     temp = PORT_Alloc(maxTempLen);
   385     if (!temp) {
   386         return 1;
   387     }
   389     /* We'll copy directory into temp just once, then ensure it ends
   390      * with the directory separator, then remember the position after
   391      * the separator, and calculate the number of remaining bytes. */
   393     strcpy(temp, directory);
   394     if (directory[directoryLength - 1] != PR_GetDirectorySeparator()) {
   395 	temp[directoryLength++] = PR_GetDirectorySeparator();
   396     }
   397     tempStartOfFilename = temp + directoryLength;
   398     maxFileNameLen = maxTempLen - directoryLength;
   400     /* measure number of Access operations that can be done in 33 milliseconds
   401      * (1/30'th of a second), or 10000 operations, which ever comes first.
   402      */
   403     time =  PR_IntervalNow();
   404     for (i=0; i < 10000u; i++) { 
   405 	PRIntervalTime next;
   407 	/* We'll use the variable part first in the filename string, just in
   408 	 * case it's longer than assumed, so if anything gets cut off, it
   409 	 * will be cut off from the constant part.
   410 	 * This code assumes the directory name at the beginning of
   411 	 * temp remains unchanged during our loop. */
   412         PR_snprintf(tempStartOfFilename, maxFileNameLen,
   413 		    ".%lu%s", (PRUint32)(time+i), doesntExistName);
   414 	PR_Access(temp,PR_ACCESS_EXISTS);
   415 	next = PR_IntervalNow();
   416 	delta = next - time;
   417 	if (delta >= duration)
   418 	    break;
   419     }
   421     PORT_Free(temp);
   423     /* always return 1 or greater */
   424     return i ? i : 1u;
   425 }
   427 /*
   428  * some file sytems are very slow to run sqlite3 on, particularly if the
   429  * access count is pretty high. On these filesystems is faster to create
   430  * a temporary database on the local filesystem and access that. This
   431  * code uses a temporary table to create that cache. Temp tables are
   432  * automatically cleared when the database handle it was created on
   433  * Is freed.
   434  */
   435 static const char DROP_CACHE_CMD[] = "DROP TABLE %s";
   436 static const char CREATE_CACHE_CMD[] =
   437   "CREATE TEMPORARY TABLE %s AS SELECT * FROM %s";
   438 static const char CREATE_ISSUER_INDEX_CMD[] = 
   439   "CREATE INDEX issuer ON %s (a81)";
   440 static const char CREATE_SUBJECT_INDEX_CMD[] = 
   441   "CREATE INDEX subject ON %s (a101)";
   442 static const char CREATE_LABEL_INDEX_CMD[] = "CREATE INDEX label ON %s (a3)";
   443 static const char CREATE_ID_INDEX_CMD[] = "CREATE INDEX ckaid ON %s (a102)";
   445 static CK_RV
   446 sdb_buildCache(sqlite3 *sqlDB, sdbDataType type, 
   447 		const char *cacheTable, const char *table)
   448 {
   449     char *newStr;
   450     int sqlerr = SQLITE_OK;
   452     newStr = sqlite3_mprintf(CREATE_CACHE_CMD, cacheTable, table);
   453     if (newStr == NULL) {
   454 	return CKR_HOST_MEMORY;
   455     }
   456     sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
   457     sqlite3_free(newStr);
   458     if (sqlerr != SQLITE_OK) {
   459 	return sdb_mapSQLError(type, sqlerr); 
   460     }
   461     /* failure to create the indexes is not an issue */
   462     newStr = sqlite3_mprintf(CREATE_ISSUER_INDEX_CMD, cacheTable);
   463     if (newStr == NULL) {
   464 	return CKR_OK;
   465     }
   466     sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
   467     sqlite3_free(newStr);
   468     newStr = sqlite3_mprintf(CREATE_SUBJECT_INDEX_CMD, cacheTable);
   469     if (newStr == NULL) {
   470 	return CKR_OK;
   471     }
   472     sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
   473     sqlite3_free(newStr);
   474     newStr = sqlite3_mprintf(CREATE_LABEL_INDEX_CMD, cacheTable);
   475     if (newStr == NULL) {
   476 	return CKR_OK;
   477     }
   478     sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
   479     sqlite3_free(newStr);
   480     newStr = sqlite3_mprintf(CREATE_ID_INDEX_CMD, cacheTable);
   481     if (newStr == NULL) {
   482 	return CKR_OK;
   483     }
   484     sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
   485     sqlite3_free(newStr);
   486     return CKR_OK;
   487 }
   489 /*
   490  * update the cache and the data records describing it.
   491  *  The cache is updated by dropping the temp database and recreating it.
   492  */
   493 static CK_RV
   494 sdb_updateCache(SDBPrivate *sdb_p)
   495 {
   496     int sqlerr = SQLITE_OK;
   497     CK_RV error = CKR_OK;
   498     char *newStr;
   500     /* drop the old table */
   501     newStr = sqlite3_mprintf(DROP_CACHE_CMD, sdb_p->cacheTable);
   502     if (newStr == NULL) {
   503 	return CKR_HOST_MEMORY;
   504     }
   505     sqlerr = sqlite3_exec(sdb_p->sqlReadDB, newStr, NULL, 0, NULL);
   506     sqlite3_free(newStr);
   507     if ((sqlerr != SQLITE_OK) && (sqlerr != SQLITE_ERROR )) {
   508         /* something went wrong with the drop, don't try to refresh...
   509          * NOTE: SQLITE_ERROR is returned if the table doesn't exist. In
   510          * that case, we just continue on and try to reload it */
   511 	return sdb_mapSQLError(sdb_p->type, sqlerr); 
   512     }
   515     /* set up the new table */
   516     error = sdb_buildCache(sdb_p->sqlReadDB,sdb_p->type,
   517 				sdb_p->cacheTable,sdb_p->table );
   518     if (error == CKR_OK) {
   519 	/* we have a new cache! */
   520 	sdb_p->lastUpdateTime = PR_IntervalNow();
   521     }
   522     return error;
   523 }
   525 /*
   526  *  The sharing of sqlite3 handles across threads is tricky. Older versions
   527  *  couldn't at all, but newer ones can under strict conditions. Basically
   528  *  no 2 threads can use the same handle while another thread has an open
   529  *  stmt running. Once the sqlite3_stmt is finalized, another thread can then
   530  *  use the database handle.
   531  *
   532  *  We use monitors to protect against trying to use a database before
   533  *  it's sqlite3_stmt is finalized. This is preferable to the opening and
   534  *  closing the database each operation because there is significant overhead
   535  *  in the open and close. Also continually opening and closing the database
   536  *  defeats the cache code as the cache table is lost on close (thus
   537  *  requiring us to have to reinitialize the cache every operation).
   538  * 
   539  *  An execption to the shared handle is transations. All writes happen
   540  *  through a transaction. When we are in  a transaction, we must use the 
   541  *  same database pointer for that entire transation. In this case we save 
   542  *  the transaction database and use it for all accesses on the transaction 
   543  *  thread. Other threads use the common database.  
   544  *
   545  *  There can only be once active transaction on the database at a time.
   546  *
   547  *  sdb_openDBLocal() provides us with a valid database handle for whatever
   548  *  state we are in (reading or in a transaction), and acquires any locks
   549  *  appropriate to that state. It also decides when it's time to refresh
   550  *  the cache before we start an operation. Any database handle returned
   551  *  just eventually be closed with sdb_closeDBLocal().
   552  *
   553  *  The table returned either points to the database's physical table, or
   554  *  to the cached shadow. Tranactions always return the physical table
   555  *  and read operations return either the physical table or the cache
   556  *  depending on whether or not the cache exists.
   557  */
   558 static CK_RV 
   559 sdb_openDBLocal(SDBPrivate *sdb_p, sqlite3 **sqlDB, const char **table)
   560 {
   561     *sqlDB = NULL;
   563     PR_EnterMonitor(sdb_p->dbMon);
   565     if (table) {
   566 	*table = sdb_p->table;
   567     }
   569     /* We're in a transaction, use the transaction DB */
   570     if ((sdb_p->sqlXactDB) && (sdb_p->sqlXactThread == PR_GetCurrentThread())) {
   571 	*sqlDB =sdb_p->sqlXactDB;
   572 	/* only one thread can get here, safe to unlock */
   573         PR_ExitMonitor(sdb_p->dbMon);
   574 	return CKR_OK;
   575     }
   577     /*
   578      * if we are just reading from the table, we may have the table
   579      * cached in a temporary table (especially if it's on a shared FS).
   580      * In that case we want to see updates to the table, the the granularity
   581      * is on order of human scale, not computer scale.
   582      */
   583     if (table && sdb_p->cacheTable) {
   584 	PRIntervalTime now = PR_IntervalNow();
   585 	if ((now - sdb_p->lastUpdateTime) > sdb_p->updateInterval) {
   586 	       sdb_updateCache(sdb_p);
   587         }
   588 	*table = sdb_p->cacheTable;
   589     }
   591     *sqlDB = sdb_p->sqlReadDB;
   593     /* leave holding the lock. only one thread can actually use a given
   594      * database connection at once */
   596     return CKR_OK;
   597 }
   599 /* closing the local database currenly means unlocking the monitor */
   600 static CK_RV 
   601 sdb_closeDBLocal(SDBPrivate *sdb_p, sqlite3 *sqlDB) 
   602 {
   603    if (sdb_p->sqlXactDB != sqlDB) {
   604 	/* if we weren't in a transaction, we got a lock */
   605         PR_ExitMonitor(sdb_p->dbMon);
   606    }
   607    return CKR_OK;
   608 }
   611 /*
   612  * wrapper to sqlite3_open which also sets the busy_timeout
   613  */
   614 static int
   615 sdb_openDB(const char *name, sqlite3 **sqlDB, int flags)
   616 {
   617     int sqlerr;
   618     /*
   619      * in sqlite3 3.5.0, there is a new open call that allows us
   620      * to specify read only. Most new OS's are still on 3.3.x (including
   621      * NSS's internal version and the version shipped with Firefox).
   622      */
   623     *sqlDB = NULL;
   624     sqlerr = sqlite3_open(name, sqlDB);
   625     if (sqlerr != SQLITE_OK) {
   626 	return sqlerr;
   627     }
   629     sqlerr = sqlite3_busy_timeout(*sqlDB, SDB_SQLITE_BUSY_TIMEOUT);
   630     if (sqlerr != SQLITE_OK) {
   631 	sqlite3_close(*sqlDB);
   632 	*sqlDB = NULL;
   633 	return sqlerr;
   634     }
   635     return SQLITE_OK;
   636 }
   638 /* Sigh, if we created a new table since we opened the database,
   639  * the database handle will not see the new table, we need to close this
   640  * database and reopen it. Caller must be in a transaction or holding
   641  * the dbMon. sqlDB is changed on success. */
   642 static int 
   643 sdb_reopenDBLocal(SDBPrivate *sdb_p, sqlite3 **sqlDB) {
   644     sqlite3 *newDB;
   645     int sqlerr;
   647     /* open a new database */
   648     sqlerr = sdb_openDB(sdb_p->sqlDBName, &newDB, SDB_RDONLY);
   649     if (sqlerr != SQLITE_OK) {
   650 	return sqlerr;
   651     }
   653     /* if we are in a transaction, we may not be holding the monitor.
   654      * grab it before we update the transaction database. This is
   655      * safe since are using monitors. */
   656     PR_EnterMonitor(sdb_p->dbMon);
   657     /* update our view of the database */
   658     if (sdb_p->sqlReadDB == *sqlDB) {
   659 	sdb_p->sqlReadDB = newDB;
   660     } else if (sdb_p->sqlXactDB == *sqlDB) {
   661 	sdb_p->sqlXactDB = newDB;
   662     }
   663     PR_ExitMonitor(sdb_p->dbMon);
   665     /* close the old one */
   666     sqlite3_close(*sqlDB);
   668     *sqlDB = newDB;
   669     return SQLITE_OK;
   670 }
   672 struct SDBFindStr {
   673     sqlite3 *sqlDB;
   674     sqlite3_stmt *findstmt;
   675 };
   678 static const char FIND_OBJECTS_CMD[] =  "SELECT ALL * FROM %s WHERE %s;";
   679 static const char FIND_OBJECTS_ALL_CMD[] = "SELECT ALL * FROM %s;";
   680 CK_RV
   681 sdb_FindObjectsInit(SDB *sdb, const CK_ATTRIBUTE *template, CK_ULONG count, 
   682 				SDBFind **find)
   683 {
   684     SDBPrivate *sdb_p = sdb->private;
   685     sqlite3  *sqlDB = NULL;
   686     const char *table;
   687     char *newStr, *findStr = NULL;
   688     sqlite3_stmt *findstmt = NULL;
   689     char *join="";
   690     int sqlerr = SQLITE_OK;
   691     CK_RV error = CKR_OK;
   692     int i;
   694     LOCK_SQLITE()
   695     *find = NULL;
   696     error = sdb_openDBLocal(sdb_p, &sqlDB, &table);
   697     if (error != CKR_OK) {
   698 	goto loser;
   699     }
   701     findStr = sqlite3_mprintf("");
   702     for (i=0; findStr && i < count; i++) {
   703 	newStr = sqlite3_mprintf("%s%sa%x=$DATA%d", findStr, join,
   704 				template[i].type, i);
   705         join=" AND ";
   706 	sqlite3_free(findStr);
   707 	findStr = newStr;
   708     }
   710     if (findStr == NULL) {
   711 	error = CKR_HOST_MEMORY;
   712 	goto loser;
   713     }
   715     if (count == 0) {
   716 	newStr = sqlite3_mprintf(FIND_OBJECTS_ALL_CMD, table);
   717     } else {
   718 	newStr = sqlite3_mprintf(FIND_OBJECTS_CMD, table, findStr);
   719     }
   720     sqlite3_free(findStr);
   721     if (newStr == NULL) {
   722 	error = CKR_HOST_MEMORY;
   723 	goto loser;
   724     }
   725     sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &findstmt, NULL);
   726     sqlite3_free(newStr);
   727     for (i=0; sqlerr == SQLITE_OK && i < count; i++) {
   728 	const void *blobData = template[i].pValue;
   729 	unsigned int blobSize = template[i].ulValueLen;
   730 	if (blobSize == 0) {
   731 	    blobSize = SQLITE_EXPLICIT_NULL_LEN;
   732 	    blobData = SQLITE_EXPLICIT_NULL;
   733 	}
   734 	sqlerr = sqlite3_bind_blob(findstmt, i+1, blobData, blobSize,
   735 				   SQLITE_TRANSIENT);
   736     }
   737     if (sqlerr == SQLITE_OK) {
   738 	*find = PORT_New(SDBFind);
   739 	if (*find == NULL) {
   740 	    error = CKR_HOST_MEMORY;
   741 	    goto loser;
   742 	}
   743 	(*find)->findstmt = findstmt;
   744 	(*find)->sqlDB = sqlDB;
   745 	UNLOCK_SQLITE()  
   746 	return CKR_OK;
   747     } 
   748     error = sdb_mapSQLError(sdb_p->type, sqlerr);
   750 loser: 
   751     if (findstmt) {
   752 	sqlite3_reset(findstmt);
   753 	sqlite3_finalize(findstmt);
   754     }
   755     if (sqlDB) {
   756 	sdb_closeDBLocal(sdb_p, sqlDB) ;
   757     }
   758     UNLOCK_SQLITE()  
   759     return error;
   760 }
   763 CK_RV
   764 sdb_FindObjects(SDB *sdb, SDBFind *sdbFind, CK_OBJECT_HANDLE *object, 
   765 		CK_ULONG arraySize, CK_ULONG *count)
   766 {
   767     SDBPrivate *sdb_p = sdb->private;
   768     sqlite3_stmt *stmt = sdbFind->findstmt;
   769     int sqlerr = SQLITE_OK;
   770     int retry = 0;
   772     *count = 0;
   774     if (arraySize == 0) {
   775 	return CKR_OK;
   776     }
   777     LOCK_SQLITE()  
   779     do {
   780 	sqlerr = sqlite3_step(stmt);
   781 	if (sqlerr == SQLITE_BUSY) {
   782 	    PR_Sleep(SDB_BUSY_RETRY_TIME);
   783 	}
   784 	if (sqlerr == SQLITE_ROW) {
   785 	    /* only care about the id */
   786 	    *object++= sqlite3_column_int(stmt, 0);
   787 	    arraySize--;
   788 	    (*count)++;
   789 	}
   790     } while (!sdb_done(sqlerr,&retry) && (arraySize > 0));
   792     /* we only have some of the objects, there is probably more,
   793      * set the sqlerr to an OK value so we return CKR_OK */
   794     if (sqlerr == SQLITE_ROW && arraySize == 0) {
   795 	sqlerr = SQLITE_DONE;
   796     }
   797     UNLOCK_SQLITE()  
   799     return sdb_mapSQLError(sdb_p->type, sqlerr);
   800 }
   802 CK_RV
   803 sdb_FindObjectsFinal(SDB *sdb, SDBFind *sdbFind)
   804 {
   805     SDBPrivate *sdb_p = sdb->private;
   806     sqlite3_stmt *stmt = sdbFind->findstmt;
   807     sqlite3 *sqlDB = sdbFind->sqlDB;
   808     int sqlerr = SQLITE_OK;
   810     LOCK_SQLITE()  
   811     if (stmt) {
   812 	sqlite3_reset(stmt);
   813 	sqlerr = sqlite3_finalize(stmt);
   814     }
   815     if (sqlDB) {
   816 	sdb_closeDBLocal(sdb_p, sqlDB) ;
   817     }
   818     PORT_Free(sdbFind);
   820     UNLOCK_SQLITE()  
   821     return sdb_mapSQLError(sdb_p->type, sqlerr);
   822 }
   824 static const char GET_ATTRIBUTE_CMD[] = "SELECT ALL %s FROM %s WHERE id=$ID;";
   825 CK_RV
   826 sdb_GetAttributeValueNoLock(SDB *sdb, CK_OBJECT_HANDLE object_id, 
   827 				CK_ATTRIBUTE *template, CK_ULONG count)
   828 {
   829     SDBPrivate *sdb_p = sdb->private;
   830     sqlite3  *sqlDB = NULL;
   831     sqlite3_stmt *stmt = NULL;
   832     char *getStr = NULL;
   833     char *newStr = NULL;
   834     const char *table = NULL;
   835     int sqlerr = SQLITE_OK;
   836     CK_RV error = CKR_OK;
   837     int found = 0;
   838     int retry = 0;
   839     int i;
   842     /* open a new db if necessary */
   843     error = sdb_openDBLocal(sdb_p, &sqlDB, &table);
   844     if (error != CKR_OK) {
   845 	goto loser;
   846     }
   848     for (i=0; i < count; i++) {
   849 	getStr = sqlite3_mprintf("a%x", template[i].type);
   851 	if (getStr == NULL) {
   852 	    error = CKR_HOST_MEMORY;
   853 	    goto loser;
   854 	}
   856 	newStr = sqlite3_mprintf(GET_ATTRIBUTE_CMD, getStr, table);
   857 	sqlite3_free(getStr);
   858 	getStr = NULL;
   859 	if (newStr == NULL) {
   860 	    error = CKR_HOST_MEMORY;
   861 	    goto loser;
   862 	}
   864 	sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL);
   865 	sqlite3_free(newStr);
   866 	newStr = NULL;
   867 	if (sqlerr == SQLITE_ERROR) {
   868 	    template[i].ulValueLen = -1;
   869 	    error = CKR_ATTRIBUTE_TYPE_INVALID;
   870 	    continue;
   871 	} else if (sqlerr != SQLITE_OK) { goto loser; }
   873 	sqlerr = sqlite3_bind_int(stmt, 1, object_id);
   874 	if (sqlerr != SQLITE_OK) { goto loser; }
   876 	do {
   877 	    sqlerr = sqlite3_step(stmt);
   878 	    if (sqlerr == SQLITE_BUSY) {
   879 		PR_Sleep(SDB_BUSY_RETRY_TIME);
   880 	    }
   881 	    if (sqlerr == SQLITE_ROW) {
   882 	    	int blobSize;
   883 	    	const char *blobData;
   885 	    	blobSize = sqlite3_column_bytes(stmt, 0);
   886 		blobData = sqlite3_column_blob(stmt, 0);
   887 		if (blobData == NULL) {
   888 		    template[i].ulValueLen = -1;
   889 		    error = CKR_ATTRIBUTE_TYPE_INVALID; 
   890 		    break;
   891 		}
   892 		/* If the blob equals our explicit NULL value, then the 
   893 		 * attribute is a NULL. */
   894 		if ((blobSize == SQLITE_EXPLICIT_NULL_LEN) &&
   895 		   	(PORT_Memcmp(blobData, SQLITE_EXPLICIT_NULL, 
   896 			      SQLITE_EXPLICIT_NULL_LEN) == 0)) {
   897 		    blobSize = 0;
   898 		}
   899 		if (template[i].pValue) {
   900 		    if (template[i].ulValueLen < blobSize) {
   901 			template[i].ulValueLen = -1;
   902 		    	error = CKR_BUFFER_TOO_SMALL;
   903 			break;
   904 		    }
   905 	    	    PORT_Memcpy(template[i].pValue, blobData, blobSize);
   906 		}
   907 		template[i].ulValueLen = blobSize;
   908 		found = 1;
   909 	    }
   910 	} while (!sdb_done(sqlerr,&retry));
   911 	sqlite3_reset(stmt);
   912 	sqlite3_finalize(stmt);
   913 	stmt = NULL;
   914     }
   916 loser:
   917     /* fix up the error if necessary */
   918     if (error == CKR_OK) {
   919 	error = sdb_mapSQLError(sdb_p->type, sqlerr);
   920 	if (!found && error == CKR_OK) {
   921 	    error = CKR_OBJECT_HANDLE_INVALID;
   922 	}
   923     }
   925     if (stmt) {
   926 	sqlite3_reset(stmt);
   927 	sqlite3_finalize(stmt);
   928     }
   930     /* if we had to open a new database, free it now */
   931     if (sqlDB) {
   932 	sdb_closeDBLocal(sdb_p, sqlDB) ;
   933     }
   934     return error;
   935 }
   937 CK_RV
   938 sdb_GetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE object_id, 
   939 				CK_ATTRIBUTE *template, CK_ULONG count)
   940 {
   941     CK_RV crv;
   943     if (count == 0) {
   944 	return CKR_OK;
   945     }
   947     LOCK_SQLITE()  
   948     crv = sdb_GetAttributeValueNoLock(sdb, object_id, template, count);
   949     UNLOCK_SQLITE()  
   950     return crv;
   951 }
   953 static const char SET_ATTRIBUTE_CMD[] = "UPDATE %s SET %s WHERE id=$ID;";
   954 CK_RV
   955 sdb_SetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE object_id, 
   956 			const CK_ATTRIBUTE *template, CK_ULONG count)
   957 {
   958     SDBPrivate *sdb_p = sdb->private;
   959     sqlite3  *sqlDB = NULL;
   960     sqlite3_stmt *stmt = NULL;
   961     char *setStr = NULL;
   962     char *newStr = NULL;
   963     int sqlerr = SQLITE_OK;
   964     int retry = 0;
   965     CK_RV error = CKR_OK;
   966     int i;
   968     if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
   969 	return CKR_TOKEN_WRITE_PROTECTED;
   970     }
   972     if (count == 0) {
   973 	return CKR_OK;
   974     }
   976     LOCK_SQLITE()  
   977     setStr = sqlite3_mprintf("");
   978     for (i=0; setStr && i < count; i++) {
   979 	if (i==0) {
   980 	    sqlite3_free(setStr);
   981    	    setStr = sqlite3_mprintf("a%x=$VALUE%d", 
   982 				template[i].type, i);
   983 	    continue;
   984 	}
   985 	newStr = sqlite3_mprintf("%s,a%x=$VALUE%d", setStr, 
   986 				template[i].type, i);
   987 	sqlite3_free(setStr);
   988 	setStr = newStr;
   989     }
   990     newStr = NULL;
   992     if (setStr == NULL) {
   993 	return CKR_HOST_MEMORY;
   994     }
   995     newStr =  sqlite3_mprintf(SET_ATTRIBUTE_CMD, sdb_p->table, setStr);
   996     sqlite3_free(setStr);
   997     if (newStr == NULL) {
   998 	UNLOCK_SQLITE()  
   999 	return CKR_HOST_MEMORY;
  1001     error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
  1002     if (error != CKR_OK) {
  1003 	goto loser;
  1005     sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL);
  1006     if (sqlerr != SQLITE_OK) goto loser;
  1007     for (i=0; i < count; i++) {
  1008 	if (template[i].ulValueLen != 0) {
  1009 	    sqlerr = sqlite3_bind_blob(stmt, i+1, template[i].pValue, 
  1010 				template[i].ulValueLen, SQLITE_STATIC);
  1011 	} else {
  1012 	    sqlerr = sqlite3_bind_blob(stmt, i+2, SQLITE_EXPLICIT_NULL, 
  1013 			SQLITE_EXPLICIT_NULL_LEN, SQLITE_STATIC);
  1015         if (sqlerr != SQLITE_OK) goto loser;
  1017     sqlerr = sqlite3_bind_int(stmt, i+1, object_id);
  1018     if (sqlerr != SQLITE_OK) goto loser;
  1020     do {
  1021 	sqlerr = sqlite3_step(stmt);
  1022 	if (sqlerr == SQLITE_BUSY) {
  1023 	    PR_Sleep(SDB_BUSY_RETRY_TIME);
  1025     } while (!sdb_done(sqlerr,&retry));
  1027 loser:
  1028     if (newStr) {
  1029 	sqlite3_free(newStr);
  1031     if (error == CKR_OK) {
  1032 	error = sdb_mapSQLError(sdb_p->type, sqlerr);
  1035     if (stmt) {
  1036 	sqlite3_reset(stmt);
  1037 	sqlite3_finalize(stmt);
  1040     if (sqlDB) {
  1041 	sdb_closeDBLocal(sdb_p, sqlDB) ;
  1044     UNLOCK_SQLITE()  
  1045     return error;
  1048 /*
  1049  * check to see if a candidate object handle already exists.
  1050  */
  1051 static PRBool
  1052 sdb_objectExists(SDB *sdb, CK_OBJECT_HANDLE candidate)
  1054     CK_RV crv;
  1055     CK_ATTRIBUTE template = { CKA_LABEL, NULL, 0 };
  1057     crv = sdb_GetAttributeValueNoLock(sdb,candidate,&template, 1);
  1058     if (crv == CKR_OBJECT_HANDLE_INVALID) {
  1059 	return PR_FALSE;
  1061     return PR_TRUE;
  1064 /*
  1065  * if we're here, we are in a transaction, so it's safe
  1066  * to examine the current state of the database
  1067  */
  1068 static CK_OBJECT_HANDLE
  1069 sdb_getObjectId(SDB *sdb)
  1071     CK_OBJECT_HANDLE candidate;
  1072     static CK_OBJECT_HANDLE next_obj = CK_INVALID_HANDLE;
  1073     int count;
  1074     /*
  1075      * get an initial object handle to use
  1076      */
  1077     if (next_obj == CK_INVALID_HANDLE) {
  1078         PRTime time;
  1079 	time = PR_Now();
  1081 	next_obj = (CK_OBJECT_HANDLE)(time & 0x3fffffffL);
  1083     candidate = next_obj++;
  1084     /* detect that we've looped through all the handles... */
  1085     for (count = 0; count < 0x40000000; count++, candidate = next_obj++) {
  1086 	/* mask off excess bits */
  1087 	candidate &= 0x3fffffff;
  1088 	/* if we hit zero, go to the next entry */
  1089 	if (candidate == CK_INVALID_HANDLE) {
  1090 	    continue;
  1092 	/* make sure we aren't already using */
  1093 	if (!sdb_objectExists(sdb, candidate)) {
  1094 	    /* this one is free */
  1095 	    return candidate;
  1099     /* no handle is free, fail */
  1100     return CK_INVALID_HANDLE;
  1103 static const char CREATE_CMD[] = "INSERT INTO %s (id%s) VALUES($ID%s);";
  1104 CK_RV
  1105 sdb_CreateObject(SDB *sdb, CK_OBJECT_HANDLE *object_id, 
  1106 		 const CK_ATTRIBUTE *template, CK_ULONG count)
  1108     SDBPrivate *sdb_p = sdb->private;
  1109     sqlite3  *sqlDB = NULL;
  1110     sqlite3_stmt *stmt = NULL;
  1111     char *columnStr = NULL;
  1112     char *valueStr = NULL;
  1113     char *newStr = NULL;
  1114     int sqlerr = SQLITE_OK;
  1115     CK_RV error = CKR_OK;
  1116     CK_OBJECT_HANDLE this_object = CK_INVALID_HANDLE;
  1117     int retry = 0;
  1118     int i;
  1120     if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
  1121 	return CKR_TOKEN_WRITE_PROTECTED;
  1124     LOCK_SQLITE()  
  1125     if ((*object_id != CK_INVALID_HANDLE) && 
  1126 		!sdb_objectExists(sdb, *object_id)) {
  1127 	this_object = *object_id;
  1128     } else {
  1129 	this_object = sdb_getObjectId(sdb);
  1131     if (this_object == CK_INVALID_HANDLE) {
  1132 	UNLOCK_SQLITE();
  1133 	return CKR_HOST_MEMORY;
  1135     columnStr = sqlite3_mprintf("");
  1136     valueStr = sqlite3_mprintf("");
  1137     *object_id = this_object;
  1138     for (i=0; columnStr && valueStr && i < count; i++) {
  1139    	newStr = sqlite3_mprintf("%s,a%x", columnStr, template[i].type);
  1140 	sqlite3_free(columnStr);
  1141 	columnStr = newStr;
  1142    	newStr = sqlite3_mprintf("%s,$VALUE%d", valueStr, i);
  1143 	sqlite3_free(valueStr);
  1144 	valueStr = newStr;
  1146     newStr = NULL;
  1147     if ((columnStr == NULL) || (valueStr == NULL)) {
  1148 	if (columnStr) {
  1149 	    sqlite3_free(columnStr);
  1151 	if (valueStr) {
  1152 	    sqlite3_free(valueStr);
  1154 	UNLOCK_SQLITE()  
  1155 	return CKR_HOST_MEMORY;
  1157     newStr =  sqlite3_mprintf(CREATE_CMD, sdb_p->table, columnStr, valueStr);
  1158     sqlite3_free(columnStr);
  1159     sqlite3_free(valueStr);
  1160     error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
  1161     if (error != CKR_OK) {
  1162 	goto loser;
  1164     sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL);
  1165     if (sqlerr != SQLITE_OK) goto loser;
  1166     sqlerr = sqlite3_bind_int(stmt, 1, *object_id);
  1167     if (sqlerr != SQLITE_OK) goto loser;
  1168     for (i=0; i < count; i++) {
  1169 	if (template[i].ulValueLen) {
  1170 	    sqlerr = sqlite3_bind_blob(stmt, i+2, template[i].pValue, 
  1171 			template[i].ulValueLen, SQLITE_STATIC);
  1172 	} else {
  1173 	    sqlerr = sqlite3_bind_blob(stmt, i+2, SQLITE_EXPLICIT_NULL, 
  1174 			SQLITE_EXPLICIT_NULL_LEN, SQLITE_STATIC);
  1176         if (sqlerr != SQLITE_OK) goto loser;
  1179     do {
  1180 	sqlerr = sqlite3_step(stmt);
  1181 	if (sqlerr == SQLITE_BUSY) {
  1182 	    PR_Sleep(SDB_BUSY_RETRY_TIME);
  1184     } while (!sdb_done(sqlerr,&retry));
  1186 loser:
  1187     if (newStr) {
  1188 	sqlite3_free(newStr);
  1190     if (error == CKR_OK) {
  1191 	error = sdb_mapSQLError(sdb_p->type, sqlerr);
  1194     if (stmt) {
  1195 	sqlite3_reset(stmt);
  1196 	sqlite3_finalize(stmt);
  1199     if (sqlDB) {
  1200 	sdb_closeDBLocal(sdb_p, sqlDB) ;
  1202     UNLOCK_SQLITE()  
  1204     return error;
  1207 static const char DESTROY_CMD[] = "DELETE FROM %s WHERE (id=$ID);";
  1208 CK_RV
  1209 sdb_DestroyObject(SDB *sdb, CK_OBJECT_HANDLE object_id)
  1211     SDBPrivate *sdb_p = sdb->private;
  1212     sqlite3  *sqlDB = NULL;
  1213     sqlite3_stmt *stmt = NULL;
  1214     char *newStr = NULL;
  1215     int sqlerr = SQLITE_OK;
  1216     CK_RV error = CKR_OK;
  1217     int retry = 0;
  1219     if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
  1220 	return CKR_TOKEN_WRITE_PROTECTED;
  1223     LOCK_SQLITE()  
  1224     error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
  1225     if (error != CKR_OK) {
  1226 	goto loser;
  1228     newStr =  sqlite3_mprintf(DESTROY_CMD, sdb_p->table);
  1229     if (newStr == NULL) {
  1230 	error = CKR_HOST_MEMORY;
  1231 	goto loser;
  1233     sqlerr =sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL);
  1234     sqlite3_free(newStr);
  1235     if (sqlerr != SQLITE_OK) goto loser;
  1236     sqlerr =sqlite3_bind_int(stmt, 1, object_id);
  1237     if (sqlerr != SQLITE_OK) goto loser;
  1239     do {
  1240 	sqlerr = sqlite3_step(stmt);
  1241 	if (sqlerr == SQLITE_BUSY) {
  1242 	    PR_Sleep(SDB_BUSY_RETRY_TIME);
  1244     } while (!sdb_done(sqlerr,&retry));
  1246 loser:
  1247     if (error == CKR_OK) {
  1248 	error = sdb_mapSQLError(sdb_p->type, sqlerr);
  1251     if (stmt) {
  1252 	sqlite3_reset(stmt);
  1253 	sqlite3_finalize(stmt);
  1256     if (sqlDB) {
  1257 	sdb_closeDBLocal(sdb_p, sqlDB) ;
  1260     UNLOCK_SQLITE()  
  1261     return error;
  1264 static const char BEGIN_CMD[] = "BEGIN IMMEDIATE TRANSACTION;";
  1265 /*
  1266  * start a transaction.
  1268  * We need to open a new database, then store that new database into
  1269  * the private data structure. We open the database first, then use locks
  1270  * to protect storing the data to prevent deadlocks.
  1271  */
  1272 CK_RV
  1273 sdb_Begin(SDB *sdb)
  1275     SDBPrivate *sdb_p = sdb->private;
  1276     sqlite3  *sqlDB = NULL;
  1277     sqlite3_stmt *stmt = NULL;
  1278     int sqlerr = SQLITE_OK;
  1279     CK_RV error = CKR_OK;
  1280     int retry = 0;
  1283     if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
  1284 	return CKR_TOKEN_WRITE_PROTECTED;
  1288     LOCK_SQLITE()  
  1290     /* get a new version that we will use for the entire transaction */
  1291     sqlerr = sdb_openDB(sdb_p->sqlDBName, &sqlDB, SDB_RDWR);
  1292     if (sqlerr != SQLITE_OK) {
  1293 	goto loser;
  1296     sqlerr =sqlite3_prepare_v2(sqlDB, BEGIN_CMD, -1, &stmt, NULL);
  1298     do {
  1299 	sqlerr = sqlite3_step(stmt);
  1300 	if (sqlerr == SQLITE_BUSY) {
  1301 	    PR_Sleep(SDB_BUSY_RETRY_TIME);
  1303     } while (!sdb_done(sqlerr,&retry));
  1305     if (stmt) {
  1306 	sqlite3_reset(stmt);
  1307 	sqlite3_finalize(stmt);
  1310 loser:
  1311     error = sdb_mapSQLError(sdb_p->type, sqlerr);
  1313     /* we are starting a new transaction, 
  1314      * and if we succeeded, then save this database for the rest of
  1315      * our transaction */
  1316     if (error == CKR_OK) {
  1317 	/* we hold a 'BEGIN TRANSACTION' and a sdb_p->lock. At this point
  1318 	 * sdb_p->sqlXactDB MUST be null */
  1319 	PR_EnterMonitor(sdb_p->dbMon);
  1320 	PORT_Assert(sdb_p->sqlXactDB == NULL);
  1321 	sdb_p->sqlXactDB = sqlDB;
  1322 	sdb_p->sqlXactThread = PR_GetCurrentThread();
  1323         PR_ExitMonitor(sdb_p->dbMon);
  1324     } else {
  1325 	/* we failed to start our transaction,
  1326 	 * free any databases we opened. */
  1327 	if (sqlDB) {
  1328 	    sqlite3_close(sqlDB);
  1332     UNLOCK_SQLITE()  
  1333     return error;
  1336 /*
  1337  * Complete a transaction. Basically undo everything we did in begin.
  1338  * There are 2 flavors Abort and Commit. Basically the only differerence between
  1339  * these 2 are what the database will show. (no change in to former, change in
  1340  * the latter).
  1341  */
  1342 static CK_RV 
  1343 sdb_complete(SDB *sdb, const char *cmd)
  1345     SDBPrivate *sdb_p = sdb->private;
  1346     sqlite3  *sqlDB = NULL;
  1347     sqlite3_stmt *stmt = NULL;
  1348     int sqlerr = SQLITE_OK;
  1349     CK_RV error = CKR_OK;
  1350     int retry = 0;
  1353     if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
  1354 	return CKR_TOKEN_WRITE_PROTECTED;
  1357     /* We must have a transation database, or we shouldn't have arrived here */
  1358     PR_EnterMonitor(sdb_p->dbMon);
  1359     PORT_Assert(sdb_p->sqlXactDB);
  1360     if (sdb_p->sqlXactDB == NULL) {
  1361         PR_ExitMonitor(sdb_p->dbMon);
  1362 	return CKR_GENERAL_ERROR; /* shouldn't happen */
  1364     PORT_Assert( sdb_p->sqlXactThread == PR_GetCurrentThread());
  1365     if ( sdb_p->sqlXactThread != PR_GetCurrentThread()) {
  1366         PR_ExitMonitor(sdb_p->dbMon);
  1367 	return CKR_GENERAL_ERROR; /* shouldn't happen */
  1369     sqlDB = sdb_p->sqlXactDB;
  1370     sdb_p->sqlXactDB = NULL; /* no one else can get to this DB, 
  1371 			      * safe to unlock */
  1372     sdb_p->sqlXactThread = NULL; 
  1373     PR_ExitMonitor(sdb_p->dbMon);
  1375     sqlerr =sqlite3_prepare_v2(sqlDB, cmd, -1, &stmt, NULL);
  1377     do {
  1378 	sqlerr = sqlite3_step(stmt);
  1379 	if (sqlerr == SQLITE_BUSY) {
  1380 	    PR_Sleep(SDB_BUSY_RETRY_TIME);
  1382     } while (!sdb_done(sqlerr,&retry));
  1384     /* Pending BEGIN TRANSACTIONS Can move forward at this point. */
  1386     if (stmt) {
  1387 	sqlite3_reset(stmt);
  1388 	sqlite3_finalize(stmt);
  1391     /* we we have a cached DB image, update it as well */
  1392     if (sdb_p->cacheTable) {
  1393 	PR_EnterMonitor(sdb_p->dbMon);
  1394 	sdb_updateCache(sdb_p);
  1395 	PR_ExitMonitor(sdb_p->dbMon);
  1398     error = sdb_mapSQLError(sdb_p->type, sqlerr);
  1400     /* We just finished a transaction.
  1401      * Free the database, and remove it from the list */
  1402     sqlite3_close(sqlDB);
  1404     return error;
  1407 static const char COMMIT_CMD[] = "COMMIT TRANSACTION;";
  1408 CK_RV
  1409 sdb_Commit(SDB *sdb)
  1411     CK_RV crv;
  1412     LOCK_SQLITE()  
  1413     crv = sdb_complete(sdb,COMMIT_CMD);
  1414     UNLOCK_SQLITE()  
  1415     return crv;
  1418 static const char ROLLBACK_CMD[] = "ROLLBACK TRANSACTION;";
  1419 CK_RV
  1420 sdb_Abort(SDB *sdb)
  1422     CK_RV crv;
  1423     LOCK_SQLITE()  
  1424     crv = sdb_complete(sdb,ROLLBACK_CMD);
  1425     UNLOCK_SQLITE()  
  1426     return crv;
  1429 static int tableExists(sqlite3 *sqlDB, const char *tableName);
  1431 static const char GET_PW_CMD[] = "SELECT ALL * FROM metaData WHERE id=$ID;";
  1432 CK_RV
  1433 sdb_GetMetaData(SDB *sdb, const char *id, SECItem *item1, SECItem *item2)
  1435     SDBPrivate *sdb_p = sdb->private;
  1436     sqlite3  *sqlDB = sdb_p->sqlXactDB;
  1437     sqlite3_stmt *stmt = NULL;
  1438     int sqlerr = SQLITE_OK;
  1439     CK_RV error = CKR_OK;
  1440     int found = 0;
  1441     int retry = 0;
  1443     LOCK_SQLITE()  
  1444     error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
  1445     if (error != CKR_OK) {
  1446 	goto loser;
  1449     /* handle 'test' versions of the sqlite db */
  1450     sqlerr = sqlite3_prepare_v2(sqlDB, GET_PW_CMD, -1, &stmt, NULL);
  1451     /* Sigh, if we created a new table since we opened the database,
  1452      * the database handle will not see the new table, we need to close this
  1453      * database and reopen it. This is safe because we are holding the lock
  1454      * still. */
  1455     if (sqlerr == SQLITE_SCHEMA) {
  1456 	sqlerr = sdb_reopenDBLocal(sdb_p, &sqlDB);
  1457 	if (sqlerr != SQLITE_OK) {
  1458 	    goto loser;
  1460 	sqlerr = sqlite3_prepare_v2(sqlDB, GET_PW_CMD, -1, &stmt, NULL);
  1462     if (sqlerr != SQLITE_OK) goto loser;
  1463     sqlerr = sqlite3_bind_text(stmt, 1, id, PORT_Strlen(id), SQLITE_STATIC);
  1464     do {
  1465 	sqlerr = sqlite3_step(stmt);
  1466 	if (sqlerr == SQLITE_BUSY) {
  1467 	    PR_Sleep(SDB_BUSY_RETRY_TIME);
  1469 	if (sqlerr == SQLITE_ROW) {
  1470 	    const char *blobData;
  1471 	    unsigned int len = item1->len;
  1472 	    item1->len = sqlite3_column_bytes(stmt, 1);
  1473 	    if (item1->len > len) {
  1474 		error = CKR_BUFFER_TOO_SMALL;
  1475 		continue;
  1477 	    blobData = sqlite3_column_blob(stmt, 1);
  1478 	    PORT_Memcpy(item1->data,blobData, item1->len);
  1479 	    if (item2) {
  1480 		len = item2->len;
  1481 		item2->len = sqlite3_column_bytes(stmt, 2);
  1482 		if (item2->len > len) {
  1483 		    error = CKR_BUFFER_TOO_SMALL;
  1484 		    continue;
  1486 		blobData = sqlite3_column_blob(stmt, 2);
  1487 		PORT_Memcpy(item2->data,blobData, item2->len);
  1489 	    found = 1;
  1491     } while (!sdb_done(sqlerr,&retry));
  1493 loser:
  1494     /* fix up the error if necessary */
  1495     if (error == CKR_OK) {
  1496 	error = sdb_mapSQLError(sdb_p->type, sqlerr);
  1497 	if (!found && error == CKR_OK) {
  1498 	    error = CKR_OBJECT_HANDLE_INVALID;
  1502     if (stmt) {
  1503 	sqlite3_reset(stmt);
  1504 	sqlite3_finalize(stmt);
  1507     if (sqlDB) {
  1508 	sdb_closeDBLocal(sdb_p, sqlDB) ;
  1510     UNLOCK_SQLITE()  
  1512     return error;
  1515 static const char PW_CREATE_TABLE_CMD[] =
  1516  "CREATE TABLE metaData (id PRIMARY KEY UNIQUE ON CONFLICT REPLACE, item1, item2);";
  1517 static const char PW_CREATE_CMD[] =
  1518  "INSERT INTO metaData (id,item1,item2) VALUES($ID,$ITEM1,$ITEM2);";
  1519 static const char MD_CREATE_CMD[]  =
  1520  "INSERT INTO metaData (id,item1) VALUES($ID,$ITEM1);";
  1521 CK_RV
  1522 sdb_PutMetaData(SDB *sdb, const char *id, const SECItem *item1, 
  1523 					   const SECItem *item2)
  1525     SDBPrivate *sdb_p = sdb->private;
  1526     sqlite3  *sqlDB = sdb_p->sqlXactDB;
  1527     sqlite3_stmt *stmt = NULL;
  1528     int sqlerr = SQLITE_OK;
  1529     CK_RV error = CKR_OK;
  1530     int retry = 0;
  1531     const char *cmd = PW_CREATE_CMD;
  1533     if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
  1534 	return CKR_TOKEN_WRITE_PROTECTED;
  1537     LOCK_SQLITE()  
  1538     error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
  1539     if (error != CKR_OK) {
  1540 	goto loser;
  1543     if (!tableExists(sqlDB, "metaData")) {
  1544     	sqlerr = sqlite3_exec(sqlDB, PW_CREATE_TABLE_CMD, NULL, 0, NULL);
  1545         if (sqlerr != SQLITE_OK) goto loser;
  1547     if (item2 == NULL) {
  1548 	cmd = MD_CREATE_CMD;
  1550     sqlerr = sqlite3_prepare_v2(sqlDB, cmd, -1, &stmt, NULL);
  1551     if (sqlerr != SQLITE_OK) goto loser;
  1552     sqlerr = sqlite3_bind_text(stmt, 1, id, PORT_Strlen(id), SQLITE_STATIC);
  1553     if (sqlerr != SQLITE_OK) goto loser;
  1554     sqlerr = sqlite3_bind_blob(stmt, 2, item1->data, item1->len, SQLITE_STATIC);
  1555     if (sqlerr != SQLITE_OK) goto loser;
  1556     if (item2) {
  1557     	sqlerr = sqlite3_bind_blob(stmt, 3, item2->data, 
  1558 				   item2->len, SQLITE_STATIC);
  1559         if (sqlerr != SQLITE_OK) goto loser;
  1562     do {
  1563 	sqlerr = sqlite3_step(stmt);
  1564 	if (sqlerr == SQLITE_BUSY) {
  1565 	    PR_Sleep(SDB_BUSY_RETRY_TIME);
  1567     } while (!sdb_done(sqlerr,&retry));
  1569 loser:
  1570     /* fix up the error if necessary */
  1571     if (error == CKR_OK) {
  1572 	error = sdb_mapSQLError(sdb_p->type, sqlerr);
  1575     if (stmt) {
  1576 	sqlite3_reset(stmt);
  1577 	sqlite3_finalize(stmt);
  1580     if (sqlDB) {
  1581 	sdb_closeDBLocal(sdb_p, sqlDB) ;
  1583     UNLOCK_SQLITE()  
  1585     return error;
  1588 static const char RESET_CMD[] = "DROP TABLE IF EXISTS %s;";
  1589 CK_RV
  1590 sdb_Reset(SDB *sdb)
  1592     SDBPrivate *sdb_p = sdb->private;
  1593     sqlite3  *sqlDB = NULL;
  1594     char *newStr;
  1595     int sqlerr = SQLITE_OK;
  1596     CK_RV error = CKR_OK;
  1598     /* only Key databases can be reset */
  1599     if (sdb_p->type != SDB_KEY) {
  1600 	return CKR_OBJECT_HANDLE_INVALID;
  1603     LOCK_SQLITE()  
  1604     error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
  1605     if (error != CKR_OK) {
  1606 	goto loser;
  1609     /* delete the key table */
  1610     newStr =  sqlite3_mprintf(RESET_CMD, sdb_p->table);
  1611     if (newStr == NULL) {
  1612 	error = CKR_HOST_MEMORY;
  1613 	goto loser;
  1615     sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
  1616     sqlite3_free(newStr);
  1618     if (sqlerr != SQLITE_OK) goto loser;
  1620     /* delete the password entry table */
  1621     sqlerr = sqlite3_exec(sqlDB, "DROP TABLE IF EXISTS metaData;", 
  1622                           NULL, 0, NULL);
  1624 loser:
  1625     /* fix up the error if necessary */
  1626     if (error == CKR_OK) {
  1627 	error = sdb_mapSQLError(sdb_p->type, sqlerr);
  1630     if (sqlDB) {
  1631 	sdb_closeDBLocal(sdb_p, sqlDB) ;
  1634     UNLOCK_SQLITE()  
  1635     return error;
  1639 CK_RV 
  1640 sdb_Close(SDB *sdb) 
  1642     SDBPrivate *sdb_p = sdb->private;
  1643     int sqlerr = SQLITE_OK;
  1644     sdbDataType type = sdb_p->type;
  1646     sqlerr = sqlite3_close(sdb_p->sqlReadDB);
  1647     PORT_Free(sdb_p->sqlDBName);
  1648     if (sdb_p->cacheTable) {
  1649 	sqlite3_free(sdb_p->cacheTable);
  1651     if (sdb_p->dbMon) {
  1652 	PR_DestroyMonitor(sdb_p->dbMon);
  1654     free(sdb_p);
  1655     free(sdb);
  1656     return sdb_mapSQLError(type, sqlerr);
  1660 /*
  1661  * functions to support open
  1662  */
  1664 static const char CHECK_TABLE_CMD[] = "SELECT ALL * FROM %s LIMIT 0;";
  1665 /* return 1 if sqlDB contains table 'tableName */
  1666 static int tableExists(sqlite3 *sqlDB, const char *tableName)
  1668     char * cmd = sqlite3_mprintf(CHECK_TABLE_CMD, tableName);
  1669     int sqlerr = SQLITE_OK;
  1671     if (cmd == NULL) {
  1672 	return 0;
  1675     sqlerr = sqlite3_exec(sqlDB, cmd, NULL, 0, 0);
  1676     sqlite3_free(cmd);
  1678     return (sqlerr == SQLITE_OK) ? 1 : 0;
  1681 void sdb_SetForkState(PRBool forked)
  1683     /* XXXright now this is a no-op. The global fork state in the softokn3
  1684      * shared library is already taken care of at the PKCS#11 level.
  1685      * If and when we add fork state to the sqlite shared library and extern
  1686      * interface, we will need to set it and reset it from here */
  1689 /*
  1690  * initialize a single database
  1691  */
  1692 static const char INIT_CMD[] =
  1693  "CREATE TABLE %s (id PRIMARY KEY UNIQUE ON CONFLICT ABORT%s)";
  1694 static const char ALTER_CMD[] = 
  1695  "ALTER TABLE %s ADD COLUMN a%x";
  1697 CK_RV 
  1698 sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate,
  1699 	 int *newInit, int flags, PRUint32 accessOps, SDB **pSdb)
  1701     int i;
  1702     char *initStr = NULL;
  1703     char *newStr;
  1704     int inTransaction = 0;
  1705     SDB *sdb = NULL;
  1706     SDBPrivate *sdb_p = NULL;
  1707     sqlite3 *sqlDB = NULL;
  1708     int sqlerr = SQLITE_OK;
  1709     CK_RV error = CKR_OK;
  1710     char *cacheTable = NULL;
  1711     PRIntervalTime now = 0;
  1712     char *env;
  1713     PRBool enableCache = PR_FALSE;
  1714     PRBool create;
  1716     *pSdb = NULL;
  1717     *inUpdate = 0;
  1719     /* sqlite3 doesn't have a flag to specify that we want to 
  1720      * open the database read only. If the db doesn't exist,
  1721      * sqlite3 will always create it.
  1722      */
  1723     LOCK_SQLITE();
  1724     create = (PR_Access(dbname, PR_ACCESS_EXISTS) != PR_SUCCESS);
  1725     if ((flags == SDB_RDONLY) && create) {
  1726 	error = sdb_mapSQLError(type, SQLITE_CANTOPEN);
  1727 	goto loser;
  1729     sqlerr = sdb_openDB(dbname, &sqlDB, flags);
  1730     if (sqlerr != SQLITE_OK) {
  1731 	error = sdb_mapSQLError(type, sqlerr); 
  1732 	goto loser;
  1734     /* sql created the file, but it doesn't set appropriate modes for
  1735      * a database */
  1736     if (create) {
  1737 	/* NO NSPR call for this? :( */
  1738 	chmod (dbname, 0600);
  1741     if (flags != SDB_RDONLY) {
  1742 	sqlerr = sqlite3_exec(sqlDB, BEGIN_CMD, NULL, 0, NULL);
  1743 	if (sqlerr != SQLITE_OK) {
  1744 	    error = sdb_mapSQLError(type, sqlerr);
  1745 	    goto loser;
  1747 	inTransaction = 1;
  1749     if (!tableExists(sqlDB,table)) {
  1750 	*newInit = 1;
  1751 	if (flags != SDB_CREATE) {
  1752 	    error = sdb_mapSQLError(type, SQLITE_CANTOPEN);
  1753 	    goto loser;
  1755 	initStr = sqlite3_mprintf("");
  1756 	for (i=0; initStr && i < known_attributes_size; i++) {
  1757 	    newStr = sqlite3_mprintf("%s, a%x",initStr, known_attributes[i]);
  1758 	    sqlite3_free(initStr);
  1759 	    initStr = newStr;
  1761 	if (initStr == NULL) {
  1762 	    error = CKR_HOST_MEMORY;
  1763 	    goto loser;
  1766 	newStr = sqlite3_mprintf(INIT_CMD, table, initStr);
  1767 	sqlite3_free(initStr);
  1768 	if (newStr == NULL) {
  1769             error = CKR_HOST_MEMORY;
  1770 	    goto loser;
  1772 	sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
  1773 	sqlite3_free(newStr);
  1774 	if (sqlerr != SQLITE_OK) {
  1775             error = sdb_mapSQLError(type, sqlerr); 
  1776 	    goto loser;
  1779 	newStr = sqlite3_mprintf(CREATE_ISSUER_INDEX_CMD, table);
  1780 	if (newStr == NULL) {
  1781             error = CKR_HOST_MEMORY;
  1782 	    goto loser;
  1784 	sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
  1785 	sqlite3_free(newStr);
  1786 	if (sqlerr != SQLITE_OK) {
  1787             error = sdb_mapSQLError(type, sqlerr); 
  1788 	    goto loser;
  1791 	newStr = sqlite3_mprintf(CREATE_SUBJECT_INDEX_CMD, table);
  1792 	if (newStr == NULL) {
  1793             error = CKR_HOST_MEMORY;
  1794 	    goto loser;
  1796 	sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
  1797 	sqlite3_free(newStr);
  1798 	if (sqlerr != SQLITE_OK) {
  1799             error = sdb_mapSQLError(type, sqlerr); 
  1800 	    goto loser;
  1803 	newStr = sqlite3_mprintf(CREATE_LABEL_INDEX_CMD, table);
  1804 	if (newStr == NULL) {
  1805             error = CKR_HOST_MEMORY;
  1806 	    goto loser;
  1808 	sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
  1809 	sqlite3_free(newStr);
  1810 	if (sqlerr != SQLITE_OK) {
  1811             error = sdb_mapSQLError(type, sqlerr); 
  1812 	    goto loser;
  1815 	newStr = sqlite3_mprintf(CREATE_ID_INDEX_CMD, table);
  1816 	if (newStr == NULL) {
  1817             error = CKR_HOST_MEMORY;
  1818 	    goto loser;
  1820 	sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
  1821 	sqlite3_free(newStr);
  1822 	if (sqlerr != SQLITE_OK) {
  1823             error = sdb_mapSQLError(type, sqlerr); 
  1824 	    goto loser;
  1827     /*
  1828      * detect the case where we have created the database, but have
  1829      * not yet updated it.
  1831      * We only check the Key database because only the key database has
  1832      * a metaData table. The metaData table is created when a password
  1833      * is set, or in the case of update, when a password is supplied.
  1834      * If no key database exists, then the update would have happened immediately
  1835      * on noticing that the cert database didn't exist (see newInit set above).
  1836      */
  1837     if (type == SDB_KEY && !tableExists(sqlDB, "metaData")) {
  1838 	*newInit = 1;
  1841     /* access to network filesystems are significantly slower than local ones
  1842      * for database operations. In those cases we need to create a cached copy
  1843      * of the database in a temporary location on the local disk. SQLITE
  1844      * already provides a way to create a temporary table and initialize it,
  1845      * so we use it for the cache (see sdb_buildCache for how it's done).*/
  1847      /* 
  1848       * we decide whether or not to use the cache based on the following input.
  1850       * NSS_SDB_USE_CACHE environment variable is non-existant or set to 
  1851       *   anything other than "no" or "yes" ("auto", for instance).
  1852       *   This is the normal case. NSS will measure the performance of access
  1853       *   to the temp database versus the access to the users passed in 
  1854       *   database location. If the temp database location is "significantly"
  1855       *   faster we will use the cache.
  1857       * NSS_SDB_USE_CACHE environment variable is set to "no": cache will not
  1858       *   be used.
  1860       * NSS_SDB_USE_CACHE environment variable is set to "yes": cache will
  1861       *   always be used.
  1863       * It is expected that most applications would use the "auto" selection,
  1864       * the environment variable is primarily to simplify testing, and to 
  1865       * correct potential corner cases where  */
  1867      env = PR_GetEnv("NSS_SDB_USE_CACHE");
  1869      if (env && PORT_Strcasecmp(env,"no") == 0) {
  1870 	enableCache = PR_FALSE;
  1871      } else if (env && PORT_Strcasecmp(env,"yes") == 0) {
  1872 	enableCache = PR_TRUE;
  1873      } else {
  1874 	char *tempDir = NULL;
  1875 	PRUint32 tempOps = 0;
  1876 	/*
  1877 	 *  Use PR_Access to determine how expensive it
  1878 	 * is to check for the existance of a local file compared to the same
  1879 	 * check in the temp directory. If the temp directory is faster, cache
  1880 	 * the database there. */
  1881 	tempDir = sdb_getTempDir(sqlDB);
  1882 	if (tempDir) {
  1883 	    tempOps = sdb_measureAccess(tempDir);
  1884 	    PORT_Free(tempDir);
  1886 	    /* There is a cost to continually copying the database. 
  1887 	     * Account for that cost  with the arbitrary factor of 10 */
  1888 	    enableCache = (PRBool)(tempOps > accessOps * 10);
  1892     if (enableCache) {
  1893 	/* try to set the temp store to memory.*/
  1894 	sqlite3_exec(sqlDB, "PRAGMA temp_store=MEMORY", NULL, 0, NULL);
  1895 	/* Failure to set the temp store to memory is not fatal,
  1896          * ignore the error */
  1898 	cacheTable = sqlite3_mprintf("%sCache",table);
  1899 	if (cacheTable == NULL) {
  1900 	    error = CKR_HOST_MEMORY;
  1901 	    goto loser;
  1903 	/* build the cache table */
  1904 	error = sdb_buildCache(sqlDB, type, cacheTable, table);
  1905 	if (error != CKR_OK) {
  1906 	    goto loser;
  1908 	/* initialize the last cache build time */
  1909 	now = PR_IntervalNow();
  1912     sdb = (SDB *) malloc(sizeof(SDB));
  1913     sdb_p = (SDBPrivate *) malloc(sizeof(SDBPrivate));
  1915     /* invariant fields */
  1916     sdb_p->sqlDBName = PORT_Strdup(dbname);
  1917     sdb_p->type = type;
  1918     sdb_p->table = table;
  1919     sdb_p->cacheTable = cacheTable;
  1920     sdb_p->lastUpdateTime = now;
  1921     /* set the cache delay time. This is how long we will wait before we
  1922      * decide the existing cache is stale. Currently set to 10 sec */
  1923     sdb_p->updateInterval = PR_SecondsToInterval(10); 
  1924     sdb_p->dbMon = PR_NewMonitor();
  1925     /* these fields are protected by the lock */
  1926     sdb_p->sqlXactDB = NULL;
  1927     sdb_p->sqlXactThread = NULL;
  1928     sdb->private = sdb_p;
  1929     sdb->version = 0;
  1930     sdb->sdb_flags = flags | SDB_HAS_META;
  1931     sdb->app_private = NULL;
  1932     sdb->sdb_FindObjectsInit = sdb_FindObjectsInit;
  1933     sdb->sdb_FindObjects = sdb_FindObjects;
  1934     sdb->sdb_FindObjectsFinal = sdb_FindObjectsFinal;
  1935     sdb->sdb_GetAttributeValue = sdb_GetAttributeValue;
  1936     sdb->sdb_SetAttributeValue = sdb_SetAttributeValue;
  1937     sdb->sdb_CreateObject = sdb_CreateObject;
  1938     sdb->sdb_DestroyObject = sdb_DestroyObject;
  1939     sdb->sdb_GetMetaData = sdb_GetMetaData;
  1940     sdb->sdb_PutMetaData = sdb_PutMetaData;
  1941     sdb->sdb_Begin = sdb_Begin;
  1942     sdb->sdb_Commit = sdb_Commit;
  1943     sdb->sdb_Abort = sdb_Abort;
  1944     sdb->sdb_Reset = sdb_Reset;
  1945     sdb->sdb_Close = sdb_Close;
  1946     sdb->sdb_SetForkState = sdb_SetForkState;
  1948     if (inTransaction) {
  1949 	sqlerr = sqlite3_exec(sqlDB, COMMIT_CMD, NULL, 0, NULL);
  1950 	if (sqlerr != SQLITE_OK) {
  1951 	    error = sdb_mapSQLError(sdb_p->type, sqlerr);
  1952 	    goto loser;
  1954 	inTransaction = 0;
  1957     sdb_p->sqlReadDB = sqlDB;
  1959     *pSdb = sdb;
  1960     UNLOCK_SQLITE();
  1961     return CKR_OK;
  1963 loser:
  1964     /* lots of stuff to do */
  1965     if (inTransaction) {
  1966 	sqlite3_exec(sqlDB, ROLLBACK_CMD, NULL, 0, NULL);
  1968     if (sdb) {
  1969 	free(sdb);
  1971     if (sdb_p) {
  1972 	free(sdb_p);
  1974     if (sqlDB) {
  1975 	sqlite3_close(sqlDB);
  1977     UNLOCK_SQLITE();
  1978     return error;
  1983 /* sdbopen */
  1984 CK_RV
  1985 s_open(const char *directory, const char *certPrefix, const char *keyPrefix,
  1986 	int cert_version, int key_version, int flags, 
  1987 	SDB **certdb, SDB **keydb, int *newInit)
  1989     char *cert = sdb_BuildFileName(directory, certPrefix,
  1990 				   "cert", cert_version);
  1991     char *key = sdb_BuildFileName(directory, keyPrefix,
  1992 				   "key", key_version);
  1993     CK_RV error = CKR_OK;
  1994     int inUpdate;
  1995     PRUint32 accessOps;
  1997     if (certdb) 
  1998 	*certdb = NULL;
  1999     if (keydb) 
  2000 	*keydb = NULL;
  2001     *newInit = 0;
  2003 #ifdef SQLITE_UNSAFE_THREADS
  2004     if (sqlite_lock == NULL) {
  2005 	sqlite_lock = PR_NewLock();
  2006 	if (sqlite_lock == NULL) {
  2007 	    error = CKR_HOST_MEMORY;
  2008 	    goto loser;
  2011 #endif
  2013     /* how long does it take to test for a non-existant file in our working
  2014      * directory? Allows us to test if we may be on a network file system */
  2015     accessOps = 1;
  2017         char *env;
  2018         env = PR_GetEnv("NSS_SDB_USE_CACHE");
  2019         /* If the environment variable is set to yes or no, sdb_init() will
  2020          * ignore the value of accessOps, and we can skip the measuring.*/
  2021         if (!env || ((PORT_Strcasecmp(env, "no") != 0) &&
  2022                      (PORT_Strcasecmp(env, "yes") != 0))){
  2023            accessOps = sdb_measureAccess(directory);
  2027     /*
  2028      * open the cert data base
  2029      */
  2030     if (certdb) {
  2031 	/* initialize Certificate database */
  2032 	error = sdb_init(cert, "nssPublic", SDB_CERT, &inUpdate,
  2033 			 newInit, flags, accessOps, certdb);
  2034 	if (error != CKR_OK) {
  2035 	    goto loser;
  2039     /*
  2040      * open the key data base: 
  2041      *  NOTE:if we want to implement a single database, we open
  2042      *  the same database file as the certificate here.
  2044      *  cert an key db's have different tables, so they will not
  2045      *  conflict.
  2046      */
  2047     if (keydb) {
  2048 	/* initialize the Key database */
  2049 	error = sdb_init(key, "nssPrivate", SDB_KEY, &inUpdate, 
  2050 			newInit, flags, accessOps, keydb);
  2051 	if (error != CKR_OK) {
  2052 	    goto loser;
  2057 loser:
  2058     if (cert) {
  2059 	sqlite3_free(cert);
  2061     if (key) {
  2062 	sqlite3_free(key);
  2065     if (error != CKR_OK) {
  2066 	/* currently redundant, but could be necessary if more code is added
  2067 	 * just before loser */
  2068 	if (keydb && *keydb) {
  2069 	    sdb_Close(*keydb);
  2071 	if (certdb && *certdb) {
  2072 	    sdb_Close(*certdb);
  2076     return error;
  2079 CK_RV
  2080 s_shutdown()
  2082 #ifdef SQLITE_UNSAFE_THREADS
  2083     if (sqlite_lock) {
  2084 	PR_DestroyLock(sqlite_lock);
  2085 	sqlite_lock = NULL;
  2087 #endif
  2088     return CKR_OK;

mercurial