Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(217)

Side by Side Diff: nss/lib/softoken/sdb.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « nss/lib/softoken/sdb.h ('k') | nss/lib/softoken/sftkdb.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
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;
49
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
56
57 typedef enum {
58 SDB_CERT = 1,
59 SDB_KEY = 2
60 } sdbDataType;
61
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
86
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 */
99
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 };
116
117 typedef struct SDBPrivateStr SDBPrivate;
118
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 };
158
159 static int known_attributes_size= sizeof(known_attributes)/
160 sizeof(known_attributes[0]);
161
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
171
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 }
192
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;
209
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;
236
237 azDirs[0] = sqlite3_temp_directory;
238 azDirs[1] = PR_GetEnvSecure("TMPDIR");
239
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 }
248
249 if (zDir == NULL)
250 return NULL;
251 return PORT_Strdup(zDir);
252 }
253 #else
254 #error "sdb_getFallbackTempDir not implemented"
255 #endif
256
257 #ifndef SQLITE_FCNTL_TEMPFILENAME
258 /* SQLITE_FCNTL_TEMPFILENAME was added in SQLite 3.7.15 */
259 #define SQLITE_FCNTL_TEMPFILENAME 16
260 #endif
261
262 static char *
263 sdb_getTempDir(sqlite3 *sqlDB)
264 {
265 int sqlrv;
266 char *result = NULL;
267 char *tempName = NULL;
268 char *foundSeparator = NULL;
269
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 }
281
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;
296
297 /* Now we copy the directory name for our caller */
298 result = PORT_Strdup(tempName);
299 }
300
301 sqlite3_free(tempName);
302 return result;
303 }
304
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 }
336
337
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 }
352
353
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;
368
369 /* no directory, just return one */
370 if (directory == NULL) {
371 return 1;
372 }
373
374 /* our calculation assumes time is a 4 bytes == 32 bit integer */
375 PORT_Assert(sizeof(time) == 4);
376
377 directoryLength = strlen(directory);
378
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 */
383
384 temp = PORT_Alloc(maxTempLen);
385 if (!temp) {
386 return 1;
387 }
388
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. */
392
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;
399
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;
406
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 }
420
421 PORT_Free(temp);
422
423 /* always return 1 or greater */
424 return i ? i : 1u;
425 }
426
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)";
444
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;
451
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 }
488
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;
499
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 }
513
514
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 }
524
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;
562
563 PR_EnterMonitor(sdb_p->dbMon);
564
565 if (table) {
566 *table = sdb_p->table;
567 }
568
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 }
576
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 }
590
591 *sqlDB = sdb_p->sqlReadDB;
592
593 /* leave holding the lock. only one thread can actually use a given
594 * database connection at once */
595
596 return CKR_OK;
597 }
598
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 }
609
610
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 }
628
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 }
637
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;
646
647 /* open a new database */
648 sqlerr = sdb_openDB(sdb_p->sqlDBName, &newDB, SDB_RDONLY);
649 if (sqlerr != SQLITE_OK) {
650 return sqlerr;
651 }
652
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);
664
665 /* close the old one */
666 sqlite3_close(*sqlDB);
667
668 *sqlDB = newDB;
669 return SQLITE_OK;
670 }
671
672 struct SDBFindStr {
673 sqlite3 *sqlDB;
674 sqlite3_stmt *findstmt;
675 };
676
677
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 unsigned int i;
693
694 LOCK_SQLITE()
695 *find = NULL;
696 error = sdb_openDBLocal(sdb_p, &sqlDB, &table);
697 if (error != CKR_OK) {
698 goto loser;
699 }
700
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 }
709
710 if (findStr == NULL) {
711 error = CKR_HOST_MEMORY;
712 goto loser;
713 }
714
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);
749
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 }
761
762
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;
771
772 *count = 0;
773
774 if (arraySize == 0) {
775 return CKR_OK;
776 }
777 LOCK_SQLITE()
778
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));
791
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()
798
799 return sdb_mapSQLError(sdb_p->type, sqlerr);
800 }
801
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;
809
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);
819
820 UNLOCK_SQLITE()
821 return sdb_mapSQLError(sdb_p->type, sqlerr);
822 }
823
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 unsigned int i;
840
841
842 /* open a new db if necessary */
843 error = sdb_openDBLocal(sdb_p, &sqlDB, &table);
844 if (error != CKR_OK) {
845 goto loser;
846 }
847
848 for (i=0; i < count; i++) {
849 getStr = sqlite3_mprintf("a%x", template[i].type);
850
851 if (getStr == NULL) {
852 error = CKR_HOST_MEMORY;
853 goto loser;
854 }
855
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 }
863
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; }
872
873 sqlerr = sqlite3_bind_int(stmt, 1, object_id);
874 if (sqlerr != SQLITE_OK) { goto loser; }
875
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 unsigned int blobSize;
883 const char *blobData;
884
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 }
915
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 }
924
925 if (stmt) {
926 sqlite3_reset(stmt);
927 sqlite3_finalize(stmt);
928 }
929
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 }
936
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;
942
943 if (count == 0) {
944 return CKR_OK;
945 }
946
947 LOCK_SQLITE()
948 crv = sdb_GetAttributeValueNoLock(sdb, object_id, template, count);
949 UNLOCK_SQLITE()
950 return crv;
951 }
952
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 unsigned int i;
967
968 if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
969 return CKR_TOKEN_WRITE_PROTECTED;
970 }
971
972 if (count == 0) {
973 return CKR_OK;
974 }
975
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;
991
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;
1000 }
1001 error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
1002 if (error != CKR_OK) {
1003 goto loser;
1004 }
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);
1014 }
1015 if (sqlerr != SQLITE_OK) goto loser;
1016 }
1017 sqlerr = sqlite3_bind_int(stmt, i+1, object_id);
1018 if (sqlerr != SQLITE_OK) goto loser;
1019
1020 do {
1021 sqlerr = sqlite3_step(stmt);
1022 if (sqlerr == SQLITE_BUSY) {
1023 PR_Sleep(SDB_BUSY_RETRY_TIME);
1024 }
1025 } while (!sdb_done(sqlerr,&retry));
1026
1027 loser:
1028 if (newStr) {
1029 sqlite3_free(newStr);
1030 }
1031 if (error == CKR_OK) {
1032 error = sdb_mapSQLError(sdb_p->type, sqlerr);
1033 }
1034
1035 if (stmt) {
1036 sqlite3_reset(stmt);
1037 sqlite3_finalize(stmt);
1038 }
1039
1040 if (sqlDB) {
1041 sdb_closeDBLocal(sdb_p, sqlDB) ;
1042 }
1043
1044 UNLOCK_SQLITE()
1045 return error;
1046 }
1047
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)
1053 {
1054 CK_RV crv;
1055 CK_ATTRIBUTE template = { CKA_LABEL, NULL, 0 };
1056
1057 crv = sdb_GetAttributeValueNoLock(sdb,candidate,&template, 1);
1058 if (crv == CKR_OBJECT_HANDLE_INVALID) {
1059 return PR_FALSE;
1060 }
1061 return PR_TRUE;
1062 }
1063
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)
1070 {
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();
1080
1081 next_obj = (CK_OBJECT_HANDLE)(time & 0x3fffffffL);
1082 }
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;
1091 }
1092 /* make sure we aren't already using */
1093 if (!sdb_objectExists(sdb, candidate)) {
1094 /* this one is free */
1095 return candidate;
1096 }
1097 }
1098
1099 /* no handle is free, fail */
1100 return CK_INVALID_HANDLE;
1101 }
1102
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)
1107 {
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 unsigned int i;
1119
1120 if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
1121 return CKR_TOKEN_WRITE_PROTECTED;
1122 }
1123
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);
1130 }
1131 if (this_object == CK_INVALID_HANDLE) {
1132 UNLOCK_SQLITE();
1133 return CKR_HOST_MEMORY;
1134 }
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;
1145 }
1146 newStr = NULL;
1147 if ((columnStr == NULL) || (valueStr == NULL)) {
1148 if (columnStr) {
1149 sqlite3_free(columnStr);
1150 }
1151 if (valueStr) {
1152 sqlite3_free(valueStr);
1153 }
1154 UNLOCK_SQLITE()
1155 return CKR_HOST_MEMORY;
1156 }
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;
1163 }
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);
1175 }
1176 if (sqlerr != SQLITE_OK) goto loser;
1177 }
1178
1179 do {
1180 sqlerr = sqlite3_step(stmt);
1181 if (sqlerr == SQLITE_BUSY) {
1182 PR_Sleep(SDB_BUSY_RETRY_TIME);
1183 }
1184 } while (!sdb_done(sqlerr,&retry));
1185
1186 loser:
1187 if (newStr) {
1188 sqlite3_free(newStr);
1189 }
1190 if (error == CKR_OK) {
1191 error = sdb_mapSQLError(sdb_p->type, sqlerr);
1192 }
1193
1194 if (stmt) {
1195 sqlite3_reset(stmt);
1196 sqlite3_finalize(stmt);
1197 }
1198
1199 if (sqlDB) {
1200 sdb_closeDBLocal(sdb_p, sqlDB) ;
1201 }
1202 UNLOCK_SQLITE()
1203
1204 return error;
1205 }
1206
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)
1210 {
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;
1218
1219 if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
1220 return CKR_TOKEN_WRITE_PROTECTED;
1221 }
1222
1223 LOCK_SQLITE()
1224 error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
1225 if (error != CKR_OK) {
1226 goto loser;
1227 }
1228 newStr = sqlite3_mprintf(DESTROY_CMD, sdb_p->table);
1229 if (newStr == NULL) {
1230 error = CKR_HOST_MEMORY;
1231 goto loser;
1232 }
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;
1238
1239 do {
1240 sqlerr = sqlite3_step(stmt);
1241 if (sqlerr == SQLITE_BUSY) {
1242 PR_Sleep(SDB_BUSY_RETRY_TIME);
1243 }
1244 } while (!sdb_done(sqlerr,&retry));
1245
1246 loser:
1247 if (error == CKR_OK) {
1248 error = sdb_mapSQLError(sdb_p->type, sqlerr);
1249 }
1250
1251 if (stmt) {
1252 sqlite3_reset(stmt);
1253 sqlite3_finalize(stmt);
1254 }
1255
1256 if (sqlDB) {
1257 sdb_closeDBLocal(sdb_p, sqlDB) ;
1258 }
1259
1260 UNLOCK_SQLITE()
1261 return error;
1262 }
1263
1264 static const char BEGIN_CMD[] = "BEGIN IMMEDIATE TRANSACTION;";
1265 /*
1266 * start a transaction.
1267 *
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)
1274 {
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;
1281
1282
1283 if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
1284 return CKR_TOKEN_WRITE_PROTECTED;
1285 }
1286
1287
1288 LOCK_SQLITE()
1289
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;
1294 }
1295
1296 sqlerr =sqlite3_prepare_v2(sqlDB, BEGIN_CMD, -1, &stmt, NULL);
1297
1298 do {
1299 sqlerr = sqlite3_step(stmt);
1300 if (sqlerr == SQLITE_BUSY) {
1301 PR_Sleep(SDB_BUSY_RETRY_TIME);
1302 }
1303 } while (!sdb_done(sqlerr,&retry));
1304
1305 if (stmt) {
1306 sqlite3_reset(stmt);
1307 sqlite3_finalize(stmt);
1308 }
1309
1310 loser:
1311 error = sdb_mapSQLError(sdb_p->type, sqlerr);
1312
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);
1329 }
1330 }
1331
1332 UNLOCK_SQLITE()
1333 return error;
1334 }
1335
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)
1344 {
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;
1351
1352
1353 if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
1354 return CKR_TOKEN_WRITE_PROTECTED;
1355 }
1356
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 */
1363 }
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 */
1368 }
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);
1374
1375 sqlerr =sqlite3_prepare_v2(sqlDB, cmd, -1, &stmt, NULL);
1376
1377 do {
1378 sqlerr = sqlite3_step(stmt);
1379 if (sqlerr == SQLITE_BUSY) {
1380 PR_Sleep(SDB_BUSY_RETRY_TIME);
1381 }
1382 } while (!sdb_done(sqlerr,&retry));
1383
1384 /* Pending BEGIN TRANSACTIONS Can move forward at this point. */
1385
1386 if (stmt) {
1387 sqlite3_reset(stmt);
1388 sqlite3_finalize(stmt);
1389 }
1390
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);
1396 }
1397
1398 error = sdb_mapSQLError(sdb_p->type, sqlerr);
1399
1400 /* We just finished a transaction.
1401 * Free the database, and remove it from the list */
1402 sqlite3_close(sqlDB);
1403
1404 return error;
1405 }
1406
1407 static const char COMMIT_CMD[] = "COMMIT TRANSACTION;";
1408 CK_RV
1409 sdb_Commit(SDB *sdb)
1410 {
1411 CK_RV crv;
1412 LOCK_SQLITE()
1413 crv = sdb_complete(sdb,COMMIT_CMD);
1414 UNLOCK_SQLITE()
1415 return crv;
1416 }
1417
1418 static const char ROLLBACK_CMD[] = "ROLLBACK TRANSACTION;";
1419 CK_RV
1420 sdb_Abort(SDB *sdb)
1421 {
1422 CK_RV crv;
1423 LOCK_SQLITE()
1424 crv = sdb_complete(sdb,ROLLBACK_CMD);
1425 UNLOCK_SQLITE()
1426 return crv;
1427 }
1428
1429 static int tableExists(sqlite3 *sqlDB, const char *tableName);
1430
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)
1434 {
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;
1442
1443 LOCK_SQLITE()
1444 error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
1445 if (error != CKR_OK) {
1446 goto loser;
1447 }
1448
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;
1459 }
1460 sqlerr = sqlite3_prepare_v2(sqlDB, GET_PW_CMD, -1, &stmt, NULL);
1461 }
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);
1468 }
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;
1476 }
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;
1485 }
1486 blobData = sqlite3_column_blob(stmt, 2);
1487 PORT_Memcpy(item2->data,blobData, item2->len);
1488 }
1489 found = 1;
1490 }
1491 } while (!sdb_done(sqlerr,&retry));
1492
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;
1499 }
1500 }
1501
1502 if (stmt) {
1503 sqlite3_reset(stmt);
1504 sqlite3_finalize(stmt);
1505 }
1506
1507 if (sqlDB) {
1508 sdb_closeDBLocal(sdb_p, sqlDB) ;
1509 }
1510 UNLOCK_SQLITE()
1511
1512 return error;
1513 }
1514
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)
1524 {
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;
1532
1533 if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
1534 return CKR_TOKEN_WRITE_PROTECTED;
1535 }
1536
1537 LOCK_SQLITE()
1538 error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
1539 if (error != CKR_OK) {
1540 goto loser;
1541 }
1542
1543 if (!tableExists(sqlDB, "metaData")) {
1544 sqlerr = sqlite3_exec(sqlDB, PW_CREATE_TABLE_CMD, NULL, 0, NULL);
1545 if (sqlerr != SQLITE_OK) goto loser;
1546 }
1547 if (item2 == NULL) {
1548 cmd = MD_CREATE_CMD;
1549 }
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;
1560 }
1561
1562 do {
1563 sqlerr = sqlite3_step(stmt);
1564 if (sqlerr == SQLITE_BUSY) {
1565 PR_Sleep(SDB_BUSY_RETRY_TIME);
1566 }
1567 } while (!sdb_done(sqlerr,&retry));
1568
1569 loser:
1570 /* fix up the error if necessary */
1571 if (error == CKR_OK) {
1572 error = sdb_mapSQLError(sdb_p->type, sqlerr);
1573 }
1574
1575 if (stmt) {
1576 sqlite3_reset(stmt);
1577 sqlite3_finalize(stmt);
1578 }
1579
1580 if (sqlDB) {
1581 sdb_closeDBLocal(sdb_p, sqlDB) ;
1582 }
1583 UNLOCK_SQLITE()
1584
1585 return error;
1586 }
1587
1588 static const char RESET_CMD[] = "DROP TABLE IF EXISTS %s;";
1589 CK_RV
1590 sdb_Reset(SDB *sdb)
1591 {
1592 SDBPrivate *sdb_p = sdb->private;
1593 sqlite3 *sqlDB = NULL;
1594 char *newStr;
1595 int sqlerr = SQLITE_OK;
1596 CK_RV error = CKR_OK;
1597
1598 /* only Key databases can be reset */
1599 if (sdb_p->type != SDB_KEY) {
1600 return CKR_OBJECT_HANDLE_INVALID;
1601 }
1602
1603 LOCK_SQLITE()
1604 error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
1605 if (error != CKR_OK) {
1606 goto loser;
1607 }
1608
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;
1614 }
1615 sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
1616 sqlite3_free(newStr);
1617
1618 if (sqlerr != SQLITE_OK) goto loser;
1619
1620 /* delete the password entry table */
1621 sqlerr = sqlite3_exec(sqlDB, "DROP TABLE IF EXISTS metaData;",
1622 NULL, 0, NULL);
1623
1624 loser:
1625 /* fix up the error if necessary */
1626 if (error == CKR_OK) {
1627 error = sdb_mapSQLError(sdb_p->type, sqlerr);
1628 }
1629
1630 if (sqlDB) {
1631 sdb_closeDBLocal(sdb_p, sqlDB) ;
1632 }
1633
1634 UNLOCK_SQLITE()
1635 return error;
1636 }
1637
1638
1639 CK_RV
1640 sdb_Close(SDB *sdb)
1641 {
1642 SDBPrivate *sdb_p = sdb->private;
1643 int sqlerr = SQLITE_OK;
1644 sdbDataType type = sdb_p->type;
1645
1646 sqlerr = sqlite3_close(sdb_p->sqlReadDB);
1647 PORT_Free(sdb_p->sqlDBName);
1648 if (sdb_p->cacheTable) {
1649 sqlite3_free(sdb_p->cacheTable);
1650 }
1651 if (sdb_p->dbMon) {
1652 PR_DestroyMonitor(sdb_p->dbMon);
1653 }
1654 free(sdb_p);
1655 free(sdb);
1656 return sdb_mapSQLError(type, sqlerr);
1657 }
1658
1659
1660 /*
1661 * functions to support open
1662 */
1663
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)
1667 {
1668 char * cmd = sqlite3_mprintf(CHECK_TABLE_CMD, tableName);
1669 int sqlerr = SQLITE_OK;
1670
1671 if (cmd == NULL) {
1672 return 0;
1673 }
1674
1675 sqlerr = sqlite3_exec(sqlDB, cmd, NULL, 0, 0);
1676 sqlite3_free(cmd);
1677
1678 return (sqlerr == SQLITE_OK) ? 1 : 0;
1679 }
1680
1681 void sdb_SetForkState(PRBool forked)
1682 {
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 */
1687 }
1688
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
1695 CK_RV
1696 sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate,
1697 int *newInit, int flags, PRUint32 accessOps, SDB **pSdb)
1698 {
1699 int i;
1700 char *initStr = NULL;
1701 char *newStr;
1702 int inTransaction = 0;
1703 SDB *sdb = NULL;
1704 SDBPrivate *sdb_p = NULL;
1705 sqlite3 *sqlDB = NULL;
1706 int sqlerr = SQLITE_OK;
1707 CK_RV error = CKR_OK;
1708 char *cacheTable = NULL;
1709 PRIntervalTime now = 0;
1710 char *env;
1711 PRBool enableCache = PR_FALSE;
1712 PRBool create;
1713
1714 *pSdb = NULL;
1715 *inUpdate = 0;
1716
1717 /* sqlite3 doesn't have a flag to specify that we want to
1718 * open the database read only. If the db doesn't exist,
1719 * sqlite3 will always create it.
1720 */
1721 LOCK_SQLITE();
1722 create = (PR_Access(dbname, PR_ACCESS_EXISTS) != PR_SUCCESS);
1723 if ((flags == SDB_RDONLY) && create) {
1724 error = sdb_mapSQLError(type, SQLITE_CANTOPEN);
1725 goto loser;
1726 }
1727 sqlerr = sdb_openDB(dbname, &sqlDB, flags);
1728 if (sqlerr != SQLITE_OK) {
1729 error = sdb_mapSQLError(type, sqlerr);
1730 goto loser;
1731 }
1732 /* sql created the file, but it doesn't set appropriate modes for
1733 * a database */
1734 if (create) {
1735 /* NO NSPR call for this? :( */
1736 chmod (dbname, 0600);
1737 }
1738
1739 if (flags != SDB_RDONLY) {
1740 sqlerr = sqlite3_exec(sqlDB, BEGIN_CMD, NULL, 0, NULL);
1741 if (sqlerr != SQLITE_OK) {
1742 error = sdb_mapSQLError(type, sqlerr);
1743 goto loser;
1744 }
1745 inTransaction = 1;
1746 }
1747 if (!tableExists(sqlDB,table)) {
1748 *newInit = 1;
1749 if (flags != SDB_CREATE) {
1750 error = sdb_mapSQLError(type, SQLITE_CANTOPEN);
1751 goto loser;
1752 }
1753 initStr = sqlite3_mprintf("");
1754 for (i=0; initStr && i < known_attributes_size; i++) {
1755 newStr = sqlite3_mprintf("%s, a%x",initStr, known_attributes[i]);
1756 sqlite3_free(initStr);
1757 initStr = newStr;
1758 }
1759 if (initStr == NULL) {
1760 error = CKR_HOST_MEMORY;
1761 goto loser;
1762 }
1763
1764 newStr = sqlite3_mprintf(INIT_CMD, table, initStr);
1765 sqlite3_free(initStr);
1766 if (newStr == NULL) {
1767 error = CKR_HOST_MEMORY;
1768 goto loser;
1769 }
1770 sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
1771 sqlite3_free(newStr);
1772 if (sqlerr != SQLITE_OK) {
1773 error = sdb_mapSQLError(type, sqlerr);
1774 goto loser;
1775 }
1776
1777 newStr = sqlite3_mprintf(CREATE_ISSUER_INDEX_CMD, table);
1778 if (newStr == NULL) {
1779 error = CKR_HOST_MEMORY;
1780 goto loser;
1781 }
1782 sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
1783 sqlite3_free(newStr);
1784 if (sqlerr != SQLITE_OK) {
1785 error = sdb_mapSQLError(type, sqlerr);
1786 goto loser;
1787 }
1788
1789 newStr = sqlite3_mprintf(CREATE_SUBJECT_INDEX_CMD, table);
1790 if (newStr == NULL) {
1791 error = CKR_HOST_MEMORY;
1792 goto loser;
1793 }
1794 sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
1795 sqlite3_free(newStr);
1796 if (sqlerr != SQLITE_OK) {
1797 error = sdb_mapSQLError(type, sqlerr);
1798 goto loser;
1799 }
1800
1801 newStr = sqlite3_mprintf(CREATE_LABEL_INDEX_CMD, table);
1802 if (newStr == NULL) {
1803 error = CKR_HOST_MEMORY;
1804 goto loser;
1805 }
1806 sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
1807 sqlite3_free(newStr);
1808 if (sqlerr != SQLITE_OK) {
1809 error = sdb_mapSQLError(type, sqlerr);
1810 goto loser;
1811 }
1812
1813 newStr = sqlite3_mprintf(CREATE_ID_INDEX_CMD, table);
1814 if (newStr == NULL) {
1815 error = CKR_HOST_MEMORY;
1816 goto loser;
1817 }
1818 sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
1819 sqlite3_free(newStr);
1820 if (sqlerr != SQLITE_OK) {
1821 error = sdb_mapSQLError(type, sqlerr);
1822 goto loser;
1823 }
1824 }
1825 /*
1826 * detect the case where we have created the database, but have
1827 * not yet updated it.
1828 *
1829 * We only check the Key database because only the key database has
1830 * a metaData table. The metaData table is created when a password
1831 * is set, or in the case of update, when a password is supplied.
1832 * If no key database exists, then the update would have happened immediatel y
1833 * on noticing that the cert database didn't exist (see newInit set above).
1834 */
1835 if (type == SDB_KEY && !tableExists(sqlDB, "metaData")) {
1836 *newInit = 1;
1837 }
1838
1839 /* access to network filesystems are significantly slower than local ones
1840 * for database operations. In those cases we need to create a cached copy
1841 * of the database in a temporary location on the local disk. SQLITE
1842 * already provides a way to create a temporary table and initialize it,
1843 * so we use it for the cache (see sdb_buildCache for how it's done).*/
1844
1845 /*
1846 * we decide whether or not to use the cache based on the following input.
1847 *
1848 * NSS_SDB_USE_CACHE environment variable is non-existant or set to
1849 * anything other than "no" or "yes" ("auto", for instance).
1850 * This is the normal case. NSS will measure the performance of access
1851 * to the temp database versus the access to the users passed in
1852 * database location. If the temp database location is "significantly"
1853 * faster we will use the cache.
1854 *
1855 * NSS_SDB_USE_CACHE environment variable is set to "no": cache will not
1856 * be used.
1857 *
1858 * NSS_SDB_USE_CACHE environment variable is set to "yes": cache will
1859 * always be used.
1860 *
1861 * It is expected that most applications would use the "auto" selection,
1862 * the environment variable is primarily to simplify testing, and to
1863 * correct potential corner cases where */
1864
1865 env = PR_GetEnvSecure("NSS_SDB_USE_CACHE");
1866
1867 if (env && PORT_Strcasecmp(env,"no") == 0) {
1868 enableCache = PR_FALSE;
1869 } else if (env && PORT_Strcasecmp(env,"yes") == 0) {
1870 enableCache = PR_TRUE;
1871 } else {
1872 char *tempDir = NULL;
1873 PRUint32 tempOps = 0;
1874 /*
1875 * Use PR_Access to determine how expensive it
1876 * is to check for the existance of a local file compared to the same
1877 * check in the temp directory. If the temp directory is faster, cache
1878 * the database there. */
1879 tempDir = sdb_getTempDir(sqlDB);
1880 if (tempDir) {
1881 tempOps = sdb_measureAccess(tempDir);
1882 PORT_Free(tempDir);
1883
1884 /* There is a cost to continually copying the database.
1885 * Account for that cost with the arbitrary factor of 10 */
1886 enableCache = (PRBool)(tempOps > accessOps * 10);
1887 }
1888 }
1889
1890 if (enableCache) {
1891 /* try to set the temp store to memory.*/
1892 sqlite3_exec(sqlDB, "PRAGMA temp_store=MEMORY", NULL, 0, NULL);
1893 /* Failure to set the temp store to memory is not fatal,
1894 * ignore the error */
1895
1896 cacheTable = sqlite3_mprintf("%sCache",table);
1897 if (cacheTable == NULL) {
1898 error = CKR_HOST_MEMORY;
1899 goto loser;
1900 }
1901 /* build the cache table */
1902 error = sdb_buildCache(sqlDB, type, cacheTable, table);
1903 if (error != CKR_OK) {
1904 goto loser;
1905 }
1906 /* initialize the last cache build time */
1907 now = PR_IntervalNow();
1908 }
1909
1910 sdb = (SDB *) malloc(sizeof(SDB));
1911 sdb_p = (SDBPrivate *) malloc(sizeof(SDBPrivate));
1912
1913 /* invariant fields */
1914 sdb_p->sqlDBName = PORT_Strdup(dbname);
1915 sdb_p->type = type;
1916 sdb_p->table = table;
1917 sdb_p->cacheTable = cacheTable;
1918 sdb_p->lastUpdateTime = now;
1919 /* set the cache delay time. This is how long we will wait before we
1920 * decide the existing cache is stale. Currently set to 10 sec */
1921 sdb_p->updateInterval = PR_SecondsToInterval(10);
1922 sdb_p->dbMon = PR_NewMonitor();
1923 /* these fields are protected by the lock */
1924 sdb_p->sqlXactDB = NULL;
1925 sdb_p->sqlXactThread = NULL;
1926 sdb->private = sdb_p;
1927 sdb->version = 0;
1928 sdb->sdb_flags = flags | SDB_HAS_META;
1929 sdb->app_private = NULL;
1930 sdb->sdb_FindObjectsInit = sdb_FindObjectsInit;
1931 sdb->sdb_FindObjects = sdb_FindObjects;
1932 sdb->sdb_FindObjectsFinal = sdb_FindObjectsFinal;
1933 sdb->sdb_GetAttributeValue = sdb_GetAttributeValue;
1934 sdb->sdb_SetAttributeValue = sdb_SetAttributeValue;
1935 sdb->sdb_CreateObject = sdb_CreateObject;
1936 sdb->sdb_DestroyObject = sdb_DestroyObject;
1937 sdb->sdb_GetMetaData = sdb_GetMetaData;
1938 sdb->sdb_PutMetaData = sdb_PutMetaData;
1939 sdb->sdb_Begin = sdb_Begin;
1940 sdb->sdb_Commit = sdb_Commit;
1941 sdb->sdb_Abort = sdb_Abort;
1942 sdb->sdb_Reset = sdb_Reset;
1943 sdb->sdb_Close = sdb_Close;
1944 sdb->sdb_SetForkState = sdb_SetForkState;
1945
1946 if (inTransaction) {
1947 sqlerr = sqlite3_exec(sqlDB, COMMIT_CMD, NULL, 0, NULL);
1948 if (sqlerr != SQLITE_OK) {
1949 error = sdb_mapSQLError(sdb_p->type, sqlerr);
1950 goto loser;
1951 }
1952 inTransaction = 0;
1953 }
1954
1955 sdb_p->sqlReadDB = sqlDB;
1956
1957 *pSdb = sdb;
1958 UNLOCK_SQLITE();
1959 return CKR_OK;
1960
1961 loser:
1962 /* lots of stuff to do */
1963 if (inTransaction) {
1964 sqlite3_exec(sqlDB, ROLLBACK_CMD, NULL, 0, NULL);
1965 }
1966 if (sdb) {
1967 free(sdb);
1968 }
1969 if (sdb_p) {
1970 free(sdb_p);
1971 }
1972 if (sqlDB) {
1973 sqlite3_close(sqlDB);
1974 }
1975 UNLOCK_SQLITE();
1976 return error;
1977
1978 }
1979
1980
1981 /* sdbopen */
1982 CK_RV
1983 s_open(const char *directory, const char *certPrefix, const char *keyPrefix,
1984 int cert_version, int key_version, int flags,
1985 SDB **certdb, SDB **keydb, int *newInit)
1986 {
1987 char *cert = sdb_BuildFileName(directory, certPrefix,
1988 "cert", cert_version);
1989 char *key = sdb_BuildFileName(directory, keyPrefix,
1990 "key", key_version);
1991 CK_RV error = CKR_OK;
1992 int inUpdate;
1993 PRUint32 accessOps;
1994
1995 if (certdb)
1996 *certdb = NULL;
1997 if (keydb)
1998 *keydb = NULL;
1999 *newInit = 0;
2000
2001 #ifdef SQLITE_UNSAFE_THREADS
2002 if (sqlite_lock == NULL) {
2003 sqlite_lock = PR_NewLock();
2004 if (sqlite_lock == NULL) {
2005 error = CKR_HOST_MEMORY;
2006 goto loser;
2007 }
2008 }
2009 #endif
2010
2011 /* how long does it take to test for a non-existant file in our working
2012 * directory? Allows us to test if we may be on a network file system */
2013 accessOps = 1;
2014 {
2015 char *env;
2016 env = PR_GetEnvSecure("NSS_SDB_USE_CACHE");
2017 /* If the environment variable is set to yes or no, sdb_init() will
2018 * ignore the value of accessOps, and we can skip the measuring.*/
2019 if (!env || ((PORT_Strcasecmp(env, "no") != 0) &&
2020 (PORT_Strcasecmp(env, "yes") != 0))){
2021 accessOps = sdb_measureAccess(directory);
2022 }
2023 }
2024
2025 /*
2026 * open the cert data base
2027 */
2028 if (certdb) {
2029 /* initialize Certificate database */
2030 error = sdb_init(cert, "nssPublic", SDB_CERT, &inUpdate,
2031 newInit, flags, accessOps, certdb);
2032 if (error != CKR_OK) {
2033 goto loser;
2034 }
2035 }
2036
2037 /*
2038 * open the key data base:
2039 * NOTE:if we want to implement a single database, we open
2040 * the same database file as the certificate here.
2041 *
2042 * cert an key db's have different tables, so they will not
2043 * conflict.
2044 */
2045 if (keydb) {
2046 /* initialize the Key database */
2047 error = sdb_init(key, "nssPrivate", SDB_KEY, &inUpdate,
2048 newInit, flags, accessOps, keydb);
2049 if (error != CKR_OK) {
2050 goto loser;
2051 }
2052 }
2053
2054
2055 loser:
2056 if (cert) {
2057 sqlite3_free(cert);
2058 }
2059 if (key) {
2060 sqlite3_free(key);
2061 }
2062
2063 if (error != CKR_OK) {
2064 /* currently redundant, but could be necessary if more code is added
2065 * just before loser */
2066 if (keydb && *keydb) {
2067 sdb_Close(*keydb);
2068 }
2069 if (certdb && *certdb) {
2070 sdb_Close(*certdb);
2071 }
2072 }
2073
2074 return error;
2075 }
2076
2077 CK_RV
2078 s_shutdown()
2079 {
2080 #ifdef SQLITE_UNSAFE_THREADS
2081 if (sqlite_lock) {
2082 PR_DestroyLock(sqlite_lock);
2083 sqlite_lock = NULL;
2084 }
2085 #endif
2086 return CKR_OK;
2087 }
OLDNEW
« no previous file with comments | « nss/lib/softoken/sdb.h ('k') | nss/lib/softoken/sftkdb.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698