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

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

Issue 12197027: Merge NSS_3_14_2_RTM. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/nss/
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* This Source Code Form is subject to the terms of the Mozilla Public 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 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/. */ 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 /* 4 /*
5 * This file implements PKCS 11 on top of our existing security modules 5 * This file implements PKCS 11 on top of our existing security modules
6 * 6 *
7 * For more information about PKCS 11 See PKCS 11 Token Inteface Standard. 7 * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
8 * This implementation has two slots: 8 * This implementation has two slots:
9 * slot 1 is our generic crypto support. It does not require login. 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. 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 11 * It can also support Private Key ops for imported Private keys. It does
12 * not have any token storage. 12 * not have any token storage.
13 * slot 2 is our private key support. It requires a login before use. It 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 14 * can store Private Keys and Certs as token objects. Currently only private
15 * keys and their associated Certificates are saved on the token. 15 * keys and their associated Certificates are saved on the token.
16 * 16 *
17 * In this implementation, session objects are only visible to the session 17 * In this implementation, session objects are only visible to the session
18 * that created or generated them. 18 * that created or generated them.
19 */ 19 */
20 20
21 #include "sdb.h" 21 #include "sdb.h"
22 #include "pkcs11t.h" 22 #include "pkcs11t.h"
23 #include "seccomon.h" 23 #include "seccomon.h"
24 #include <sqlite3.h> 24 #include <sqlite3.h>
25 #include "prthread.h" 25 #include "prthread.h"
26 #include "prio.h" 26 #include "prio.h"
27 #include "stdio.h" 27 #include <stdio.h>
28 #include "secport.h" 28 #include "secport.h"
29 #include "prmon.h" 29 #include "prmon.h"
30 #include "prenv.h" 30 #include "prenv.h"
31 #include "prprf.h"
31 #include "prsystem.h" /* for PR_GetDirectorySeparator() */ 32 #include "prsystem.h" /* for PR_GetDirectorySeparator() */
32 #include "sys/stat.h" 33 #include <sys/stat.h>
33 #if defined (_WIN32) 34 #if defined(_WIN32)
34 #include <io.h> 35 #include <io.h>
36 #include <windows.h>
37 #elif defined(XP_UNIX)
38 #include <unistd.h>
35 #endif 39 #endif
36 40
37 #ifdef SQLITE_UNSAFE_THREADS 41 #ifdef SQLITE_UNSAFE_THREADS
38 #include "prlock.h" 42 #include "prlock.h"
39 /* 43 /*
40 * SQLite can be compiled to be thread safe or not. 44 * SQLite can be compiled to be thread safe or not.
41 * turn on SQLITE_UNSAFE_THREADS if the OS does not support 45 * turn on SQLITE_UNSAFE_THREADS if the OS does not support
42 * a thread safe version of sqlite. 46 * a thread safe version of sqlite.
43 */ 47 */
44 static PRLock *sqlite_lock = NULL; 48 static PRLock *sqlite_lock = NULL;
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 return 1; 184 return 1;
181 } 185 }
182 /* err == SQLITE_BUSY, Dont' retry forever in this case */ 186 /* err == SQLITE_BUSY, Dont' retry forever in this case */
183 if (++(*count) >= SDB_MAX_BUSY_RETRIES) { 187 if (++(*count) >= SDB_MAX_BUSY_RETRIES) {
184 return 1; 188 return 1;
185 } 189 }
186 return 0; 190 return 0;
187 } 191 }
188 192
189 /* 193 /*
190 * 194 * find out where sqlite stores the temp tables. We do this by replicating
191 * strdup limited to 'n' bytes. (Note: len of file is assumed to be >= len) 195 * the logic from sqlite.
192 *
193 * We don't have a PORT_ version of this function,
194 * I suspect it's only normally available in glib,
195 */ 196 */
197 #if defined(_WIN32)
196 static char * 198 static char *
197 sdb_strndup(const char *file, int len) 199 sdb_getFallbackTempDir(void)
198 { 200 {
199 char *result = PORT_Alloc(len+1); 201 /* sqlite uses sqlite3_temp_directory if it is not NULL. We don't have
202 * access to sqlite3_temp_directory because it is not exported from
203 * sqlite3.dll. Assume sqlite3_win32_set_directory isn't called and
204 * sqlite3_temp_directory is NULL.
205 */
206 char path[MAX_PATH];
207 DWORD rv;
208 size_t len;
200 209
201 if (result == NULL) { 210 rv = GetTempPathA(MAX_PATH, path);
202 » return result; 211 if (rv > MAX_PATH || rv == 0)
203 } 212 return NULL;
213 len = strlen(path);
214 if (len == 0)
215 return NULL;
216 /* The returned string ends with a backslash, for example, "C:\TEMP\". */
217 if (path[len - 1] == '\\')
218 path[len - 1] = '\0';
219 return PORT_Strdup(path);
220 }
221 #elif defined(XP_UNIX)
222 static char *
223 sdb_getFallbackTempDir(void)
224 {
225 const char *azDirs[] = {
226 NULL,
227 NULL,
228 "/var/tmp",
229 "/usr/tmp",
230 "/tmp",
231 NULL /* List terminator */
232 };
233 unsigned int i;
234 struct stat buf;
235 const char *zDir = NULL;
204 236
205 PORT_Memcpy(result, file, len); 237 azDirs[0] = sqlite3_temp_directory;
206 result[len] = 0; 238 azDirs[1] = getenv("TMPDIR");
207 return result;
208 }
209 239
210 /* 240 for (i = 0; i < PR_ARRAY_SIZE(azDirs); i++) {
211 * call back from sqlite3_exec("Pragma database_list"). Looks for the 241 zDir = azDirs[i];
212 * temp directory, then return the file the temp directory is stored 242 if (zDir == NULL) continue;
213 * at. */ 243 if (stat(zDir, &buf)) continue;
214 static int 244 if (!S_ISDIR(buf.st_mode)) continue;
215 sdb_getTempDirCallback(void *arg, int columnCount, char **cval, char **cname) 245 if (access(zDir, 07)) continue;
216 { 246 break;
217 int i;
218 int found = 0;
219 char *file = NULL;
220 char *end, *dir;
221 char dirsep;
222
223 /* we've already found the temp directory, don't look at any more records*/
224 if (*(char **)arg) {
225 » return SQLITE_OK;
226 } 247 }
227 248
228 /* look at the columns to see if this record is the temp database, 249 if (zDir == NULL)
229 * and does it say where it is stored */ 250 return NULL;
230 for (i=0; i < columnCount; i++) { 251 return PORT_Strdup(zDir);
231 » if (PORT_Strcmp(cname[i],"name") == 0) { 252 }
232 » if (PORT_Strcmp(cval[i], "temp") == 0) { 253 #else
233 » » found++; 254 #error "sdb_getFallbackTempDir not implemented"
234 » » continue; 255 #endif
235 » }
236 » }
237 » if (PORT_Strcmp(cname[i],"file") == 0) {
238 » if (cval[i] && (*cval[i] != 0)) {
239 » » file = cval[i];
240 » }
241 » }
242 }
243 256
244 /* if we couldn't find it, ask for the next record */ 257 #ifndef SQLITE_FCNTL_TEMPFILENAME
245 if (!found || !file) { 258 /* SQLITE_FCNTL_TEMPFILENAME was added in SQLite 3.7.15 */
246 » return SQLITE_OK; 259 #define SQLITE_FCNTL_TEMPFILENAME 16
247 } 260 #endif
248 261
249 /* drop of the database file name and just return the directory */
250 dirsep = PR_GetDirectorySeparator();
251 end = PORT_Strrchr(file, dirsep);
252 if (!end) {
253 return SQLITE_OK;
254 }
255 dir = sdb_strndup(file, end-file);
256
257 *(char **)arg = dir;
258 return SQLITE_OK;
259 }
260
261 /*
262 * find out where sqlite stores the temp tables. We do this by creating
263 * a temp table, then looking for the database name that sqlite3 creates.
264 */
265 static char * 262 static char *
266 sdb_getTempDir(sqlite3 *sqlDB) 263 sdb_getTempDir(sqlite3 *sqlDB)
267 { 264 {
268 char *tempDir = NULL; 265 int sqlrv;
269 int sqlerr; 266 char *result = NULL;
267 char *tempName = NULL;
268 char *foundSeparator = NULL;
270 269
271 /* create a temporary table */ 270 /* Obtain temporary filename in sqlite's directory for temporary tables */
272 sqlerr = sqlite3_exec(sqlDB, "CREATE TEMPORARY TABLE myTemp (id)", 271 sqlrv = sqlite3_file_control(sqlDB, 0, SQLITE_FCNTL_TEMPFILENAME,
273 » » » NULL, 0, NULL); 272 » » » » (void*)&tempName);
274 if (sqlerr != SQLITE_OK) { 273 if (sqlrv == SQLITE_NOTFOUND) {
274 » /* SQLITE_FCNTL_TEMPFILENAME not implemented because we are using
275 » * an older SQLite. */
276 » return sdb_getFallbackTempDir();
277 }
278 if (sqlrv != SQLITE_OK) {
275 return NULL; 279 return NULL;
276 } 280 }
277 /* look for through the database list for the temp directory */
278 sqlerr = sqlite3_exec(sqlDB, "PRAGMA database_list",
279 sdb_getTempDirCallback, &tempDir, NULL);
280 281
281 /* drop the temp table we created */ 282 /* We'll extract the temporary directory from tempName */
282 sqlite3_exec(sqlDB, "DROP TABLE myTemp", NULL, 0, NULL); 283 foundSeparator = PORT_Strrchr(tempName, PR_GetDirectorySeparator());
284 if (foundSeparator) {
285 » /* We shorten the temp filename string to contain only
286 » * the directory name (including the trailing separator).
287 » * We know the byte after the foundSeparator position is
288 » * safe to use, in the shortest scenario it contains the
289 » * end-of-string byte.
290 » * By keeping the separator at the found position, it will
291 » * even work if tempDir consists of the separator, only.
292 » * (In this case the toplevel directory will be used for
293 » * access speed testing). */
294 » ++foundSeparator;
295 » *foundSeparator = 0;
283 296
284 if (sqlerr != SQLITE_OK) { 297 » /* Now we copy the directory name for our caller */
285 » return NULL; 298 » result = PORT_Strdup(tempName);
286 } 299 }
287 return tempDir; 300
301 sqlite3_free(tempName);
302 return result;
288 } 303 }
289 304
290
291 /* 305 /*
292 * Map SQL_LITE errors to PKCS #11 errors as best we can. 306 * Map SQL_LITE errors to PKCS #11 errors as best we can.
293 */ 307 */
294 static CK_RV 308 static CK_RV
295 sdb_mapSQLError(sdbDataType type, int sqlerr) 309 sdb_mapSQLError(sdbDataType type, int sqlerr)
296 { 310 {
297 switch (sqlerr) { 311 switch (sqlerr) {
298 /* good matches */ 312 /* good matches */
299 case SQLITE_OK: 313 case SQLITE_OK:
300 case SQLITE_DONE: 314 case SQLITE_DONE:
(...skipping 18 matching lines...) Expand all
319 } 333 }
320 return CKR_GENERAL_ERROR; 334 return CKR_GENERAL_ERROR;
321 } 335 }
322 336
323 337
324 /* 338 /*
325 * build up database name from a directory, prefix, name, version and flags. 339 * build up database name from a directory, prefix, name, version and flags.
326 */ 340 */
327 static char *sdb_BuildFileName(const char * directory, 341 static char *sdb_BuildFileName(const char * directory,
328 const char *prefix, const char *type, 342 const char *prefix, const char *type,
329 » » » int version, int flags) 343 » » » int version)
330 { 344 {
331 char *dbname = NULL; 345 char *dbname = NULL;
332 /* build the full dbname */ 346 /* build the full dbname */
333 dbname = sqlite3_mprintf("%s/%s%s%d.db",directory, prefix, type, version); 347 dbname = sqlite3_mprintf("%s%c%s%s%d.db", directory,
348 » » » (int)(unsigned char)PR_GetDirectorySeparator(),
349 » » » prefix, type, version);
334 return dbname; 350 return dbname;
335 } 351 }
336 352
337 353
338 /* 354 /*
339 * find out how expensive the access system call is for non-existant files 355 * find out how expensive the access system call is for non-existant files
340 * in the given directory. Return the number of operations done in 33 ms. 356 * in the given directory. Return the number of operations done in 33 ms.
341 */ 357 */
342 static PRUint32 358 static PRUint32
343 sdb_measureAccess(const char *directory) 359 sdb_measureAccess(const char *directory)
344 { 360 {
345 PRUint32 i; 361 PRUint32 i;
346 PRIntervalTime time; 362 PRIntervalTime time;
347 PRIntervalTime delta; 363 PRIntervalTime delta;
348 PRIntervalTime duration = PR_MillisecondsToInterval(33); 364 PRIntervalTime duration = PR_MillisecondsToInterval(33);
365 const char *doesntExistName = "_dOeSnotExist_.db";
366 char *temp, *tempStartOfFilename;
367 size_t maxTempLen, maxFileNameLen, directoryLength;
349 368
350 /* no directory, just return one */ 369 /* no directory, just return one */
351 if (directory == NULL) { 370 if (directory == NULL) {
352 return 1; 371 return 1;
353 } 372 }
354 373
374 /* our calculation assumes time is a 4 bytes == 32 bit integer */
375 PORT_Assert(sizeof(time) == 4);
376
377 directoryLength = strlen(directory);
378
379 maxTempLen = directoryLength + strlen(doesntExistName)
380 + 1 /* potential additional separator char */
381 + 11 /* max chars for 32 bit int plus potential sign */
382 + 1; /* zero terminator */
383
384 temp = PORT_Alloc(maxTempLen);
385 if (!temp) {
386 return 1;
387 }
388
389 /* We'll copy directory into temp just once, then ensure it ends
390 * with the directory separator, then remember the position after
391 * the separator, and calculate the number of remaining bytes. */
392
393 strcpy(temp, directory);
394 if (directory[directoryLength - 1] != PR_GetDirectorySeparator()) {
395 temp[directoryLength++] = PR_GetDirectorySeparator();
396 }
397 tempStartOfFilename = temp + directoryLength;
398 maxFileNameLen = maxTempLen - directoryLength;
399
355 /* measure number of Access operations that can be done in 33 milliseconds 400 /* measure number of Access operations that can be done in 33 milliseconds
356 * (1/30'th of a second), or 10000 operations, which ever comes first. 401 * (1/30'th of a second), or 10000 operations, which ever comes first.
357 */ 402 */
358 time = PR_IntervalNow(); 403 time = PR_IntervalNow();
359 for (i=0; i < 10000u; i++) { 404 for (i=0; i < 10000u; i++) {
360 char *temp;
361 PRIntervalTime next; 405 PRIntervalTime next;
362 406
363 temp = sdb_BuildFileName(directory,"","._dOeSnotExist_", time+i, 0); 407 » /* We'll use the variable part first in the filename string, just in
408 » * case it's longer than assumed, so if anything gets cut off, it
409 » * will be cut off from the constant part.
410 » * This code assumes the directory name at the beginning of
411 » * temp remains unchanged during our loop. */
412 PR_snprintf(tempStartOfFilename, maxFileNameLen,
413 » » ".%lu%s", (PRUint32)(time+i), doesntExistName);
364 PR_Access(temp,PR_ACCESS_EXISTS); 414 PR_Access(temp,PR_ACCESS_EXISTS);
365 sqlite3_free(temp);
366 next = PR_IntervalNow(); 415 next = PR_IntervalNow();
367 delta = next - time; 416 delta = next - time;
368 if (delta >= duration) 417 if (delta >= duration)
369 break; 418 break;
370 } 419 }
371 420
421 PORT_Free(temp);
422
372 /* always return 1 or greater */ 423 /* always return 1 or greater */
373 return i ? i : 1u; 424 return i ? i : 1u;
374 } 425 }
375 426
376 /* 427 /*
377 * some file sytems are very slow to run sqlite3 on, particularly if the 428 * some file sytems are very slow to run sqlite3 on, particularly if the
378 * access count is pretty high. On these filesystems is faster to create 429 * access count is pretty high. On these filesystems is faster to create
379 * a temporary database on the local filesystem and access that. This 430 * a temporary database on the local filesystem and access that. This
380 * code uses a temporary table to create that cache. Temp tables are 431 * code uses a temporary table to create that cache. Temp tables are
381 * automatically cleared when the database handle it was created on 432 * automatically cleared when the database handle it was created on
(...skipping 1547 matching lines...) Expand 10 before | Expand all | Expand 10 after
1929 } 1980 }
1930 1981
1931 1982
1932 /* sdbopen */ 1983 /* sdbopen */
1933 CK_RV 1984 CK_RV
1934 s_open(const char *directory, const char *certPrefix, const char *keyPrefix, 1985 s_open(const char *directory, const char *certPrefix, const char *keyPrefix,
1935 int cert_version, int key_version, int flags, 1986 int cert_version, int key_version, int flags,
1936 SDB **certdb, SDB **keydb, int *newInit) 1987 SDB **certdb, SDB **keydb, int *newInit)
1937 { 1988 {
1938 char *cert = sdb_BuildFileName(directory, certPrefix, 1989 char *cert = sdb_BuildFileName(directory, certPrefix,
1939 » » » » "cert", cert_version, flags); 1990 » » » » "cert", cert_version);
1940 char *key = sdb_BuildFileName(directory, keyPrefix, 1991 char *key = sdb_BuildFileName(directory, keyPrefix,
1941 » » » » "key", key_version, flags); 1992 » » » » "key", key_version);
1942 CK_RV error = CKR_OK; 1993 CK_RV error = CKR_OK;
1943 int inUpdate; 1994 int inUpdate;
1944 PRUint32 accessOps; 1995 PRUint32 accessOps;
1945 1996
1946 if (certdb) 1997 if (certdb)
1947 *certdb = NULL; 1998 *certdb = NULL;
1948 if (keydb) 1999 if (keydb)
1949 *keydb = NULL; 2000 *keydb = NULL;
1950 *newInit = 0; 2001 *newInit = 0;
1951 2002
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2019 s_shutdown() 2070 s_shutdown()
2020 { 2071 {
2021 #ifdef SQLITE_UNSAFE_THREADS 2072 #ifdef SQLITE_UNSAFE_THREADS
2022 if (sqlite_lock) { 2073 if (sqlite_lock) {
2023 PR_DestroyLock(sqlite_lock); 2074 PR_DestroyLock(sqlite_lock);
2024 sqlite_lock = NULL; 2075 sqlite_lock = NULL;
2025 } 2076 }
2026 #endif 2077 #endif
2027 return CKR_OK; 2078 return CKR_OK;
2028 } 2079 }
OLDNEW
« no previous file with comments | « mozilla/security/nss/lib/softoken/pkcs11c.c ('k') | mozilla/security/nss/lib/softoken/softkver.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698