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