OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |