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 */
20
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
40 #if defined(LINUX) && !defined(ANDROID)
41 #include <linux/magic.h>
42 #include <sys/vfs.h>
43 #endif
44 #include "utilpars.h"
45
46 #ifdef SQLITE_UNSAFE_THREADS
47 #include "prlock.h"
48 /*
49 * SQLite can be compiled to be thread safe or not.
50 * turn on SQLITE_UNSAFE_THREADS if the OS does not support
51 * a thread safe version of sqlite.
52 */
53 static PRLock *sqlite_lock = NULL;
54
55 #define LOCK_SQLITE() PR_Lock(sqlite_lock);
56 #define UNLOCK_SQLITE() PR_Unlock(sqlite_lock);
57 #else
58 #define LOCK_SQLITE()
59 #define UNLOCK_SQLITE()
60 #endif
61
62 typedef enum {
63 SDB_CERT = 1,
64 SDB_KEY = 2
65 } sdbDataType;
66
67 /*
68 * defines controlling how long we wait to acquire locks.
69 *
70 * SDB_SQLITE_BUSY_TIMEOUT specifies how long (in milliseconds)
71 * sqlite will wait on lock. If that timeout expires, sqlite will
72 * return SQLITE_BUSY.
73 * SDB_BUSY_RETRY_TIME specifies how many seconds the sdb_ code waits
74 * after receiving a busy before retrying.
75 * SDB_MAX_BUSY_RETRIES specifies how many times the sdb_ will retry on
76 * a busy condition.
77 *
78 * SDB_SQLITE_BUSY_TIMEOUT affects all opertions, both manual
79 * (prepare/step/reset/finalize) and automatic (sqlite3_exec()).
80 * SDB_BUSY_RETRY_TIME and SDB_MAX_BUSY_RETRIES only affect manual operations
81 *
82 * total wait time for automatic operations:
83 * 1 second (SDB_SQLITE_BUSY_TIMEOUT/1000).
84 * total wait time for manual operations:
85 * (1 second + 5 seconds) * 10 = 60 seconds.
86 * (SDB_SQLITE_BUSY_TIMEOUT/1000 + SDB_BUSY_RETRY_TIME)*SDB_MAX_BUSY_RETRIES
87 */
88 #define SDB_SQLITE_BUSY_TIMEOUT 1000 /* milliseconds */
89 #define SDB_BUSY_RETRY_TIME 5 /* seconds */
90 #define SDB_MAX_BUSY_RETRIES 10
91
92 /*
93 * known attributes
94 */
95 static const CK_ATTRIBUTE_TYPE known_attributes[] = {
96 CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_LABEL, CKA_APPLICATION,
97 CKA_VALUE, CKA_OBJECT_ID, CKA_CERTIFICATE_TYPE, CKA_ISSUER,
98 CKA_SERIAL_NUMBER, CKA_AC_ISSUER, CKA_OWNER, CKA_ATTR_TYPES, CKA_TRUSTED,
99 CKA_CERTIFICATE_CATEGORY, CKA_JAVA_MIDP_SECURITY_DOMAIN, CKA_URL,
100 CKA_HASH_OF_SUBJECT_PUBLIC_KEY, CKA_HASH_OF_ISSUER_PUBLIC_KEY,
101 CKA_CHECK_VALUE, CKA_KEY_TYPE, CKA_SUBJECT, CKA_ID, CKA_SENSITIVE,
102 CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP, CKA_SIGN, CKA_SIGN_RECOVER,
103 CKA_VERIFY, CKA_VERIFY_RECOVER, CKA_DERIVE, CKA_START_DATE, CKA_END_DATE,
104 CKA_MODULUS, CKA_MODULUS_BITS, CKA_PUBLIC_EXPONENT, CKA_PRIVATE_EXPONENT,
105 CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT,
106 CKA_PUBLIC_KEY_INFO, CKA_PRIME, CKA_SUBPRIME, CKA_BASE, CKA_PRIME_BITS,
107 CKA_SUB_PRIME_BITS, CKA_VALUE_BITS, CKA_VALUE_LEN, CKA_EXTRACTABLE,
108 CKA_LOCAL, CKA_NEVER_EXTRACTABLE, CKA_ALWAYS_SENSITIVE,
109 CKA_KEY_GEN_MECHANISM, CKA_MODIFIABLE, CKA_EC_PARAMS,
110 CKA_EC_POINT, CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
111 CKA_ALWAYS_AUTHENTICATE, CKA_WRAP_WITH_TRUSTED, CKA_HW_FEATURE_TYPE,
112 CKA_RESET_ON_INIT, CKA_HAS_RESET, CKA_PIXEL_X, CKA_PIXEL_Y,
113 CKA_RESOLUTION, CKA_CHAR_ROWS, CKA_CHAR_COLUMNS, CKA_COLOR,
114 CKA_BITS_PER_PIXEL, CKA_CHAR_SETS, CKA_ENCODING_METHODS, CKA_MIME_TYPES,
115 CKA_MECHANISM_TYPE, CKA_REQUIRED_CMS_ATTRIBUTES,
116 CKA_DEFAULT_CMS_ATTRIBUTES, CKA_SUPPORTED_CMS_ATTRIBUTES,
117 CKA_WRAP_TEMPLATE, CKA_UNWRAP_TEMPLATE, CKA_NSS_TRUST, CKA_NSS_URL,
118 CKA_NSS_EMAIL, CKA_NSS_SMIME_INFO, CKA_NSS_SMIME_TIMESTAMP,
119 CKA_NSS_PKCS8_SALT, CKA_NSS_PASSWORD_CHECK, CKA_NSS_EXPIRES,
120 CKA_NSS_KRL, CKA_NSS_PQG_COUNTER, CKA_NSS_PQG_SEED,
121 CKA_NSS_PQG_H, CKA_NSS_PQG_SEED_BITS, CKA_NSS_MODULE_SPEC,
122 CKA_NSS_OVERRIDE_EXTENSIONS, CKA_NSS_SERVER_DISTRUST_AFTER,
123 CKA_NSS_EMAIL_DISTRUST_AFTER, CKA_TRUST_DIGITAL_SIGNATURE,
124 CKA_TRUST_NON_REPUDIATION, CKA_TRUST_KEY_ENCIPHERMENT,
125 CKA_TRUST_DATA_ENCIPHERMENT, CKA_TRUST_KEY_AGREEMENT,
126 CKA_TRUST_KEY_CERT_SIGN, CKA_TRUST_CRL_SIGN, CKA_TRUST_SERVER_AUTH,
127 CKA_TRUST_CLIENT_AUTH, CKA_TRUST_CODE_SIGNING, CKA_TRUST_EMAIL_PROTECTION,
128 CKA_TRUST_IPSEC_END_SYSTEM, CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER,
129 CKA_TRUST_TIME_STAMPING, CKA_TRUST_STEP_UP_APPROVED, CKA_CERT_SHA1_HASH,
130 CKA_CERT_MD5_HASH, CKA_NSS_DB
131 };
132
133 static const int known_attributes_size = PR_ARRAY_SIZE(known_attributes);
134
135 /*
136 * Note on use of sqlReadDB: Only one thread at a time may have an actual
137 * operation going on given sqlite3 * database. An operation is defined as
138 * the time from a sqlite3_prepare() until the sqlite3_finalize().
139 * Multiple sqlite3 * databases can be open and have simultaneous operations
140 * going. We use the sqlXactDB for all write operations. This database
141 * is only opened when we first create a transaction and closed when the
142 * transaction is complete. sqlReadDB is open when we first opened the database
143 * and is used for all read operation. It's use is protected by a monitor. This
144 * is because an operation can span the use of FindObjectsInit() through the
145 * call to FindObjectsFinal(). In the intermediate time it is possible to call
146 * other operations like NSC_GetAttributeValue */
147
148 struct SDBPrivateStr {
149 char *sqlDBName; /* invariant, path to this database */
150 sqlite3 *sqlXactDB; /* access protected by dbMon, use protected
151 * by the transaction. Current transaction db*/
152 PRThread *sqlXactThread; /* protected by dbMon,
153 * current transaction thread */
154 sqlite3 *sqlReadDB; /* use protected by dbMon, value invariant */
155 PRIntervalTime lastUpdateTime; /* last time the cache was updated */
156 PRIntervalTime updateInterval; /* how long the cache can go before it
157 * must be updated again */
158 sdbDataType type; /* invariant, database type */
159 char *table; /* invariant, SQL table which contains the db */
160 char *cacheTable; /* invariant, SQL table cache of db */
161 PRMonitor *dbMon; /* invariant, monitor to protect
162 * sqlXact* fields, and use of the sqlReadDB */
163 CK_ATTRIBUTE_TYPE *schemaAttrs; /* Attribute columns that exist in the table. */
164 unsigned int numSchemaAttrs;
165 };
166
167 typedef struct SDBPrivateStr SDBPrivate;
168
169 /* Magic for an explicit NULL. NOTE: ideally this should be
170 * out of band data. Since it's not completely out of band, pick
171 * a value that has no meaning to any existing PKCS #11 attributes.
172 * This value is 1) not a valid string (imbedded '\0'). 2) not a U_LONG
173 * or a normal key (too short). 3) not a bool (too long). 4) not an RSA
174 * public exponent (too many bits).
175 */
176 const unsigned char SQLITE_EXPLICIT_NULL[] = { 0xa5, 0x0, 0x5a };
177 #define SQLITE_EXPLICIT_NULL_LEN 3
178
179 /*
180 * determine when we've completed our tasks
181 */
182 static int
sdb_done(int err,int * count)183 sdb_done(int err, int *count)
184 {
185 /* allow as many rows as the database wants to give */
186 if (err == SQLITE_ROW) {
187 *count = 0;
188 return 0;
189 }
190 if (err != SQLITE_BUSY) {
191 return 1;
192 }
193 /* err == SQLITE_BUSY, Dont' retry forever in this case */
194 if (++(*count) >= SDB_MAX_BUSY_RETRIES) {
195 return 1;
196 }
197 return 0;
198 }
199
200 #if defined(_WIN32)
201 /*
202 * NSPR functions and narrow CRT functions do not handle UTF-8 file paths that
203 * sqlite3 expects.
204 */
205
206 static int
sdb_chmod(const char * filename,int pmode)207 sdb_chmod(const char *filename, int pmode)
208 {
209 int result;
210
211 if (!filename) {
212 return -1;
213 }
214
215 wchar_t *filenameWide = _NSSUTIL_UTF8ToWide(filename);
216 if (!filenameWide) {
217 return -1;
218 }
219 result = _wchmod(filenameWide, pmode);
220 PORT_Free(filenameWide);
221
222 return result;
223 }
224 #else
225 #define sdb_chmod(filename, pmode) chmod((filename), (pmode))
226 #endif
227
228 /*
229 * find out where sqlite stores the temp tables. We do this by replicating
230 * the logic from sqlite.
231 */
232 #if defined(_WIN32)
233 static char *
sdb_getFallbackTempDir(void)234 sdb_getFallbackTempDir(void)
235 {
236 /* sqlite uses sqlite3_temp_directory if it is not NULL. We don't have
237 * access to sqlite3_temp_directory because it is not exported from
238 * sqlite3.dll. Assume sqlite3_win32_set_directory isn't called and
239 * sqlite3_temp_directory is NULL.
240 */
241 char path[MAX_PATH];
242 DWORD rv;
243 size_t len;
244
245 rv = GetTempPathA(MAX_PATH, path);
246 if (rv > MAX_PATH || rv == 0)
247 return NULL;
248 len = strlen(path);
249 if (len == 0)
250 return NULL;
251 /* The returned string ends with a backslash, for example, "C:\TEMP\". */
252 if (path[len - 1] == '\\')
253 path[len - 1] = '\0';
254 return PORT_Strdup(path);
255 }
256 #elif defined(XP_UNIX)
257 static char *
sdb_getFallbackTempDir(void)258 sdb_getFallbackTempDir(void)
259 {
260 const char *azDirs[] = {
261 NULL,
262 NULL,
263 "/var/tmp",
264 "/usr/tmp",
265 "/tmp",
266 NULL /* List terminator */
267 };
268 unsigned int i;
269 struct stat buf;
270 const char *zDir = NULL;
271
272 azDirs[0] = sqlite3_temp_directory;
273 azDirs[1] = PR_GetEnvSecure("TMPDIR");
274
275 for (i = 0; i < PR_ARRAY_SIZE(azDirs); i++) {
276 zDir = azDirs[i];
277 if (zDir == NULL)
278 continue;
279 if (stat(zDir, &buf))
280 continue;
281 if (!S_ISDIR(buf.st_mode))
282 continue;
283 if (access(zDir, 07))
284 continue;
285 break;
286 }
287
288 if (zDir == NULL)
289 return NULL;
290 return PORT_Strdup(zDir);
291 }
292 #else
293 #error "sdb_getFallbackTempDir not implemented"
294 #endif
295
296 #ifndef SQLITE_FCNTL_TEMPFILENAME
297 /* SQLITE_FCNTL_TEMPFILENAME was added in SQLite 3.7.15 */
298 #define SQLITE_FCNTL_TEMPFILENAME 16
299 #endif
300
301 static char *
sdb_getTempDir(sqlite3 * sqlDB)302 sdb_getTempDir(sqlite3 *sqlDB)
303 {
304 int sqlrv;
305 char *result = NULL;
306 char *tempName = NULL;
307 char *foundSeparator = NULL;
308
309 /* Obtain temporary filename in sqlite's directory for temporary tables */
310 sqlrv = sqlite3_file_control(sqlDB, 0, SQLITE_FCNTL_TEMPFILENAME,
311 (void *)&tempName);
312 if (sqlrv == SQLITE_NOTFOUND) {
313 /* SQLITE_FCNTL_TEMPFILENAME not implemented because we are using
314 * an older SQLite. */
315 return sdb_getFallbackTempDir();
316 }
317 if (sqlrv != SQLITE_OK) {
318 return NULL;
319 }
320
321 /* We'll extract the temporary directory from tempName */
322 foundSeparator = PORT_Strrchr(tempName, PR_GetDirectorySeparator());
323 if (foundSeparator) {
324 /* We shorten the temp filename string to contain only
325 * the directory name (including the trailing separator).
326 * We know the byte after the foundSeparator position is
327 * safe to use, in the shortest scenario it contains the
328 * end-of-string byte.
329 * By keeping the separator at the found position, it will
330 * even work if tempDir consists of the separator, only.
331 * (In this case the toplevel directory will be used for
332 * access speed testing). */
333 ++foundSeparator;
334 *foundSeparator = 0;
335
336 /* Now we copy the directory name for our caller */
337 result = PORT_Strdup(tempName);
338 }
339
340 sqlite3_free(tempName);
341 return result;
342 }
343
344 /*
345 * Map SQL_LITE errors to PKCS #11 errors as best we can.
346 */
347 static CK_RV
sdb_mapSQLError(sdbDataType type,int sqlerr)348 sdb_mapSQLError(sdbDataType type, int sqlerr)
349 {
350 switch (sqlerr) {
351 /* good matches */
352 case SQLITE_OK:
353 case SQLITE_DONE:
354 return CKR_OK;
355 case SQLITE_NOMEM:
356 return CKR_HOST_MEMORY;
357 case SQLITE_READONLY:
358 return CKR_TOKEN_WRITE_PROTECTED;
359 /* close matches */
360 case SQLITE_AUTH:
361 case SQLITE_PERM:
362 /*return CKR_USER_NOT_LOGGED_IN; */
363 case SQLITE_CANTOPEN:
364 case SQLITE_NOTFOUND:
365 /* NSS distiguishes between failure to open the cert and the key db */
366 return type == SDB_CERT ? CKR_NSS_CERTDB_FAILED : CKR_NSS_KEYDB_FAILED;
367 case SQLITE_IOERR:
368 return CKR_DEVICE_ERROR;
369 default:
370 break;
371 }
372 return CKR_GENERAL_ERROR;
373 }
374
375 /*
376 * build up database name from a directory, prefix, name, version and flags.
377 */
378 static char *
sdb_BuildFileName(const char * directory,const char * prefix,const char * type,int version)379 sdb_BuildFileName(const char *directory,
380 const char *prefix, const char *type,
381 int version)
382 {
383 char *dbname = NULL;
384 /* build the full dbname */
385 dbname = sqlite3_mprintf("%s%c%s%s%d.db", directory,
386 (int)(unsigned char)PR_GetDirectorySeparator(),
387 prefix, type, version);
388 return dbname;
389 }
390
391 /*
392 * find out how expensive the access system call is for non-existant files
393 * in the given directory. Return the number of operations done in 33 ms.
394 */
395 static PRUint32
sdb_measureAccess(const char * directory)396 sdb_measureAccess(const char *directory)
397 {
398 PRUint32 i;
399 PRIntervalTime time;
400 PRIntervalTime delta;
401 PRIntervalTime duration = PR_MillisecondsToInterval(33);
402 const char *doesntExistName = "_dOeSnotExist_.db";
403 char *temp, *tempStartOfFilename;
404 size_t maxTempLen, maxFileNameLen, directoryLength, tmpdirLength = 0;
405 #ifdef SDB_MEASURE_USE_TEMP_DIR
406 /*
407 * on some OS's and Filesystems, creating a bunch of files and deleting
408 * them messes up the systems's caching, but if we create the files in
409 * a temp directory which we later delete, then the cache gets cleared
410 * up. This code uses several OS dependent calls, and it's not clear
411 * that temp directory use won't mess up other filesystems and OS caching,
412 * so if you need this for your OS, you can turn on the
413 * 'SDB_MEASURE_USE_TEMP_DIR' define in coreconf
414 */
415 const char template[] = "dbTemp.XXXXXX";
416 tmpdirLength = sizeof(template);
417 #endif
418 /* no directory, just return one */
419 if (directory == NULL) {
420 return 1;
421 }
422
423 /* our calculation assumes time is a 4 bytes == 32 bit integer */
424 PORT_Assert(sizeof(time) == 4);
425
426 directoryLength = strlen(directory);
427
428 maxTempLen = directoryLength + 1 /* dirname + / */
429 + tmpdirLength /* tmpdirname includes / */
430 + strlen(doesntExistName) /* filename base */
431 + 11 /* max chars for 32 bit int plus potential sign */
432 + 1; /* zero terminator */
433
434 temp = PORT_ZAlloc(maxTempLen);
435 if (!temp) {
436 return 1;
437 }
438
439 /* We'll copy directory into temp just once, then ensure it ends
440 * with the directory separator. */
441
442 strcpy(temp, directory);
443 if (directory[directoryLength - 1] != PR_GetDirectorySeparator()) {
444 temp[directoryLength++] = PR_GetDirectorySeparator();
445 }
446
447 #ifdef SDB_MEASURE_USE_TEMP_DIR
448 /* add the template for a temporary subdir, and create it */
449 strcat(temp, template);
450 if (!mkdtemp(temp)) {
451 PORT_Free(temp);
452 return 1;
453 }
454 /* and terminate that tmp subdir with a / */
455 strcat(temp, "/");
456 #endif
457
458 /* Remember the position after the last separator, and calculate the
459 * number of remaining bytes. */
460 tempStartOfFilename = temp + directoryLength + tmpdirLength;
461 maxFileNameLen = maxTempLen - directoryLength;
462
463 /* measure number of Access operations that can be done in 33 milliseconds
464 * (1/30'th of a second), or 10000 operations, which ever comes first.
465 */
466 time = PR_IntervalNow();
467 for (i = 0; i < 10000u; i++) {
468 PRIntervalTime next;
469
470 /* We'll use the variable part first in the filename string, just in
471 * case it's longer than assumed, so if anything gets cut off, it
472 * will be cut off from the constant part.
473 * This code assumes the directory name at the beginning of
474 * temp remains unchanged during our loop. */
475 PR_snprintf(tempStartOfFilename, maxFileNameLen,
476 ".%lu%s", (PRUint32)(time + i), doesntExistName);
477 PR_Access(temp, PR_ACCESS_EXISTS);
478 next = PR_IntervalNow();
479 delta = next - time;
480 if (delta >= duration)
481 break;
482 }
483
484 #ifdef SDB_MEASURE_USE_TEMP_DIR
485 /* turn temp back into our tmpdir path by removing doesntExistName, and
486 * remove the tmp dir */
487 *tempStartOfFilename = '\0';
488 (void)rmdir(temp);
489 #endif
490 PORT_Free(temp);
491
492 /* always return 1 or greater */
493 return i ? i : 1u;
494 }
495
496 /*
497 * some file sytems are very slow to run sqlite3 on, particularly if the
498 * access count is pretty high. On these filesystems is faster to create
499 * a temporary database on the local filesystem and access that. This
500 * code uses a temporary table to create that cache. Temp tables are
501 * automatically cleared when the database handle it was created on
502 * Is freed.
503 */
504 static const char DROP_CACHE_CMD[] = "DROP TABLE %s";
505 static const char CREATE_CACHE_CMD[] =
506 "CREATE TEMPORARY TABLE %s AS SELECT * FROM %s";
507 static const char CREATE_ISSUER_INDEX_CMD[] =
508 "CREATE INDEX issuer ON %s (a81)";
509 static const char CREATE_SUBJECT_INDEX_CMD[] =
510 "CREATE INDEX subject ON %s (a101)";
511 static const char CREATE_LABEL_INDEX_CMD[] = "CREATE INDEX label ON %s (a3)";
512 static const char CREATE_ID_INDEX_CMD[] = "CREATE INDEX ckaid ON %s (a102)";
513
514 static CK_RV
sdb_buildCache(sqlite3 * sqlDB,sdbDataType type,const char * cacheTable,const char * table)515 sdb_buildCache(sqlite3 *sqlDB, sdbDataType type,
516 const char *cacheTable, const char *table)
517 {
518 char *newStr;
519 int sqlerr = SQLITE_OK;
520
521 newStr = sqlite3_mprintf(CREATE_CACHE_CMD, cacheTable, table);
522 if (newStr == NULL) {
523 return CKR_HOST_MEMORY;
524 }
525 sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
526 sqlite3_free(newStr);
527 if (sqlerr != SQLITE_OK) {
528 return sdb_mapSQLError(type, sqlerr);
529 }
530 /* failure to create the indexes is not an issue */
531 newStr = sqlite3_mprintf(CREATE_ISSUER_INDEX_CMD, cacheTable);
532 if (newStr == NULL) {
533 return CKR_OK;
534 }
535 sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
536 sqlite3_free(newStr);
537 newStr = sqlite3_mprintf(CREATE_SUBJECT_INDEX_CMD, cacheTable);
538 if (newStr == NULL) {
539 return CKR_OK;
540 }
541 sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
542 sqlite3_free(newStr);
543 newStr = sqlite3_mprintf(CREATE_LABEL_INDEX_CMD, cacheTable);
544 if (newStr == NULL) {
545 return CKR_OK;
546 }
547 sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
548 sqlite3_free(newStr);
549 newStr = sqlite3_mprintf(CREATE_ID_INDEX_CMD, cacheTable);
550 if (newStr == NULL) {
551 return CKR_OK;
552 }
553 sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
554 sqlite3_free(newStr);
555 return CKR_OK;
556 }
557
558 /*
559 * update the cache and the data records describing it.
560 * The cache is updated by dropping the temp database and recreating it.
561 */
562 static CK_RV
sdb_updateCache(SDBPrivate * sdb_p)563 sdb_updateCache(SDBPrivate *sdb_p)
564 {
565 int sqlerr = SQLITE_OK;
566 CK_RV error = CKR_OK;
567 char *newStr;
568
569 /* drop the old table */
570 newStr = sqlite3_mprintf(DROP_CACHE_CMD, sdb_p->cacheTable);
571 if (newStr == NULL) {
572 return CKR_HOST_MEMORY;
573 }
574 sqlerr = sqlite3_exec(sdb_p->sqlReadDB, newStr, NULL, 0, NULL);
575 sqlite3_free(newStr);
576 if ((sqlerr != SQLITE_OK) && (sqlerr != SQLITE_ERROR)) {
577 /* something went wrong with the drop, don't try to refresh...
578 * NOTE: SQLITE_ERROR is returned if the table doesn't exist. In
579 * that case, we just continue on and try to reload it */
580 return sdb_mapSQLError(sdb_p->type, sqlerr);
581 }
582
583 /* set up the new table */
584 error = sdb_buildCache(sdb_p->sqlReadDB, sdb_p->type,
585 sdb_p->cacheTable, sdb_p->table);
586 if (error == CKR_OK) {
587 /* we have a new cache! */
588 sdb_p->lastUpdateTime = PR_IntervalNow();
589 }
590 return error;
591 }
592
593 /*
594 * The sharing of sqlite3 handles across threads is tricky. Older versions
595 * couldn't at all, but newer ones can under strict conditions. Basically
596 * no 2 threads can use the same handle while another thread has an open
597 * stmt running. Once the sqlite3_stmt is finalized, another thread can then
598 * use the database handle.
599 *
600 * We use monitors to protect against trying to use a database before
601 * it's sqlite3_stmt is finalized. This is preferable to the opening and
602 * closing the database each operation because there is significant overhead
603 * in the open and close. Also continually opening and closing the database
604 * defeats the cache code as the cache table is lost on close (thus
605 * requiring us to have to reinitialize the cache every operation).
606 *
607 * An execption to the shared handle is transations. All writes happen
608 * through a transaction. When we are in a transaction, we must use the
609 * same database pointer for that entire transation. In this case we save
610 * the transaction database and use it for all accesses on the transaction
611 * thread. Other threads use the common database.
612 *
613 * There can only be once active transaction on the database at a time.
614 *
615 * sdb_openDBLocal() provides us with a valid database handle for whatever
616 * state we are in (reading or in a transaction), and acquires any locks
617 * appropriate to that state. It also decides when it's time to refresh
618 * the cache before we start an operation. Any database handle returned
619 * just eventually be closed with sdb_closeDBLocal().
620 *
621 * The table returned either points to the database's physical table, or
622 * to the cached shadow. Tranactions always return the physical table
623 * and read operations return either the physical table or the cache
624 * depending on whether or not the cache exists.
625 */
626 static CK_RV
sdb_openDBLocal(SDBPrivate * sdb_p,sqlite3 ** sqlDB,const char ** table)627 sdb_openDBLocal(SDBPrivate *sdb_p, sqlite3 **sqlDB, const char **table)
628 {
629 *sqlDB = NULL;
630
631 PR_EnterMonitor(sdb_p->dbMon);
632
633 if (table) {
634 *table = sdb_p->table;
635 }
636
637 /* We're in a transaction, use the transaction DB */
638 if ((sdb_p->sqlXactDB) && (sdb_p->sqlXactThread == PR_GetCurrentThread())) {
639 *sqlDB = sdb_p->sqlXactDB;
640 /* only one thread can get here, safe to unlock */
641 PR_ExitMonitor(sdb_p->dbMon);
642 return CKR_OK;
643 }
644
645 /*
646 * if we are just reading from the table, we may have the table
647 * cached in a temporary table (especially if it's on a shared FS).
648 * In that case we want to see updates to the table, the the granularity
649 * is on order of human scale, not computer scale.
650 */
651 if (table && sdb_p->cacheTable) {
652 PRIntervalTime now = PR_IntervalNow();
653 if ((now - sdb_p->lastUpdateTime) > sdb_p->updateInterval) {
654 sdb_updateCache(sdb_p);
655 }
656 *table = sdb_p->cacheTable;
657 }
658
659 *sqlDB = sdb_p->sqlReadDB;
660
661 /* leave holding the lock. only one thread can actually use a given
662 * database connection at once */
663
664 return CKR_OK;
665 }
666
667 /* closing the local database currenly means unlocking the monitor */
668 static CK_RV
sdb_closeDBLocal(SDBPrivate * sdb_p,sqlite3 * sqlDB)669 sdb_closeDBLocal(SDBPrivate *sdb_p, sqlite3 *sqlDB)
670 {
671 if (sdb_p->sqlXactDB != sqlDB) {
672 /* if we weren't in a transaction, we got a lock */
673 PR_ExitMonitor(sdb_p->dbMon);
674 }
675 return CKR_OK;
676 }
677
678 /*
679 * wrapper to sqlite3_open which also sets the busy_timeout
680 */
681 static int
sdb_openDB(const char * name,sqlite3 ** sqlDB,int flags)682 sdb_openDB(const char *name, sqlite3 **sqlDB, int flags)
683 {
684 int sqlerr;
685 int openFlags;
686
687 *sqlDB = NULL;
688
689 if (flags & SDB_RDONLY) {
690 openFlags = SQLITE_OPEN_READONLY;
691 } else {
692 openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
693 }
694
695 /* Requires SQLite 3.5.0 or newer. */
696 sqlerr = sqlite3_open_v2(name, sqlDB, openFlags, NULL);
697 if (sqlerr != SQLITE_OK) {
698 return sqlerr;
699 }
700
701 sqlerr = sqlite3_busy_timeout(*sqlDB, SDB_SQLITE_BUSY_TIMEOUT);
702 if (sqlerr != SQLITE_OK) {
703 sqlite3_close(*sqlDB);
704 *sqlDB = NULL;
705 return sqlerr;
706 }
707 return SQLITE_OK;
708 }
709
710 /* Sigh, if we created a new table since we opened the database,
711 * the database handle will not see the new table, we need to close this
712 * database and reopen it. Caller must be in a transaction or holding
713 * the dbMon. sqlDB is changed on success. */
714 static int
sdb_reopenDBLocal(SDBPrivate * sdb_p,sqlite3 ** sqlDB)715 sdb_reopenDBLocal(SDBPrivate *sdb_p, sqlite3 **sqlDB)
716 {
717 sqlite3 *newDB;
718 int sqlerr;
719
720 /* open a new database */
721 sqlerr = sdb_openDB(sdb_p->sqlDBName, &newDB, SDB_RDONLY);
722 if (sqlerr != SQLITE_OK) {
723 return sqlerr;
724 }
725
726 /* if we are in a transaction, we may not be holding the monitor.
727 * grab it before we update the transaction database. This is
728 * safe since are using monitors. */
729 PR_EnterMonitor(sdb_p->dbMon);
730 /* update our view of the database */
731 if (sdb_p->sqlReadDB == *sqlDB) {
732 sdb_p->sqlReadDB = newDB;
733 } else if (sdb_p->sqlXactDB == *sqlDB) {
734 sdb_p->sqlXactDB = newDB;
735 }
736 PR_ExitMonitor(sdb_p->dbMon);
737
738 /* close the old one */
739 sqlite3_close(*sqlDB);
740
741 *sqlDB = newDB;
742 return SQLITE_OK;
743 }
744
745 struct SDBFindStr {
746 sqlite3 *sqlDB;
747 sqlite3_stmt *findstmt;
748 };
749
750 static const char FIND_OBJECTS_CMD[] = "SELECT ALL id FROM %s WHERE %s;";
751 static const char FIND_OBJECTS_ALL_CMD[] = "SELECT ALL id FROM %s;";
752 CK_RV
sdb_FindObjectsInit(SDB * sdb,const CK_ATTRIBUTE * template,CK_ULONG count,SDBFind ** find)753 sdb_FindObjectsInit(SDB *sdb, const CK_ATTRIBUTE *template, CK_ULONG count,
754 SDBFind **find)
755 {
756 SDBPrivate *sdb_p = sdb->private;
757 sqlite3 *sqlDB = NULL;
758 const char *table;
759 char *newStr, *findStr = NULL;
760 sqlite3_stmt *findstmt = NULL;
761 char *join = "";
762 int sqlerr = SQLITE_OK;
763 CK_RV error = CKR_OK;
764 unsigned int i;
765
766 LOCK_SQLITE()
767 *find = NULL;
768 error = sdb_openDBLocal(sdb_p, &sqlDB, &table);
769 if (error != CKR_OK) {
770 goto loser;
771 }
772
773 findStr = sqlite3_mprintf("");
774 for (i = 0; findStr && i < count; i++) {
775 newStr = sqlite3_mprintf("%s%sa%x=$DATA%d", findStr, join,
776 template[i].type, i);
777 join = " AND ";
778 sqlite3_free(findStr);
779 findStr = newStr;
780 }
781
782 if (findStr == NULL) {
783 error = CKR_HOST_MEMORY;
784 goto loser;
785 }
786
787 if (count == 0) {
788 newStr = sqlite3_mprintf(FIND_OBJECTS_ALL_CMD, table);
789 } else {
790 newStr = sqlite3_mprintf(FIND_OBJECTS_CMD, table, findStr);
791 }
792 sqlite3_free(findStr);
793 if (newStr == NULL) {
794 error = CKR_HOST_MEMORY;
795 goto loser;
796 }
797 sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &findstmt, NULL);
798 sqlite3_free(newStr);
799 for (i = 0; sqlerr == SQLITE_OK && i < count; i++) {
800 const void *blobData = template[i].pValue;
801 unsigned int blobSize = template[i].ulValueLen;
802 if (blobSize == 0) {
803 blobSize = SQLITE_EXPLICIT_NULL_LEN;
804 blobData = SQLITE_EXPLICIT_NULL;
805 }
806 sqlerr = sqlite3_bind_blob(findstmt, i + 1, blobData, blobSize,
807 SQLITE_TRANSIENT);
808 }
809 if (sqlerr == SQLITE_OK) {
810 *find = PORT_New(SDBFind);
811 if (*find == NULL) {
812 error = CKR_HOST_MEMORY;
813 goto loser;
814 }
815 (*find)->findstmt = findstmt;
816 (*find)->sqlDB = sqlDB;
817 UNLOCK_SQLITE()
818 return CKR_OK;
819 }
820 error = sdb_mapSQLError(sdb_p->type, sqlerr);
821
822 loser:
823 if (findstmt) {
824 sqlite3_reset(findstmt);
825 sqlite3_finalize(findstmt);
826 }
827 if (sqlDB) {
828 sdb_closeDBLocal(sdb_p, sqlDB);
829 }
830 UNLOCK_SQLITE()
831 return error;
832 }
833
834 CK_RV
sdb_FindObjects(SDB * sdb,SDBFind * sdbFind,CK_OBJECT_HANDLE * object,CK_ULONG arraySize,CK_ULONG * count)835 sdb_FindObjects(SDB *sdb, SDBFind *sdbFind, CK_OBJECT_HANDLE *object,
836 CK_ULONG arraySize, CK_ULONG *count)
837 {
838 SDBPrivate *sdb_p = sdb->private;
839 sqlite3_stmt *stmt = sdbFind->findstmt;
840 int sqlerr = SQLITE_OK;
841 int retry = 0;
842
843 *count = 0;
844
845 if (arraySize == 0) {
846 return CKR_OK;
847 }
848 LOCK_SQLITE()
849
850 do {
851 sqlerr = sqlite3_step(stmt);
852 if (sqlerr == SQLITE_BUSY) {
853 PR_Sleep(SDB_BUSY_RETRY_TIME);
854 }
855 if (sqlerr == SQLITE_ROW) {
856 /* only care about the id */
857 *object++ = sqlite3_column_int(stmt, 0);
858 arraySize--;
859 (*count)++;
860 }
861 } while (!sdb_done(sqlerr, &retry) && (arraySize > 0));
862
863 /* we only have some of the objects, there is probably more,
864 * set the sqlerr to an OK value so we return CKR_OK */
865 if (sqlerr == SQLITE_ROW && arraySize == 0) {
866 sqlerr = SQLITE_DONE;
867 }
868 UNLOCK_SQLITE()
869
870 return sdb_mapSQLError(sdb_p->type, sqlerr);
871 }
872
873 CK_RV
sdb_FindObjectsFinal(SDB * sdb,SDBFind * sdbFind)874 sdb_FindObjectsFinal(SDB *sdb, SDBFind *sdbFind)
875 {
876 SDBPrivate *sdb_p = sdb->private;
877 sqlite3_stmt *stmt = sdbFind->findstmt;
878 sqlite3 *sqlDB = sdbFind->sqlDB;
879 int sqlerr = SQLITE_OK;
880
881 LOCK_SQLITE()
882 if (stmt) {
883 sqlite3_reset(stmt);
884 sqlerr = sqlite3_finalize(stmt);
885 }
886 if (sqlDB) {
887 sdb_closeDBLocal(sdb_p, sqlDB);
888 }
889 PORT_Free(sdbFind);
890
891 UNLOCK_SQLITE()
892 return sdb_mapSQLError(sdb_p->type, sqlerr);
893 }
894
895 static CK_RV
sdb_GetValidAttributeValueNoLock(SDB * sdb,CK_OBJECT_HANDLE object_id,CK_ATTRIBUTE * template,CK_ULONG count)896 sdb_GetValidAttributeValueNoLock(SDB *sdb, CK_OBJECT_HANDLE object_id,
897 CK_ATTRIBUTE *template, CK_ULONG count)
898 {
899 SDBPrivate *sdb_p = sdb->private;
900 sqlite3 *sqlDB = NULL;
901 sqlite3_stmt *stmt = NULL;
902 const char *table = NULL;
903 int sqlerr = SQLITE_OK;
904 CK_RV error = CKR_OK;
905 int found = 0;
906 int retry = 0;
907 unsigned int i;
908
909 if (count == 0) {
910 error = CKR_OBJECT_HANDLE_INVALID;
911 goto loser;
912 }
913
914 /* open a new db if necessary */
915 error = sdb_openDBLocal(sdb_p, &sqlDB, &table);
916 if (error != CKR_OK) {
917 goto loser;
918 }
919
920 char *columns = NULL;
921 for (i = 0; i < count; i++) {
922 char *newColumns;
923 if (columns) {
924 newColumns = sqlite3_mprintf("%s, a%x", columns, template[i].type);
925 sqlite3_free(columns);
926 columns = NULL;
927 } else {
928 newColumns = sqlite3_mprintf("a%x", template[i].type);
929 }
930 if (!newColumns) {
931 error = CKR_HOST_MEMORY;
932 goto loser;
933 }
934 columns = newColumns;
935 }
936
937 PORT_Assert(columns);
938
939 char *statement = sqlite3_mprintf("SELECT DISTINCT %s FROM %s where id=$ID LIMIT 1;",
940 columns, table);
941 sqlite3_free(columns);
942 columns = NULL;
943 if (!statement) {
944 error = CKR_HOST_MEMORY;
945 goto loser;
946 }
947
948 sqlerr = sqlite3_prepare_v2(sqlDB, statement, -1, &stmt, NULL);
949 sqlite3_free(statement);
950 statement = NULL;
951 if (sqlerr != SQLITE_OK) {
952 goto loser;
953 }
954
955 // NB: indices in sqlite3_bind_int are 1-indexed
956 sqlerr = sqlite3_bind_int(stmt, 1, object_id);
957 if (sqlerr != SQLITE_OK) {
958 goto loser;
959 }
960
961 do {
962 sqlerr = sqlite3_step(stmt);
963 if (sqlerr == SQLITE_BUSY) {
964 PR_Sleep(SDB_BUSY_RETRY_TIME);
965 }
966 if (sqlerr == SQLITE_ROW) {
967 PORT_Assert(!found);
968 for (i = 0; i < count; i++) {
969 unsigned int blobSize;
970 const char *blobData;
971
972 // NB: indices in sqlite_column_{bytes,blob} are 0-indexed
973 blobSize = sqlite3_column_bytes(stmt, i);
974 blobData = sqlite3_column_blob(stmt, i);
975 if (blobData == NULL) {
976 /* PKCS 11 requires that get attributes process all the
977 * attributes in the template, marking the attributes with
978 * issues with -1. Mark the error but continue */
979 template[i].ulValueLen = -1;
980 error = CKR_ATTRIBUTE_TYPE_INVALID;
981 continue;
982 }
983 /* If the blob equals our explicit NULL value, then the
984 * attribute is a NULL. */
985 if ((blobSize == SQLITE_EXPLICIT_NULL_LEN) &&
986 (PORT_Memcmp(blobData, SQLITE_EXPLICIT_NULL,
987 SQLITE_EXPLICIT_NULL_LEN) == 0)) {
988 blobSize = 0;
989 }
990 if (template[i].pValue) {
991 if (template[i].ulValueLen < blobSize) {
992 /* like CKR_ATTRIBUTE_TYPE_INVALID, continue processing */
993 template[i].ulValueLen = -1;
994 error = CKR_BUFFER_TOO_SMALL;
995 continue;
996 }
997 PORT_Memcpy(template[i].pValue, blobData, blobSize);
998 }
999 template[i].ulValueLen = blobSize;
1000 }
1001 found = 1;
1002 }
1003 } while (!sdb_done(sqlerr, &retry));
1004 sqlite3_reset(stmt);
1005 sqlite3_finalize(stmt);
1006 stmt = NULL;
1007
1008 loser:
1009 /* fix up the error if necessary */
1010 if (error == CKR_OK) {
1011 error = sdb_mapSQLError(sdb_p->type, sqlerr);
1012 if (!found && error == CKR_OK) {
1013 error = CKR_OBJECT_HANDLE_INVALID;
1014 }
1015 }
1016
1017 if (stmt) {
1018 sqlite3_reset(stmt);
1019 sqlite3_finalize(stmt);
1020 }
1021
1022 /* if we had to open a new database, free it now */
1023 if (sqlDB) {
1024 sdb_closeDBLocal(sdb_p, sqlDB);
1025 }
1026 return error;
1027 }
1028
1029 /* NOTE: requires sdb_p->schemaAttrs to be sorted asc. */
1030 inline static PRBool
sdb_attributeExists(SDB * sdb,CK_ATTRIBUTE_TYPE attr)1031 sdb_attributeExists(SDB *sdb, CK_ATTRIBUTE_TYPE attr)
1032 {
1033 SDBPrivate *sdb_p = sdb->private;
1034 int first = 0;
1035 int last = (int)sdb_p->numSchemaAttrs - 1;
1036 while (last >= first) {
1037 int mid = first + (last - first) / 2;
1038 if (sdb_p->schemaAttrs[mid] == attr) {
1039 return PR_TRUE;
1040 }
1041 if (attr > sdb_p->schemaAttrs[mid]) {
1042 first = mid + 1;
1043 } else {
1044 last = mid - 1;
1045 }
1046 }
1047
1048 return PR_FALSE;
1049 }
1050
1051 CK_RV
sdb_GetAttributeValue(SDB * sdb,CK_OBJECT_HANDLE object_id,CK_ATTRIBUTE * template,CK_ULONG count)1052 sdb_GetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE object_id,
1053 CK_ATTRIBUTE *template, CK_ULONG count)
1054 {
1055 CK_RV crv = CKR_OK;
1056 unsigned int tmplIdx;
1057 unsigned int resIdx = 0;
1058 unsigned int validCount = 0;
1059 unsigned int i;
1060
1061 if (count == 0) {
1062 return crv;
1063 }
1064
1065 CK_ATTRIBUTE *validTemplate;
1066 PRBool invalidExists = PR_FALSE;
1067 for (tmplIdx = 0; tmplIdx < count; tmplIdx++) {
1068 if (!sdb_attributeExists(sdb, template[tmplIdx].type)) {
1069 template[tmplIdx].ulValueLen = -1;
1070 crv = CKR_ATTRIBUTE_TYPE_INVALID;
1071 invalidExists = PR_TRUE;
1072 break;
1073 }
1074 }
1075
1076 if (!invalidExists) {
1077 validTemplate = template;
1078 validCount = count;
1079 } else {
1080 /* Create a new template containing only the valid subset of
1081 * input |template|, and query with that. */
1082 validCount = tmplIdx;
1083 validTemplate = malloc(sizeof(CK_ATTRIBUTE) * count);
1084 if (!validTemplate) {
1085 return CKR_HOST_MEMORY;
1086 }
1087 /* Copy in what we already know is valid. */
1088 for (i = 0; i < validCount; i++) {
1089 validTemplate[i] = template[i];
1090 }
1091
1092 /* tmplIdx was left at the index of the first invalid
1093 * attribute, which has been handled. We only need to
1094 * deal with the remainder. */
1095 tmplIdx++;
1096 for (; tmplIdx < count; tmplIdx++) {
1097 if (sdb_attributeExists(sdb, template[tmplIdx].type)) {
1098 validTemplate[validCount++] = template[tmplIdx];
1099 } else {
1100 template[tmplIdx].ulValueLen = -1;
1101 }
1102 }
1103 }
1104
1105 if (validCount) {
1106 LOCK_SQLITE()
1107 CK_RV crv2 = sdb_GetValidAttributeValueNoLock(sdb, object_id, validTemplate, validCount);
1108 UNLOCK_SQLITE()
1109
1110 /* If an invalid attribute was removed above, let
1111 * the caller know. Any other error from the actual
1112 * query should propogate. */
1113 crv = (crv2 == CKR_OK) ? crv : crv2;
1114 }
1115
1116 if (invalidExists) {
1117 /* Copy out valid lengths. */
1118 tmplIdx = 0;
1119 for (resIdx = 0; resIdx < validCount; resIdx++) {
1120 for (; tmplIdx < count; tmplIdx++) {
1121 if (template[tmplIdx].type != validTemplate[resIdx].type) {
1122 continue;
1123 }
1124 template[tmplIdx].ulValueLen = validTemplate[resIdx].ulValueLen;
1125 tmplIdx++;
1126 break;
1127 }
1128 }
1129 free(validTemplate);
1130 }
1131
1132 return crv;
1133 }
1134
1135 static const char SET_ATTRIBUTE_CMD[] = "UPDATE %s SET %s WHERE id=$ID;";
1136 CK_RV
sdb_SetAttributeValue(SDB * sdb,CK_OBJECT_HANDLE object_id,const CK_ATTRIBUTE * template,CK_ULONG count)1137 sdb_SetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE object_id,
1138 const CK_ATTRIBUTE *template, CK_ULONG count)
1139 {
1140 SDBPrivate *sdb_p = sdb->private;
1141 sqlite3 *sqlDB = NULL;
1142 sqlite3_stmt *stmt = NULL;
1143 char *setStr = NULL;
1144 char *newStr = NULL;
1145 int sqlerr = SQLITE_OK;
1146 int retry = 0;
1147 CK_RV error = CKR_OK;
1148 unsigned int i;
1149
1150 if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
1151 return CKR_TOKEN_WRITE_PROTECTED;
1152 }
1153
1154 if (count == 0) {
1155 return CKR_OK;
1156 }
1157
1158 LOCK_SQLITE()
1159 setStr = sqlite3_mprintf("");
1160 for (i = 0; setStr && i < count; i++) {
1161 if (i == 0) {
1162 sqlite3_free(setStr);
1163 setStr = sqlite3_mprintf("a%x=$VALUE%d",
1164 template[i].type, i);
1165 continue;
1166 }
1167 newStr = sqlite3_mprintf("%s,a%x=$VALUE%d", setStr,
1168 template[i].type, i);
1169 sqlite3_free(setStr);
1170 setStr = newStr;
1171 }
1172 newStr = NULL;
1173
1174 if (setStr == NULL) {
1175 return CKR_HOST_MEMORY;
1176 }
1177 newStr = sqlite3_mprintf(SET_ATTRIBUTE_CMD, sdb_p->table, setStr);
1178 sqlite3_free(setStr);
1179 if (newStr == NULL) {
1180 UNLOCK_SQLITE()
1181 return CKR_HOST_MEMORY;
1182 }
1183 error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
1184 if (error != CKR_OK) {
1185 goto loser;
1186 }
1187 sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL);
1188 if (sqlerr != SQLITE_OK)
1189 goto loser;
1190 for (i = 0; i < count; i++) {
1191 if (template[i].ulValueLen != 0) {
1192 sqlerr = sqlite3_bind_blob(stmt, i + 1, template[i].pValue,
1193 template[i].ulValueLen, SQLITE_STATIC);
1194 } else {
1195 sqlerr = sqlite3_bind_blob(stmt, i + 1, SQLITE_EXPLICIT_NULL,
1196 SQLITE_EXPLICIT_NULL_LEN, SQLITE_STATIC);
1197 }
1198 if (sqlerr != SQLITE_OK)
1199 goto loser;
1200 }
1201 sqlerr = sqlite3_bind_int(stmt, i + 1, object_id);
1202 if (sqlerr != SQLITE_OK)
1203 goto loser;
1204
1205 do {
1206 sqlerr = sqlite3_step(stmt);
1207 if (sqlerr == SQLITE_BUSY) {
1208 PR_Sleep(SDB_BUSY_RETRY_TIME);
1209 }
1210 } while (!sdb_done(sqlerr, &retry));
1211
1212 loser:
1213 if (newStr) {
1214 sqlite3_free(newStr);
1215 }
1216 if (error == CKR_OK) {
1217 error = sdb_mapSQLError(sdb_p->type, sqlerr);
1218 }
1219
1220 if (stmt) {
1221 sqlite3_reset(stmt);
1222 sqlite3_finalize(stmt);
1223 }
1224
1225 if (sqlDB) {
1226 sdb_closeDBLocal(sdb_p, sqlDB);
1227 }
1228
1229 UNLOCK_SQLITE()
1230 return error;
1231 }
1232
1233 /*
1234 * check to see if a candidate object handle already exists.
1235 */
1236 static PRBool
sdb_objectExists(SDB * sdb,CK_OBJECT_HANDLE candidate)1237 sdb_objectExists(SDB *sdb, CK_OBJECT_HANDLE candidate)
1238 {
1239 CK_RV crv;
1240 CK_ATTRIBUTE template = { CKA_LABEL, NULL, 0 };
1241
1242 crv = sdb_GetValidAttributeValueNoLock(sdb, candidate, &template, 1);
1243 if (crv == CKR_OBJECT_HANDLE_INVALID) {
1244 return PR_FALSE;
1245 }
1246 return PR_TRUE;
1247 }
1248
1249 /*
1250 * if we're here, we are in a transaction, so it's safe
1251 * to examine the current state of the database
1252 */
1253 static CK_OBJECT_HANDLE
sdb_getObjectId(SDB * sdb)1254 sdb_getObjectId(SDB *sdb)
1255 {
1256 CK_OBJECT_HANDLE candidate;
1257 static CK_OBJECT_HANDLE next_obj = CK_INVALID_HANDLE;
1258 int count;
1259 /*
1260 * get an initial object handle to use
1261 */
1262 if (next_obj == CK_INVALID_HANDLE) {
1263 PRTime time;
1264 time = PR_Now();
1265
1266 next_obj = (CK_OBJECT_HANDLE)(time & 0x3fffffffL);
1267 }
1268 candidate = next_obj++;
1269 /* detect that we've looped through all the handles... */
1270 for (count = 0; count < 0x40000000; count++, candidate = next_obj++) {
1271 /* mask off excess bits */
1272 candidate &= 0x3fffffff;
1273 /* if we hit zero, go to the next entry */
1274 if (candidate == CK_INVALID_HANDLE) {
1275 continue;
1276 }
1277 /* make sure we aren't already using */
1278 if (!sdb_objectExists(sdb, candidate)) {
1279 /* this one is free */
1280 return candidate;
1281 }
1282 }
1283
1284 /* no handle is free, fail */
1285 return CK_INVALID_HANDLE;
1286 }
1287
1288 CK_RV
sdb_GetNewObjectID(SDB * sdb,CK_OBJECT_HANDLE * object)1289 sdb_GetNewObjectID(SDB *sdb, CK_OBJECT_HANDLE *object)
1290 {
1291 CK_OBJECT_HANDLE id;
1292
1293 id = sdb_getObjectId(sdb);
1294 if (id == CK_INVALID_HANDLE) {
1295 return CKR_DEVICE_MEMORY; /* basically we ran out of resources */
1296 }
1297 *object = id;
1298 return CKR_OK;
1299 }
1300
1301 static const char CREATE_CMD[] = "INSERT INTO %s (id%s) VALUES($ID%s);";
1302 CK_RV
sdb_CreateObject(SDB * sdb,CK_OBJECT_HANDLE * object_id,const CK_ATTRIBUTE * template,CK_ULONG count)1303 sdb_CreateObject(SDB *sdb, CK_OBJECT_HANDLE *object_id,
1304 const CK_ATTRIBUTE *template, CK_ULONG count)
1305 {
1306 SDBPrivate *sdb_p = sdb->private;
1307 sqlite3 *sqlDB = NULL;
1308 sqlite3_stmt *stmt = NULL;
1309 char *columnStr = NULL;
1310 char *valueStr = NULL;
1311 char *newStr = NULL;
1312 int sqlerr = SQLITE_OK;
1313 CK_RV error = CKR_OK;
1314 CK_OBJECT_HANDLE this_object = CK_INVALID_HANDLE;
1315 int retry = 0;
1316 unsigned int i;
1317
1318 if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
1319 return CKR_TOKEN_WRITE_PROTECTED;
1320 }
1321
1322 LOCK_SQLITE()
1323 if ((*object_id != CK_INVALID_HANDLE) &&
1324 !sdb_objectExists(sdb, *object_id)) {
1325 this_object = *object_id;
1326 } else {
1327 this_object = sdb_getObjectId(sdb);
1328 }
1329 if (this_object == CK_INVALID_HANDLE) {
1330 UNLOCK_SQLITE();
1331 return CKR_HOST_MEMORY;
1332 }
1333 columnStr = sqlite3_mprintf("");
1334 valueStr = sqlite3_mprintf("");
1335 *object_id = this_object;
1336 for (i = 0; columnStr && valueStr && i < count; i++) {
1337 newStr = sqlite3_mprintf("%s,a%x", columnStr, template[i].type);
1338 sqlite3_free(columnStr);
1339 columnStr = newStr;
1340 newStr = sqlite3_mprintf("%s,$VALUE%d", valueStr, i);
1341 sqlite3_free(valueStr);
1342 valueStr = newStr;
1343 }
1344 newStr = NULL;
1345 if ((columnStr == NULL) || (valueStr == NULL)) {
1346 if (columnStr) {
1347 sqlite3_free(columnStr);
1348 }
1349 if (valueStr) {
1350 sqlite3_free(valueStr);
1351 }
1352 UNLOCK_SQLITE()
1353 return CKR_HOST_MEMORY;
1354 }
1355 newStr = sqlite3_mprintf(CREATE_CMD, sdb_p->table, columnStr, valueStr);
1356 sqlite3_free(columnStr);
1357 sqlite3_free(valueStr);
1358 error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
1359 if (error != CKR_OK) {
1360 goto loser;
1361 }
1362 sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL);
1363 if (sqlerr != SQLITE_OK)
1364 goto loser;
1365 sqlerr = sqlite3_bind_int(stmt, 1, *object_id);
1366 if (sqlerr != SQLITE_OK)
1367 goto loser;
1368 for (i = 0; i < count; i++) {
1369 if (template[i].ulValueLen) {
1370 sqlerr = sqlite3_bind_blob(stmt, i + 2, template[i].pValue,
1371 template[i].ulValueLen, SQLITE_STATIC);
1372 } else {
1373 sqlerr = sqlite3_bind_blob(stmt, i + 2, SQLITE_EXPLICIT_NULL,
1374 SQLITE_EXPLICIT_NULL_LEN, SQLITE_STATIC);
1375 }
1376 if (sqlerr != SQLITE_OK)
1377 goto loser;
1378 }
1379
1380 do {
1381 sqlerr = sqlite3_step(stmt);
1382 if (sqlerr == SQLITE_BUSY) {
1383 PR_Sleep(SDB_BUSY_RETRY_TIME);
1384 }
1385 } while (!sdb_done(sqlerr, &retry));
1386
1387 loser:
1388 if (newStr) {
1389 sqlite3_free(newStr);
1390 }
1391 if (error == CKR_OK) {
1392 error = sdb_mapSQLError(sdb_p->type, sqlerr);
1393 }
1394
1395 if (stmt) {
1396 sqlite3_reset(stmt);
1397 sqlite3_finalize(stmt);
1398 }
1399
1400 if (sqlDB) {
1401 sdb_closeDBLocal(sdb_p, sqlDB);
1402 }
1403 UNLOCK_SQLITE()
1404
1405 return error;
1406 }
1407
1408 /*
1409 * Generic destroy that can destroy metadata or objects
1410 */
1411 static const char DESTROY_CMD[] = "DELETE FROM %s WHERE (id=$ID);";
1412 CK_RV
sdb_destroyAnyObject(SDB * sdb,const char * table,CK_OBJECT_HANDLE object_id,const char * string_id)1413 sdb_destroyAnyObject(SDB *sdb, const char *table,
1414 CK_OBJECT_HANDLE object_id, const char *string_id)
1415 {
1416 SDBPrivate *sdb_p = sdb->private;
1417 sqlite3 *sqlDB = NULL;
1418 sqlite3_stmt *stmt = NULL;
1419 char *newStr = NULL;
1420 int sqlerr = SQLITE_OK;
1421 CK_RV error = CKR_OK;
1422 int retry = 0;
1423
1424 if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
1425 return CKR_TOKEN_WRITE_PROTECTED;
1426 }
1427
1428 LOCK_SQLITE()
1429 error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
1430 if (error != CKR_OK) {
1431 goto loser;
1432 }
1433 newStr = sqlite3_mprintf(DESTROY_CMD, table);
1434 if (newStr == NULL) {
1435 error = CKR_HOST_MEMORY;
1436 goto loser;
1437 }
1438 sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL);
1439 sqlite3_free(newStr);
1440 if (sqlerr != SQLITE_OK)
1441 goto loser;
1442 if (string_id == NULL) {
1443 sqlerr = sqlite3_bind_int(stmt, 1, object_id);
1444 } else {
1445 sqlerr = sqlite3_bind_text(stmt, 1, string_id,
1446 PORT_Strlen(string_id), SQLITE_STATIC);
1447 }
1448 if (sqlerr != SQLITE_OK)
1449 goto loser;
1450
1451 do {
1452 sqlerr = sqlite3_step(stmt);
1453 if (sqlerr == SQLITE_BUSY) {
1454 PR_Sleep(SDB_BUSY_RETRY_TIME);
1455 }
1456 } while (!sdb_done(sqlerr, &retry));
1457
1458 loser:
1459 if (error == CKR_OK) {
1460 error = sdb_mapSQLError(sdb_p->type, sqlerr);
1461 }
1462
1463 if (stmt) {
1464 sqlite3_reset(stmt);
1465 sqlite3_finalize(stmt);
1466 }
1467
1468 if (sqlDB) {
1469 sdb_closeDBLocal(sdb_p, sqlDB);
1470 }
1471
1472 UNLOCK_SQLITE()
1473 return error;
1474 }
1475
1476 CK_RV
sdb_DestroyObject(SDB * sdb,CK_OBJECT_HANDLE object_id)1477 sdb_DestroyObject(SDB *sdb, CK_OBJECT_HANDLE object_id)
1478 {
1479 SDBPrivate *sdb_p = sdb->private;
1480 return sdb_destroyAnyObject(sdb, sdb_p->table, object_id, NULL);
1481 }
1482
1483 CK_RV
sdb_DestroyMetaData(SDB * sdb,const char * id)1484 sdb_DestroyMetaData(SDB *sdb, const char *id)
1485 {
1486 return sdb_destroyAnyObject(sdb, "metaData", 0, id);
1487 }
1488
1489 static const char BEGIN_CMD[] = "BEGIN IMMEDIATE TRANSACTION;";
1490
1491 /*
1492 * start a transaction.
1493 *
1494 * We need to open a new database, then store that new database into
1495 * the private data structure. We open the database first, then use locks
1496 * to protect storing the data to prevent deadlocks.
1497 */
1498 CK_RV
sdb_Begin(SDB * sdb)1499 sdb_Begin(SDB *sdb)
1500 {
1501 SDBPrivate *sdb_p = sdb->private;
1502 sqlite3 *sqlDB = NULL;
1503 sqlite3_stmt *stmt = NULL;
1504 int sqlerr = SQLITE_OK;
1505 CK_RV error = CKR_OK;
1506 int retry = 0;
1507
1508 if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
1509 return CKR_TOKEN_WRITE_PROTECTED;
1510 }
1511
1512 LOCK_SQLITE()
1513
1514 /* get a new version that we will use for the entire transaction */
1515 sqlerr = sdb_openDB(sdb_p->sqlDBName, &sqlDB, SDB_RDWR);
1516 if (sqlerr != SQLITE_OK) {
1517 goto loser;
1518 }
1519
1520 sqlerr = sqlite3_prepare_v2(sqlDB, BEGIN_CMD, -1, &stmt, NULL);
1521
1522 do {
1523 sqlerr = sqlite3_step(stmt);
1524 if (sqlerr == SQLITE_BUSY) {
1525 PR_Sleep(SDB_BUSY_RETRY_TIME);
1526 }
1527 } while (!sdb_done(sqlerr, &retry));
1528
1529 if (stmt) {
1530 sqlite3_reset(stmt);
1531 sqlite3_finalize(stmt);
1532 }
1533
1534 loser:
1535 error = sdb_mapSQLError(sdb_p->type, sqlerr);
1536
1537 /* we are starting a new transaction,
1538 * and if we succeeded, then save this database for the rest of
1539 * our transaction */
1540 if (error == CKR_OK) {
1541 /* we hold a 'BEGIN TRANSACTION' and a sdb_p->lock. At this point
1542 * sdb_p->sqlXactDB MUST be null */
1543 PR_EnterMonitor(sdb_p->dbMon);
1544 PORT_Assert(sdb_p->sqlXactDB == NULL);
1545 sdb_p->sqlXactDB = sqlDB;
1546 sdb_p->sqlXactThread = PR_GetCurrentThread();
1547 PR_ExitMonitor(sdb_p->dbMon);
1548 } else {
1549 /* we failed to start our transaction,
1550 * free any databases we opened. */
1551 if (sqlDB) {
1552 sqlite3_close(sqlDB);
1553 }
1554 }
1555
1556 UNLOCK_SQLITE()
1557 return error;
1558 }
1559
1560 /*
1561 * Complete a transaction. Basically undo everything we did in begin.
1562 * There are 2 flavors Abort and Commit. Basically the only differerence between
1563 * these 2 are what the database will show. (no change in to former, change in
1564 * the latter).
1565 */
1566 static CK_RV
sdb_complete(SDB * sdb,const char * cmd)1567 sdb_complete(SDB *sdb, const char *cmd)
1568 {
1569 SDBPrivate *sdb_p = sdb->private;
1570 sqlite3 *sqlDB = NULL;
1571 sqlite3_stmt *stmt = NULL;
1572 int sqlerr = SQLITE_OK;
1573 CK_RV error = CKR_OK;
1574 int retry = 0;
1575
1576 if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
1577 return CKR_TOKEN_WRITE_PROTECTED;
1578 }
1579
1580 /* We must have a transation database, or we shouldn't have arrived here */
1581 PR_EnterMonitor(sdb_p->dbMon);
1582 PORT_Assert(sdb_p->sqlXactDB);
1583 if (sdb_p->sqlXactDB == NULL) {
1584 PR_ExitMonitor(sdb_p->dbMon);
1585 return CKR_GENERAL_ERROR; /* shouldn't happen */
1586 }
1587 PORT_Assert(sdb_p->sqlXactThread == PR_GetCurrentThread());
1588 if (sdb_p->sqlXactThread != PR_GetCurrentThread()) {
1589 PR_ExitMonitor(sdb_p->dbMon);
1590 return CKR_GENERAL_ERROR; /* shouldn't happen */
1591 }
1592 sqlDB = sdb_p->sqlXactDB;
1593 sdb_p->sqlXactDB = NULL; /* no one else can get to this DB,
1594 * safe to unlock */
1595 sdb_p->sqlXactThread = NULL;
1596 PR_ExitMonitor(sdb_p->dbMon);
1597
1598 sqlerr = sqlite3_prepare_v2(sqlDB, cmd, -1, &stmt, NULL);
1599
1600 do {
1601 sqlerr = sqlite3_step(stmt);
1602 if (sqlerr == SQLITE_BUSY) {
1603 PR_Sleep(SDB_BUSY_RETRY_TIME);
1604 }
1605 } while (!sdb_done(sqlerr, &retry));
1606
1607 /* Pending BEGIN TRANSACTIONS Can move forward at this point. */
1608
1609 if (stmt) {
1610 sqlite3_reset(stmt);
1611 sqlite3_finalize(stmt);
1612 }
1613
1614 /* we we have a cached DB image, update it as well */
1615 if (sdb_p->cacheTable) {
1616 PR_EnterMonitor(sdb_p->dbMon);
1617 sdb_updateCache(sdb_p);
1618 PR_ExitMonitor(sdb_p->dbMon);
1619 }
1620
1621 error = sdb_mapSQLError(sdb_p->type, sqlerr);
1622
1623 /* We just finished a transaction.
1624 * Free the database, and remove it from the list */
1625 sqlite3_close(sqlDB);
1626
1627 return error;
1628 }
1629
1630 static const char COMMIT_CMD[] = "COMMIT TRANSACTION;";
1631 CK_RV
sdb_Commit(SDB * sdb)1632 sdb_Commit(SDB *sdb)
1633 {
1634 CK_RV crv;
1635 LOCK_SQLITE()
1636 crv = sdb_complete(sdb, COMMIT_CMD);
1637 UNLOCK_SQLITE()
1638 return crv;
1639 }
1640
1641 static const char ROLLBACK_CMD[] = "ROLLBACK TRANSACTION;";
1642 CK_RV
sdb_Abort(SDB * sdb)1643 sdb_Abort(SDB *sdb)
1644 {
1645 CK_RV crv;
1646 LOCK_SQLITE()
1647 crv = sdb_complete(sdb, ROLLBACK_CMD);
1648 UNLOCK_SQLITE()
1649 return crv;
1650 }
1651
1652 static int tableExists(sqlite3 *sqlDB, const char *tableName);
1653
1654 static const char GET_PW_CMD[] = "SELECT ALL * FROM metaData WHERE id=$ID;";
1655 CK_RV
sdb_GetMetaData(SDB * sdb,const char * id,SECItem * item1,SECItem * item2)1656 sdb_GetMetaData(SDB *sdb, const char *id, SECItem *item1, SECItem *item2)
1657 {
1658 SDBPrivate *sdb_p = sdb->private;
1659 sqlite3 *sqlDB = sdb_p->sqlXactDB;
1660 sqlite3_stmt *stmt = NULL;
1661 int sqlerr = SQLITE_OK;
1662 CK_RV error = CKR_OK;
1663 int found = 0;
1664 int retry = 0;
1665
1666 LOCK_SQLITE()
1667 error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
1668 if (error != CKR_OK) {
1669 goto loser;
1670 }
1671
1672 /* handle 'test' versions of the sqlite db */
1673 sqlerr = sqlite3_prepare_v2(sqlDB, GET_PW_CMD, -1, &stmt, NULL);
1674 /* Sigh, if we created a new table since we opened the database,
1675 * the database handle will not see the new table, we need to close this
1676 * database and reopen it. This is safe because we are holding the lock
1677 * still. */
1678 if (sqlerr == SQLITE_SCHEMA) {
1679 sqlerr = sdb_reopenDBLocal(sdb_p, &sqlDB);
1680 if (sqlerr != SQLITE_OK) {
1681 goto loser;
1682 }
1683 sqlerr = sqlite3_prepare_v2(sqlDB, GET_PW_CMD, -1, &stmt, NULL);
1684 }
1685 if (sqlerr != SQLITE_OK)
1686 goto loser;
1687 sqlerr = sqlite3_bind_text(stmt, 1, id, PORT_Strlen(id), SQLITE_STATIC);
1688 do {
1689 sqlerr = sqlite3_step(stmt);
1690 if (sqlerr == SQLITE_BUSY) {
1691 PR_Sleep(SDB_BUSY_RETRY_TIME);
1692 }
1693 if (sqlerr == SQLITE_ROW) {
1694 const char *blobData;
1695 unsigned int len = item1->len;
1696 item1->len = sqlite3_column_bytes(stmt, 1);
1697 if (item1->len > len) {
1698 error = CKR_BUFFER_TOO_SMALL;
1699 continue;
1700 }
1701 blobData = sqlite3_column_blob(stmt, 1);
1702 PORT_Memcpy(item1->data, blobData, item1->len);
1703 if (item2) {
1704 len = item2->len;
1705 item2->len = sqlite3_column_bytes(stmt, 2);
1706 if (item2->len > len) {
1707 error = CKR_BUFFER_TOO_SMALL;
1708 continue;
1709 }
1710 blobData = sqlite3_column_blob(stmt, 2);
1711 PORT_Memcpy(item2->data, blobData, item2->len);
1712 }
1713 found = 1;
1714 }
1715 } while (!sdb_done(sqlerr, &retry));
1716
1717 loser:
1718 /* fix up the error if necessary */
1719 if (error == CKR_OK) {
1720 error = sdb_mapSQLError(sdb_p->type, sqlerr);
1721 if (!found && error == CKR_OK) {
1722 error = CKR_OBJECT_HANDLE_INVALID;
1723 }
1724 }
1725
1726 if (stmt) {
1727 sqlite3_reset(stmt);
1728 sqlite3_finalize(stmt);
1729 }
1730
1731 if (sqlDB) {
1732 sdb_closeDBLocal(sdb_p, sqlDB);
1733 }
1734 UNLOCK_SQLITE()
1735
1736 return error;
1737 }
1738
1739 static const char PW_CREATE_TABLE_CMD[] =
1740 "CREATE TABLE metaData (id PRIMARY KEY UNIQUE ON CONFLICT REPLACE, item1, item2);";
1741 static const char PW_CREATE_CMD[] =
1742 "INSERT INTO metaData (id,item1,item2) VALUES($ID,$ITEM1,$ITEM2);";
1743 static const char MD_CREATE_CMD[] =
1744 "INSERT INTO metaData (id,item1) VALUES($ID,$ITEM1);";
1745
1746 CK_RV
sdb_PutMetaData(SDB * sdb,const char * id,const SECItem * item1,const SECItem * item2)1747 sdb_PutMetaData(SDB *sdb, const char *id, const SECItem *item1,
1748 const SECItem *item2)
1749 {
1750 SDBPrivate *sdb_p = sdb->private;
1751 sqlite3 *sqlDB = sdb_p->sqlXactDB;
1752 sqlite3_stmt *stmt = NULL;
1753 int sqlerr = SQLITE_OK;
1754 CK_RV error = CKR_OK;
1755 int retry = 0;
1756 const char *cmd = PW_CREATE_CMD;
1757
1758 if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
1759 return CKR_TOKEN_WRITE_PROTECTED;
1760 }
1761
1762 LOCK_SQLITE()
1763 error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
1764 if (error != CKR_OK) {
1765 goto loser;
1766 }
1767
1768 if (!tableExists(sqlDB, "metaData")) {
1769 sqlerr = sqlite3_exec(sqlDB, PW_CREATE_TABLE_CMD, NULL, 0, NULL);
1770 if (sqlerr != SQLITE_OK)
1771 goto loser;
1772 }
1773 if (item2 == NULL) {
1774 cmd = MD_CREATE_CMD;
1775 }
1776 sqlerr = sqlite3_prepare_v2(sqlDB, cmd, -1, &stmt, NULL);
1777 if (sqlerr != SQLITE_OK)
1778 goto loser;
1779 sqlerr = sqlite3_bind_text(stmt, 1, id, PORT_Strlen(id), SQLITE_STATIC);
1780 if (sqlerr != SQLITE_OK)
1781 goto loser;
1782 sqlerr = sqlite3_bind_blob(stmt, 2, item1->data, item1->len, SQLITE_STATIC);
1783 if (sqlerr != SQLITE_OK)
1784 goto loser;
1785 if (item2) {
1786 sqlerr = sqlite3_bind_blob(stmt, 3, item2->data,
1787 item2->len, SQLITE_STATIC);
1788 if (sqlerr != SQLITE_OK)
1789 goto loser;
1790 }
1791
1792 do {
1793 sqlerr = sqlite3_step(stmt);
1794 if (sqlerr == SQLITE_BUSY) {
1795 PR_Sleep(SDB_BUSY_RETRY_TIME);
1796 }
1797 } while (!sdb_done(sqlerr, &retry));
1798
1799 loser:
1800 /* fix up the error if necessary */
1801 if (error == CKR_OK) {
1802 error = sdb_mapSQLError(sdb_p->type, sqlerr);
1803 }
1804
1805 if (stmt) {
1806 sqlite3_reset(stmt);
1807 sqlite3_finalize(stmt);
1808 }
1809
1810 if (sqlDB) {
1811 sdb_closeDBLocal(sdb_p, sqlDB);
1812 }
1813 UNLOCK_SQLITE()
1814
1815 return error;
1816 }
1817
1818 static const char RESET_CMD[] = "DELETE FROM %s;";
1819 CK_RV
sdb_Reset(SDB * sdb)1820 sdb_Reset(SDB *sdb)
1821 {
1822 SDBPrivate *sdb_p = sdb->private;
1823 sqlite3 *sqlDB = NULL;
1824 char *newStr;
1825 int sqlerr = SQLITE_OK;
1826 CK_RV error = CKR_OK;
1827
1828 /* only Key databases can be reset */
1829 if (sdb_p->type != SDB_KEY) {
1830 return CKR_OBJECT_HANDLE_INVALID;
1831 }
1832
1833 LOCK_SQLITE()
1834 error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
1835 if (error != CKR_OK) {
1836 goto loser;
1837 }
1838
1839 if (tableExists(sqlDB, sdb_p->table)) {
1840 /* delete the contents of the key table */
1841 newStr = sqlite3_mprintf(RESET_CMD, sdb_p->table);
1842 if (newStr == NULL) {
1843 error = CKR_HOST_MEMORY;
1844 goto loser;
1845 }
1846 sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
1847 sqlite3_free(newStr);
1848
1849 if (sqlerr != SQLITE_OK)
1850 goto loser;
1851 }
1852
1853 /* delete the password entry table */
1854 sqlerr = sqlite3_exec(sqlDB, "DROP TABLE IF EXISTS metaData;",
1855 NULL, 0, NULL);
1856
1857 loser:
1858 /* fix up the error if necessary */
1859 if (error == CKR_OK) {
1860 error = sdb_mapSQLError(sdb_p->type, sqlerr);
1861 }
1862
1863 if (sqlDB) {
1864 sdb_closeDBLocal(sdb_p, sqlDB);
1865 }
1866
1867 UNLOCK_SQLITE()
1868 return error;
1869 }
1870
1871 CK_RV
sdb_Close(SDB * sdb)1872 sdb_Close(SDB *sdb)
1873 {
1874 SDBPrivate *sdb_p = sdb->private;
1875 int sqlerr = SQLITE_OK;
1876 sdbDataType type = sdb_p->type;
1877
1878 sqlerr = sqlite3_close(sdb_p->sqlReadDB);
1879 PORT_Free(sdb_p->sqlDBName);
1880 if (sdb_p->cacheTable) {
1881 sqlite3_free(sdb_p->cacheTable);
1882 }
1883 if (sdb_p->dbMon) {
1884 PR_DestroyMonitor(sdb_p->dbMon);
1885 }
1886 free(sdb_p->schemaAttrs);
1887 free(sdb_p);
1888 free(sdb);
1889 return sdb_mapSQLError(type, sqlerr);
1890 }
1891
1892 /*
1893 * functions to support open
1894 */
1895
1896 static const char CHECK_TABLE_CMD[] = "SELECT ALL * FROM %s LIMIT 0;";
1897
1898 /* return 1 if sqlDB contains table 'tableName */
1899 static int
tableExists(sqlite3 * sqlDB,const char * tableName)1900 tableExists(sqlite3 *sqlDB, const char *tableName)
1901 {
1902 char *cmd = sqlite3_mprintf(CHECK_TABLE_CMD, tableName);
1903 int sqlerr = SQLITE_OK;
1904
1905 if (cmd == NULL) {
1906 return 0;
1907 }
1908
1909 sqlerr = sqlite3_exec(sqlDB, cmd, NULL, 0, 0);
1910 sqlite3_free(cmd);
1911
1912 return (sqlerr == SQLITE_OK) ? 1 : 0;
1913 }
1914
1915 void
sdb_SetForkState(PRBool forked)1916 sdb_SetForkState(PRBool forked)
1917 {
1918 /* XXXright now this is a no-op. The global fork state in the softokn3
1919 * shared library is already taken care of at the PKCS#11 level.
1920 * If and when we add fork state to the sqlite shared library and extern
1921 * interface, we will need to set it and reset it from here */
1922 }
1923
1924 static int
sdb_attributeComparator(const void * a,const void * b)1925 sdb_attributeComparator(const void *a, const void *b)
1926 {
1927 if (*(CK_ATTRIBUTE_TYPE *)a < *(CK_ATTRIBUTE_TYPE *)b) {
1928 return -1;
1929 }
1930 if (*(CK_ATTRIBUTE_TYPE *)a > *(CK_ATTRIBUTE_TYPE *)b) {
1931 return 1;
1932 }
1933 return 0;
1934 }
1935
1936 /*
1937 * initialize a single database
1938 */
1939 static const char INIT_CMD[] =
1940 "CREATE TABLE %s (id PRIMARY KEY UNIQUE ON CONFLICT ABORT%s)";
1941
1942 CK_RV
sdb_init(char * dbname,char * table,sdbDataType type,int * inUpdate,int * newInit,int inFlags,PRUint32 accessOps,SDB ** pSdb)1943 sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate,
1944 int *newInit, int inFlags, PRUint32 accessOps, SDB **pSdb)
1945 {
1946 int i;
1947 char *initStr = NULL;
1948 char *newStr;
1949 char *queryStr = NULL;
1950 int inTransaction = 0;
1951 SDB *sdb = NULL;
1952 SDBPrivate *sdb_p = NULL;
1953 sqlite3 *sqlDB = NULL;
1954 int sqlerr = SQLITE_OK;
1955 CK_RV error = CKR_OK;
1956 char *cacheTable = NULL;
1957 PRIntervalTime now = 0;
1958 char *env;
1959 PRBool enableCache = PR_FALSE;
1960 PRBool checkFSType = PR_FALSE;
1961 PRBool measureSpeed = PR_FALSE;
1962 PRBool create;
1963 int flags = inFlags & 0x7;
1964
1965 *pSdb = NULL;
1966 *inUpdate = 0;
1967
1968 /* sqlite3 doesn't have a flag to specify that we want to
1969 * open the database read only. If the db doesn't exist,
1970 * sqlite3 will always create it.
1971 */
1972 LOCK_SQLITE();
1973 create = (_NSSUTIL_Access(dbname, PR_ACCESS_EXISTS) != PR_SUCCESS);
1974 if ((flags == SDB_RDONLY) && create) {
1975 error = sdb_mapSQLError(type, SQLITE_CANTOPEN);
1976 goto loser;
1977 }
1978 sqlerr = sdb_openDB(dbname, &sqlDB, flags);
1979 if (sqlerr != SQLITE_OK) {
1980 error = sdb_mapSQLError(type, sqlerr);
1981 goto loser;
1982 }
1983
1984 /*
1985 * SQL created the file, but it doesn't set appropriate modes for
1986 * a database.
1987 *
1988 * NO NSPR call for chmod? :(
1989 */
1990 if (create && sdb_chmod(dbname, 0600) != 0) {
1991 error = sdb_mapSQLError(type, SQLITE_CANTOPEN);
1992 goto loser;
1993 }
1994
1995 if (flags != SDB_RDONLY) {
1996 sqlerr = sqlite3_exec(sqlDB, BEGIN_CMD, NULL, 0, NULL);
1997 if (sqlerr != SQLITE_OK) {
1998 error = sdb_mapSQLError(type, sqlerr);
1999 goto loser;
2000 }
2001 inTransaction = 1;
2002 }
2003 if (!tableExists(sqlDB, table)) {
2004 *newInit = 1;
2005 if (flags != SDB_CREATE) {
2006 error = sdb_mapSQLError(type, SQLITE_CANTOPEN);
2007 goto loser;
2008 }
2009 initStr = sqlite3_mprintf("");
2010 for (i = 0; initStr && i < known_attributes_size; i++) {
2011 newStr = sqlite3_mprintf("%s, a%x", initStr, known_attributes[i]);
2012 sqlite3_free(initStr);
2013 initStr = newStr;
2014 }
2015 if (initStr == NULL) {
2016 error = CKR_HOST_MEMORY;
2017 goto loser;
2018 }
2019
2020 newStr = sqlite3_mprintf(INIT_CMD, table, initStr);
2021 sqlite3_free(initStr);
2022 if (newStr == NULL) {
2023 error = CKR_HOST_MEMORY;
2024 goto loser;
2025 }
2026 sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
2027 sqlite3_free(newStr);
2028 if (sqlerr != SQLITE_OK) {
2029 error = sdb_mapSQLError(type, sqlerr);
2030 goto loser;
2031 }
2032
2033 newStr = sqlite3_mprintf(CREATE_ISSUER_INDEX_CMD, table);
2034 if (newStr == NULL) {
2035 error = CKR_HOST_MEMORY;
2036 goto loser;
2037 }
2038 sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
2039 sqlite3_free(newStr);
2040 if (sqlerr != SQLITE_OK) {
2041 error = sdb_mapSQLError(type, sqlerr);
2042 goto loser;
2043 }
2044
2045 newStr = sqlite3_mprintf(CREATE_SUBJECT_INDEX_CMD, table);
2046 if (newStr == NULL) {
2047 error = CKR_HOST_MEMORY;
2048 goto loser;
2049 }
2050 sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
2051 sqlite3_free(newStr);
2052 if (sqlerr != SQLITE_OK) {
2053 error = sdb_mapSQLError(type, sqlerr);
2054 goto loser;
2055 }
2056
2057 newStr = sqlite3_mprintf(CREATE_LABEL_INDEX_CMD, table);
2058 if (newStr == NULL) {
2059 error = CKR_HOST_MEMORY;
2060 goto loser;
2061 }
2062 sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
2063 sqlite3_free(newStr);
2064 if (sqlerr != SQLITE_OK) {
2065 error = sdb_mapSQLError(type, sqlerr);
2066 goto loser;
2067 }
2068
2069 newStr = sqlite3_mprintf(CREATE_ID_INDEX_CMD, table);
2070 if (newStr == NULL) {
2071 error = CKR_HOST_MEMORY;
2072 goto loser;
2073 }
2074 sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
2075 sqlite3_free(newStr);
2076 if (sqlerr != SQLITE_OK) {
2077 error = sdb_mapSQLError(type, sqlerr);
2078 goto loser;
2079 }
2080 }
2081 /*
2082 * detect the case where we have created the database, but have
2083 * not yet updated it.
2084 *
2085 * We only check the Key database because only the key database has
2086 * a metaData table. The metaData table is created when a password
2087 * is set, or in the case of update, when a password is supplied.
2088 * If no key database exists, then the update would have happened immediately
2089 * on noticing that the cert database didn't exist (see newInit set above).
2090 */
2091 if (type == SDB_KEY && !tableExists(sqlDB, "metaData")) {
2092 *newInit = 1;
2093 }
2094
2095 /* access to network filesystems are significantly slower than local ones
2096 * for database operations. In those cases we need to create a cached copy
2097 * of the database in a temporary location on the local disk. SQLITE
2098 * already provides a way to create a temporary table and initialize it,
2099 * so we use it for the cache (see sdb_buildCache for how it's done).*/
2100
2101 /*
2102 * we decide whether or not to use the cache based on the following input.
2103 *
2104 * NSS_SDB_USE_CACHE environment variable is set to anything other than
2105 * "yes" or "no" (for instance, "auto"): NSS will measure the performance
2106 * of access to the temp database versus the access to the user's
2107 * passed-in database location. If the temp database location is
2108 * "significantly" faster we will use the cache.
2109 *
2110 * NSS_SDB_USE_CACHE environment variable is nonexistent or set to "no":
2111 * cache will not be used.
2112 *
2113 * NSS_SDB_USE_CACHE environment variable is set to "yes": cache will
2114 * always be used.
2115 *
2116 * It is expected that most applications will not need this feature, and
2117 * thus it is disabled by default.
2118 */
2119
2120 env = PR_GetEnvSecure("NSS_SDB_USE_CACHE");
2121
2122 /* Variables enableCache, checkFSType, measureSpeed are PR_FALSE by default,
2123 * which is the expected behavior for NSS_SDB_USE_CACHE="no".
2124 * We don't need to check for "no" here. */
2125 if (!env) {
2126 /* By default, with no variable set, we avoid expensive measuring for
2127 * most FS types. We start with inexpensive FS type checking, and
2128 * might perform measuring for some types. */
2129 checkFSType = PR_TRUE;
2130 } else if (PORT_Strcasecmp(env, "yes") == 0) {
2131 enableCache = PR_TRUE;
2132 } else if (PORT_Strcasecmp(env, "no") != 0) { /* not "no" => "auto" */
2133 measureSpeed = PR_TRUE;
2134 }
2135
2136 if (checkFSType) {
2137 #if defined(LINUX) && !defined(ANDROID)
2138 struct statfs statfs_s;
2139 if (statfs(dbname, &statfs_s) == 0) {
2140 switch (statfs_s.f_type) {
2141 case SMB_SUPER_MAGIC:
2142 case 0xff534d42: /* CIFS_MAGIC_NUMBER */
2143 case NFS_SUPER_MAGIC:
2144 /* We assume these are slow. */
2145 enableCache = PR_TRUE;
2146 break;
2147 case CODA_SUPER_MAGIC:
2148 case 0x65735546: /* FUSE_SUPER_MAGIC */
2149 case NCP_SUPER_MAGIC:
2150 /* It's uncertain if this FS is fast or slow.
2151 * It seems reasonable to perform slow measuring for users
2152 * with questionable FS speed. */
2153 measureSpeed = PR_TRUE;
2154 break;
2155 case AFS_SUPER_MAGIC: /* Already implements caching. */
2156 default:
2157 break;
2158 }
2159 }
2160 #endif
2161 }
2162
2163 if (measureSpeed) {
2164 char *tempDir = NULL;
2165 PRUint32 tempOps = 0;
2166 /*
2167 * Use PR_Access to determine how expensive it
2168 * is to check for the existance of a local file compared to the same
2169 * check in the temp directory. If the temp directory is faster, cache
2170 * the database there. */
2171 tempDir = sdb_getTempDir(sqlDB);
2172 if (tempDir) {
2173 tempOps = sdb_measureAccess(tempDir);
2174 PORT_Free(tempDir);
2175
2176 /* There is a cost to continually copying the database.
2177 * Account for that cost with the arbitrary factor of 10 */
2178 enableCache = (PRBool)(tempOps > accessOps * 10);
2179 }
2180 }
2181
2182 if (enableCache) {
2183 /* try to set the temp store to memory.*/
2184 sqlite3_exec(sqlDB, "PRAGMA temp_store=MEMORY", NULL, 0, NULL);
2185 /* Failure to set the temp store to memory is not fatal,
2186 * ignore the error */
2187
2188 cacheTable = sqlite3_mprintf("%sCache", table);
2189 if (cacheTable == NULL) {
2190 error = CKR_HOST_MEMORY;
2191 goto loser;
2192 }
2193 /* build the cache table */
2194 error = sdb_buildCache(sqlDB, type, cacheTable, table);
2195 if (error != CKR_OK) {
2196 goto loser;
2197 }
2198 /* initialize the last cache build time */
2199 now = PR_IntervalNow();
2200 }
2201
2202 sdb = (SDB *)malloc(sizeof(SDB));
2203 if (!sdb) {
2204 error = CKR_HOST_MEMORY;
2205 goto loser;
2206 }
2207 sdb_p = (SDBPrivate *)malloc(sizeof(SDBPrivate));
2208 if (!sdb_p) {
2209 error = CKR_HOST_MEMORY;
2210 goto loser;
2211 }
2212
2213 /* Cache the attributes that are held in the table, so we can later check
2214 * that queried attributes actually exist. We don't assume the schema
2215 * to be exactly |known_attributes|, as it may change over time. */
2216 sdb_p->schemaAttrs = NULL;
2217 if (!PORT_Strcmp("nssPublic", table) ||
2218 !PORT_Strcmp("nssPrivate", table)) {
2219 sqlite3_stmt *stmt = NULL;
2220 int retry = 0;
2221 unsigned int backedAttrs = 0;
2222
2223 /* Can't bind parameters to a PRAGMA. */
2224 queryStr = sqlite3_mprintf("PRAGMA table_info(%s);", table);
2225 if (queryStr == NULL) {
2226 error = CKR_HOST_MEMORY;
2227 goto loser;
2228 }
2229 sqlerr = sqlite3_prepare_v2(sqlDB, queryStr, -1, &stmt, NULL);
2230 sqlite3_free(queryStr);
2231 queryStr = NULL;
2232 if (sqlerr != SQLITE_OK) {
2233 goto loser;
2234 }
2235 unsigned int schemaAttrsCapacity = known_attributes_size;
2236 sdb_p->schemaAttrs = malloc(schemaAttrsCapacity * sizeof(CK_ATTRIBUTE));
2237 if (!sdb_p->schemaAttrs) {
2238 error = CKR_HOST_MEMORY;
2239 goto loser;
2240 }
2241 do {
2242 sqlerr = sqlite3_step(stmt);
2243 if (sqlerr == SQLITE_BUSY) {
2244 PR_Sleep(SDB_BUSY_RETRY_TIME);
2245 }
2246 if (sqlerr == SQLITE_ROW) {
2247 if (backedAttrs == schemaAttrsCapacity) {
2248 schemaAttrsCapacity += known_attributes_size;
2249 sdb_p->schemaAttrs = realloc(sdb_p->schemaAttrs,
2250 schemaAttrsCapacity * sizeof(CK_ATTRIBUTE));
2251 if (!sdb_p->schemaAttrs) {
2252 error = CKR_HOST_MEMORY;
2253 goto loser;
2254 }
2255 }
2256 /* Record the ULONG attribute value. */
2257 char *val = (char *)sqlite3_column_text(stmt, 1);
2258 if (val && val[0] == 'a') {
2259 CK_ATTRIBUTE_TYPE attr = strtoul(&val[1], NULL, 16);
2260 sdb_p->schemaAttrs[backedAttrs++] = attr;
2261 }
2262 }
2263 } while (!sdb_done(sqlerr, &retry));
2264 if (sqlerr != SQLITE_DONE) {
2265 goto loser;
2266 }
2267 sqlerr = sqlite3_reset(stmt);
2268 if (sqlerr != SQLITE_OK) {
2269 goto loser;
2270 }
2271 sqlerr = sqlite3_finalize(stmt);
2272 if (sqlerr != SQLITE_OK) {
2273 goto loser;
2274 }
2275
2276 sdb_p->numSchemaAttrs = backedAttrs;
2277
2278 /* Sort these once so we can shortcut invalid attribute searches. */
2279 qsort(sdb_p->schemaAttrs, sdb_p->numSchemaAttrs,
2280 sizeof(CK_ATTRIBUTE_TYPE), sdb_attributeComparator);
2281 }
2282
2283 /* invariant fields */
2284 sdb_p->sqlDBName = PORT_Strdup(dbname);
2285 sdb_p->type = type;
2286 sdb_p->table = table;
2287 sdb_p->cacheTable = cacheTable;
2288 sdb_p->lastUpdateTime = now;
2289 /* set the cache delay time. This is how long we will wait before we
2290 * decide the existing cache is stale. Currently set to 10 sec */
2291 sdb_p->updateInterval = PR_SecondsToInterval(10);
2292 sdb_p->dbMon = PR_NewMonitor();
2293 /* these fields are protected by the lock */
2294 sdb_p->sqlXactDB = NULL;
2295 sdb_p->sqlXactThread = NULL;
2296 sdb->private = sdb_p;
2297 sdb->version = 1;
2298 sdb->sdb_flags = inFlags | SDB_HAS_META;
2299 sdb->app_private = NULL;
2300 sdb->sdb_FindObjectsInit = sdb_FindObjectsInit;
2301 sdb->sdb_FindObjects = sdb_FindObjects;
2302 sdb->sdb_FindObjectsFinal = sdb_FindObjectsFinal;
2303 sdb->sdb_GetAttributeValue = sdb_GetAttributeValue;
2304 sdb->sdb_SetAttributeValue = sdb_SetAttributeValue;
2305 sdb->sdb_CreateObject = sdb_CreateObject;
2306 sdb->sdb_DestroyObject = sdb_DestroyObject;
2307 sdb->sdb_GetMetaData = sdb_GetMetaData;
2308 sdb->sdb_PutMetaData = sdb_PutMetaData;
2309 sdb->sdb_DestroyMetaData = sdb_DestroyMetaData;
2310 sdb->sdb_Begin = sdb_Begin;
2311 sdb->sdb_Commit = sdb_Commit;
2312 sdb->sdb_Abort = sdb_Abort;
2313 sdb->sdb_Reset = sdb_Reset;
2314 sdb->sdb_Close = sdb_Close;
2315 sdb->sdb_SetForkState = sdb_SetForkState;
2316 sdb->sdb_GetNewObjectID = sdb_GetNewObjectID;
2317
2318 if (inTransaction) {
2319 sqlerr = sqlite3_exec(sqlDB, COMMIT_CMD, NULL, 0, NULL);
2320 if (sqlerr != SQLITE_OK) {
2321 error = sdb_mapSQLError(sdb_p->type, sqlerr);
2322 goto loser;
2323 }
2324 inTransaction = 0;
2325 }
2326
2327 sdb_p->sqlReadDB = sqlDB;
2328
2329 *pSdb = sdb;
2330 UNLOCK_SQLITE();
2331 return CKR_OK;
2332
2333 loser:
2334 /* lots of stuff to do */
2335 if (inTransaction) {
2336 sqlite3_exec(sqlDB, ROLLBACK_CMD, NULL, 0, NULL);
2337 }
2338 if (sdb) {
2339 free(sdb);
2340 }
2341 if (sdb_p) {
2342 if (sdb_p->schemaAttrs) {
2343 free(sdb_p->schemaAttrs);
2344 }
2345 free(sdb_p);
2346 }
2347 if (sqlDB) {
2348 sqlite3_close(sqlDB);
2349 }
2350 UNLOCK_SQLITE();
2351 return error;
2352 }
2353
2354 /* sdbopen */
2355 CK_RV
s_open(const char * directory,const char * certPrefix,const char * keyPrefix,int cert_version,int key_version,int flags,SDB ** certdb,SDB ** keydb,int * newInit)2356 s_open(const char *directory, const char *certPrefix, const char *keyPrefix,
2357 int cert_version, int key_version, int flags,
2358 SDB **certdb, SDB **keydb, int *newInit)
2359 {
2360 char *cert = sdb_BuildFileName(directory, certPrefix,
2361 "cert", cert_version);
2362 char *key = sdb_BuildFileName(directory, keyPrefix,
2363 "key", key_version);
2364 CK_RV error = CKR_OK;
2365 int inUpdate;
2366 PRUint32 accessOps;
2367
2368 if (certdb)
2369 *certdb = NULL;
2370 if (keydb)
2371 *keydb = NULL;
2372 *newInit = 0;
2373
2374 #ifdef SQLITE_UNSAFE_THREADS
2375 if (sqlite_lock == NULL) {
2376 sqlite_lock = PR_NewLock();
2377 if (sqlite_lock == NULL) {
2378 error = CKR_HOST_MEMORY;
2379 goto loser;
2380 }
2381 }
2382 #endif
2383
2384 /* how long does it take to test for a non-existant file in our working
2385 * directory? Allows us to test if we may be on a network file system */
2386 accessOps = 1;
2387 {
2388 char *env;
2389 env = PR_GetEnvSecure("NSS_SDB_USE_CACHE");
2390 /* If the environment variable is undefined or set to yes or no,
2391 * sdb_init() will ignore the value of accessOps, and we can skip the
2392 * measuring.*/
2393 if (env && PORT_Strcasecmp(env, "no") != 0 &&
2394 PORT_Strcasecmp(env, "yes") != 0) {
2395 accessOps = sdb_measureAccess(directory);
2396 }
2397 }
2398
2399 /*
2400 * open the cert data base
2401 */
2402 if (certdb) {
2403 /* initialize Certificate database */
2404 error = sdb_init(cert, "nssPublic", SDB_CERT, &inUpdate,
2405 newInit, flags, accessOps, certdb);
2406 if (error != CKR_OK) {
2407 goto loser;
2408 }
2409 }
2410
2411 /*
2412 * open the key data base:
2413 * NOTE:if we want to implement a single database, we open
2414 * the same database file as the certificate here.
2415 *
2416 * cert an key db's have different tables, so they will not
2417 * conflict.
2418 */
2419 if (keydb) {
2420 /* initialize the Key database */
2421 error = sdb_init(key, "nssPrivate", SDB_KEY, &inUpdate,
2422 newInit, flags, accessOps, keydb);
2423 if (error != CKR_OK) {
2424 goto loser;
2425 }
2426 }
2427
2428 loser:
2429 if (cert) {
2430 sqlite3_free(cert);
2431 }
2432 if (key) {
2433 sqlite3_free(key);
2434 }
2435
2436 if (error != CKR_OK) {
2437 /* currently redundant, but could be necessary if more code is added
2438 * just before loser */
2439 if (keydb && *keydb) {
2440 sdb_Close(*keydb);
2441 }
2442 if (certdb && *certdb) {
2443 sdb_Close(*certdb);
2444 }
2445 }
2446
2447 return error;
2448 }
2449
2450 CK_RV
s_shutdown()2451 s_shutdown()
2452 {
2453 #ifdef SQLITE_UNSAFE_THREADS
2454 if (sqlite_lock) {
2455 PR_DestroyLock(sqlite_lock);
2456 sqlite_lock = NULL;
2457 }
2458 #endif
2459 return CKR_OK;
2460 }
2461