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

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 */
245 if (!found || !file) {
246 return SQLITE_OK;
247 }
248
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 * 257 static char *
266 sdb_getTempDir(sqlite3 *sqlDB) 258 sdb_getTempDir(sqlite3 *sqlDB)
267 { 259 {
268 char *tempDir = NULL; 260 #ifndef SQLITE_FCNTL_TEMPFILENAME
269 int sqlerr; 261 return sdb_getFallbackTempDir();
262 #else
263 int sqlrv;
264 char *result = NULL;
265 char *tempName = NULL;
266 char *foundSeparator = NULL;
270 267
271 /* create a temporary table */ 268 /* Obtain temporary filename in sqlite's directory for temporary tables */
272 sqlerr = sqlite3_exec(sqlDB, "CREATE TEMPORARY TABLE myTemp (id)", 269 sqlrv = sqlite3_file_control(sqlDB, 0, SQLITE_FCNTL_TEMPFILENAME,
273 » » » NULL, 0, NULL); 270 » » » » (void*)&tempName);
274 if (sqlerr != SQLITE_OK) { 271 if (sqlrv == SQLITE_NOTFOUND) {
272 » /* SQLITE_FCNTL_TEMPFILENAME not implemented because we are using
273 » * an older SQLite. */
274 » return sdb_getFallbackTempDir();
275 }
276 if (sqlrv != SQLITE_OK) {
275 return NULL; 277 return NULL;
276 } 278 }
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 279
281 /* drop the temp table we created */ 280 /* We'll extract the temporary directory from tempName */
282 sqlite3_exec(sqlDB, "DROP TABLE myTemp", NULL, 0, NULL); 281 foundSeparator = PORT_Strrchr(tempName, PR_GetDirectorySeparator());
282 if (foundSeparator) {
283 » /* We shorten the temp filename string to contain only
284 » * the directory name (including the trailing separator).
285 » * We know the byte after the foundSeparator position is
286 » * safe to use, in the shortest scenario it contains the
287 » * end-of-string byte.
288 » * By keeping the separator at the found position, it will
289 » * even work if tempDir consists of the separator, only.
290 » * (In this case the toplevel directory will be used for
291 » * access speed testing). */
292 » ++foundSeparator;
293 » *foundSeparator = 0;
283 294
284 if (sqlerr != SQLITE_OK) { 295 » /* Now we copy the directory name for our caller */
285 » return NULL; 296 » result = PORT_Strdup(tempName);
286 } 297 }
287 return tempDir; 298
299 sqlite3_free(tempName);
300 return result;
301 #endif
288 } 302 }
289 303
290
291 /* 304 /*
292 * Map SQL_LITE errors to PKCS #11 errors as best we can. 305 * Map SQL_LITE errors to PKCS #11 errors as best we can.
293 */ 306 */
294 static CK_RV 307 static CK_RV
295 sdb_mapSQLError(sdbDataType type, int sqlerr) 308 sdb_mapSQLError(sdbDataType type, int sqlerr)
296 { 309 {
297 switch (sqlerr) { 310 switch (sqlerr) {
298 /* good matches */ 311 /* good matches */
299 case SQLITE_OK: 312 case SQLITE_OK:
300 case SQLITE_DONE: 313 case SQLITE_DONE:
(...skipping 18 matching lines...) Expand all
319 } 332 }
320 return CKR_GENERAL_ERROR; 333 return CKR_GENERAL_ERROR;
321 } 334 }
322 335
323 336
324 /* 337 /*
325 * build up database name from a directory, prefix, name, version and flags. 338 * build up database name from a directory, prefix, name, version and flags.
326 */ 339 */
327 static char *sdb_BuildFileName(const char * directory, 340 static char *sdb_BuildFileName(const char * directory,
328 const char *prefix, const char *type, 341 const char *prefix, const char *type,
329 » » » int version, int flags) 342 » » » int version)
330 { 343 {
331 char *dbname = NULL; 344 char *dbname = NULL;
332 /* build the full dbname */ 345 /* build the full dbname */
333 dbname = sqlite3_mprintf("%s/%s%s%d.db",directory, prefix, type, version); 346 dbname = sqlite3_mprintf("%s%c%s%s%d.db", directory,
347 » » » (int)(unsigned char)PR_GetDirectorySeparator(),
348 » » » prefix, type, version);
334 return dbname; 349 return dbname;
335 } 350 }
336 351
337 352
338 /* 353 /*
339 * find out how expensive the access system call is for non-existant files 354 * 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. 355 * in the given directory. Return the number of operations done in 33 ms.
341 */ 356 */
342 static PRUint32 357 static PRUint32
343 sdb_measureAccess(const char *directory) 358 sdb_measureAccess(const char *directory)
344 { 359 {
345 PRUint32 i; 360 PRUint32 i;
346 PRIntervalTime time; 361 PRIntervalTime time;
347 PRIntervalTime delta; 362 PRIntervalTime delta;
348 PRIntervalTime duration = PR_MillisecondsToInterval(33); 363 PRIntervalTime duration = PR_MillisecondsToInterval(33);
364 const char *doesntExistName = "_dOeSnotExist_.db";
365 char *temp, *tempStartOfFilename;
366 size_t maxTempLen, maxFileNameLen, directoryLength;
349 367
350 /* no directory, just return one */ 368 /* no directory, just return one */
351 if (directory == NULL) { 369 if (directory == NULL) {
352 return 1; 370 return 1;
353 } 371 }
354 372
373 /* our calculation assumes time is a 4 bytes == 32 bit integer */
374 PORT_Assert(sizeof(time) == 4);
375
376 directoryLength = strlen(directory);
377
378 maxTempLen = directoryLength + strlen(doesntExistName)
379 + 1 /* potential additional separator char */
380 + 11 /* max chars for 32 bit int plus potential sign */
381 + 1; /* zero terminator */
382
383 temp = PORT_Alloc(maxTempLen);
384 if (!temp) {
385 return 1;
386 }
387
388 /* We'll copy directory into temp just once, then ensure it ends
389 * with the directory separator, then remember the position after
390 * the separator, and calculate the number of remaining bytes. */
391
392 strcpy(temp, directory);
393 if (directory[directoryLength - 1] != PR_GetDirectorySeparator()) {
394 temp[directoryLength++] = PR_GetDirectorySeparator();
395 }
396 tempStartOfFilename = temp + directoryLength;
397 maxFileNameLen = maxTempLen - directoryLength;
398
355 /* measure number of Access operations that can be done in 33 milliseconds 399 /* 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. 400 * (1/30'th of a second), or 10000 operations, which ever comes first.
357 */ 401 */
358 time = PR_IntervalNow(); 402 time = PR_IntervalNow();
359 for (i=0; i < 10000u; i++) { 403 for (i=0; i < 10000u; i++) {
360 char *temp;
361 PRIntervalTime next; 404 PRIntervalTime next;
362 405
363 temp = sdb_BuildFileName(directory,"","._dOeSnotExist_", time+i, 0); 406 » /* We'll use the variable part first in the filename string, just in
407 » * case it's longer than assumed, so if anything gets cut off, it
408 » * will be cut off from the constant part.
409 » * This code assumes the directory name at the beginning of
410 » * temp remains unchanged during our loop. */
411 PR_snprintf(tempStartOfFilename, maxFileNameLen,
412 » » ".%lu%s", (PRUint32)(time+i), doesntExistName);
364 PR_Access(temp,PR_ACCESS_EXISTS); 413 PR_Access(temp,PR_ACCESS_EXISTS);
365 sqlite3_free(temp);
366 next = PR_IntervalNow(); 414 next = PR_IntervalNow();
367 delta = next - time; 415 delta = next - time;
368 if (delta >= duration) 416 if (delta >= duration)
369 break; 417 break;
370 } 418 }
371 419
420 PORT_Free(temp);
421
372 /* always return 1 or greater */ 422 /* always return 1 or greater */
373 return i ? i : 1u; 423 return i ? i : 1u;
374 } 424 }
375 425
376 /* 426 /*
377 * some file sytems are very slow to run sqlite3 on, particularly if the 427 * 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 428 * access count is pretty high. On these filesystems is faster to create
379 * a temporary database on the local filesystem and access that. This 429 * a temporary database on the local filesystem and access that. This
380 * code uses a temporary table to create that cache. Temp tables are 430 * code uses a temporary table to create that cache. Temp tables are
381 * automatically cleared when the database handle it was created on 431 * automatically cleared when the database handle it was created on
(...skipping 1547 matching lines...) Expand 10 before | Expand all | Expand 10 after
1929 } 1979 }
1930 1980
1931 1981
1932 /* sdbopen */ 1982 /* sdbopen */
1933 CK_RV 1983 CK_RV
1934 s_open(const char *directory, const char *certPrefix, const char *keyPrefix, 1984 s_open(const char *directory, const char *certPrefix, const char *keyPrefix,
1935 int cert_version, int key_version, int flags, 1985 int cert_version, int key_version, int flags,
1936 SDB **certdb, SDB **keydb, int *newInit) 1986 SDB **certdb, SDB **keydb, int *newInit)
1937 { 1987 {
1938 char *cert = sdb_BuildFileName(directory, certPrefix, 1988 char *cert = sdb_BuildFileName(directory, certPrefix,
1939 » » » » "cert", cert_version, flags); 1989 » » » » "cert", cert_version);
1940 char *key = sdb_BuildFileName(directory, keyPrefix, 1990 char *key = sdb_BuildFileName(directory, keyPrefix,
1941 » » » » "key", key_version, flags); 1991 » » » » "key", key_version);
1942 CK_RV error = CKR_OK; 1992 CK_RV error = CKR_OK;
1943 int inUpdate; 1993 int inUpdate;
1944 PRUint32 accessOps; 1994 PRUint32 accessOps;
1945 1995
1946 if (certdb) 1996 if (certdb)
1947 *certdb = NULL; 1997 *certdb = NULL;
1948 if (keydb) 1998 if (keydb)
1949 *keydb = NULL; 1999 *keydb = NULL;
1950 *newInit = 0; 2000 *newInit = 0;
1951 2001
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2019 s_shutdown() 2069 s_shutdown()
2020 { 2070 {
2021 #ifdef SQLITE_UNSAFE_THREADS 2071 #ifdef SQLITE_UNSAFE_THREADS
2022 if (sqlite_lock) { 2072 if (sqlite_lock) {
2023 PR_DestroyLock(sqlite_lock); 2073 PR_DestroyLock(sqlite_lock);
2024 sqlite_lock = NULL; 2074 sqlite_lock = NULL;
2025 } 2075 }
2026 #endif 2076 #endif
2027 return CKR_OK; 2077 return CKR_OK;
2028 } 2078 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698