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