Mercurial > trustbridge > nss-cmake-static
comparison nss/lib/softoken/lgglue.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e5118fa0cb1 |
---|---|
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 * The following code handles the storage of PKCS 11 modules used by the | |
6 * NSS. This file is written to abstract away how the modules are | |
7 * stored so we can deside that later. | |
8 */ | |
9 #include "sftkdb.h" | |
10 #include "sftkdbti.h" | |
11 #include "sdb.h" | |
12 #include "prsystem.h" | |
13 #include "prprf.h" | |
14 #include "prenv.h" | |
15 #include "lgglue.h" | |
16 #include "secerr.h" | |
17 #include "softoken.h" | |
18 | |
19 static LGOpenFunc legacy_glue_open = NULL; | |
20 static LGReadSecmodFunc legacy_glue_readSecmod = NULL; | |
21 static LGReleaseSecmodFunc legacy_glue_releaseSecmod = NULL; | |
22 static LGDeleteSecmodFunc legacy_glue_deleteSecmod = NULL; | |
23 static LGAddSecmodFunc legacy_glue_addSecmod = NULL; | |
24 static LGShutdownFunc legacy_glue_shutdown = NULL; | |
25 | |
26 #ifndef NSS_STATIC | |
27 /* | |
28 * The following 3 functions duplicate the work done by bl_LoadLibrary. | |
29 * We should make bl_LoadLibrary a global and replace the call to | |
30 * sftkdb_LoadLibrary(const char *libname) with it. | |
31 */ | |
32 #ifdef XP_UNIX | |
33 #include <unistd.h> | |
34 #define LG_MAX_LINKS 20 | |
35 static char * | |
36 sftkdb_resolvePath(const char *orig) | |
37 { | |
38 int count = 0; | |
39 int len =0; | |
40 int ret = -1; | |
41 char *resolved = NULL; | |
42 char *source = NULL; | |
43 | |
44 len = 1025; /* MAX PATH +1*/ | |
45 if (strlen(orig)+1 > len) { | |
46 /* PATH TOO LONG */ | |
47 return NULL; | |
48 } | |
49 resolved = PORT_Alloc(len); | |
50 if (!resolved) { | |
51 return NULL; | |
52 } | |
53 source = PORT_Alloc(len); | |
54 if (!source) { | |
55 goto loser; | |
56 } | |
57 PORT_Strcpy(source, orig); | |
58 /* Walk down all the links */ | |
59 while ( count++ < LG_MAX_LINKS) { | |
60 char *tmp; | |
61 /* swap our previous sorce out with resolved */ | |
62 /* read it */ | |
63 ret = readlink(source, resolved, len-1); | |
64 if (ret < 0) { | |
65 break; | |
66 } | |
67 resolved[ret] = 0; | |
68 tmp = source; source = resolved; resolved = tmp; | |
69 } | |
70 if (count > 1) { | |
71 ret = 0; | |
72 } | |
73 loser: | |
74 if (resolved) { | |
75 PORT_Free(resolved); | |
76 } | |
77 if (ret < 0) { | |
78 if (source) { | |
79 PORT_Free(source); | |
80 source = NULL; | |
81 } | |
82 } | |
83 return source; | |
84 } | |
85 | |
86 #endif | |
87 | |
88 static PRLibrary * | |
89 sftkdb_LoadFromPath(const char *path, const char *libname) | |
90 { | |
91 char *c; | |
92 int pathLen, nameLen, fullPathLen; | |
93 char *fullPathName = NULL; | |
94 PRLibSpec libSpec; | |
95 PRLibrary *lib = NULL; | |
96 | |
97 | |
98 /* strip of our parent's library name */ | |
99 c = strrchr(path, PR_GetDirectorySeparator()); | |
100 if (!c) { | |
101 return NULL; /* invalid path */ | |
102 } | |
103 pathLen = (c-path)+1; | |
104 nameLen = strlen(libname); | |
105 fullPathLen = pathLen + nameLen +1; | |
106 fullPathName = (char *)PORT_Alloc(fullPathLen); | |
107 if (fullPathName == NULL) { | |
108 return NULL; /* memory allocation error */ | |
109 } | |
110 PORT_Memcpy(fullPathName, path, pathLen); | |
111 PORT_Memcpy(fullPathName+pathLen, libname, nameLen); | |
112 fullPathName[fullPathLen-1] = 0; | |
113 | |
114 libSpec.type = PR_LibSpec_Pathname; | |
115 libSpec.value.pathname = fullPathName; | |
116 lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); | |
117 PORT_Free(fullPathName); | |
118 return lib; | |
119 } | |
120 | |
121 | |
122 static PRLibrary * | |
123 sftkdb_LoadLibrary(const char *libname) | |
124 { | |
125 PRLibrary *lib = NULL; | |
126 PRFuncPtr fn_addr; | |
127 char *parentLibPath = NULL; | |
128 | |
129 fn_addr = (PRFuncPtr) &sftkdb_LoadLibrary; | |
130 parentLibPath = PR_GetLibraryFilePathname(SOFTOKEN_LIB_NAME, fn_addr); | |
131 | |
132 if (!parentLibPath) { | |
133 goto done; | |
134 } | |
135 | |
136 lib = sftkdb_LoadFromPath(parentLibPath, libname); | |
137 #ifdef XP_UNIX | |
138 /* handle symbolic link case */ | |
139 if (!lib) { | |
140 char *trueParentLibPath = sftkdb_resolvePath(parentLibPath); | |
141 if (!trueParentLibPath) { | |
142 goto done; | |
143 } | |
144 lib = sftkdb_LoadFromPath(trueParentLibPath, libname); | |
145 PORT_Free(trueParentLibPath); | |
146 } | |
147 #endif | |
148 | |
149 done: | |
150 if (parentLibPath) { | |
151 PORT_Free(parentLibPath); | |
152 } | |
153 | |
154 /* still couldn't load it, try the generic path */ | |
155 if (!lib) { | |
156 PRLibSpec libSpec; | |
157 libSpec.type = PR_LibSpec_Pathname; | |
158 libSpec.value.pathname = libname; | |
159 lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); | |
160 } | |
161 | |
162 return lib; | |
163 } | |
164 #endif /* STATIC LIBRARIES */ | |
165 | |
166 /* | |
167 * stub files for legacy db's to be able to encrypt and decrypt | |
168 * various keys and attributes. | |
169 */ | |
170 static SECStatus | |
171 sftkdb_encrypt_stub(PLArenaPool *arena, SDB *sdb, SECItem *plainText, | |
172 SECItem **cipherText) | |
173 { | |
174 SFTKDBHandle *handle = sdb->app_private; | |
175 SECStatus rv; | |
176 | |
177 if (handle == NULL) { | |
178 return SECFailure; | |
179 } | |
180 | |
181 /* if we aren't the key handle, try the other handle */ | |
182 if (handle->type != SFTK_KEYDB_TYPE) { | |
183 handle = handle->peerDB; | |
184 } | |
185 | |
186 /* not a key handle */ | |
187 if (handle == NULL || handle->passwordLock == NULL) { | |
188 return SECFailure; | |
189 } | |
190 | |
191 PZ_Lock(handle->passwordLock); | |
192 if (handle->passwordKey.data == NULL) { | |
193 PZ_Unlock(handle->passwordLock); | |
194 /* PORT_SetError */ | |
195 return SECFailure; | |
196 } | |
197 | |
198 rv = sftkdb_EncryptAttribute(arena, | |
199 handle->newKey?handle->newKey:&handle->passwordKey, | |
200 plainText, cipherText); | |
201 PZ_Unlock(handle->passwordLock); | |
202 | |
203 return rv; | |
204 } | |
205 | |
206 /* | |
207 * stub files for legacy db's to be able to encrypt and decrypt | |
208 * various keys and attributes. | |
209 */ | |
210 static SECStatus | |
211 sftkdb_decrypt_stub(SDB *sdb, SECItem *cipherText, SECItem **plainText) | |
212 { | |
213 SFTKDBHandle *handle = sdb->app_private; | |
214 SECStatus rv; | |
215 SECItem *oldKey = NULL; | |
216 | |
217 if (handle == NULL) { | |
218 return SECFailure; | |
219 } | |
220 | |
221 /* if we aren't th handle, try the other handle */ | |
222 oldKey = handle->oldKey; | |
223 if (handle->type != SFTK_KEYDB_TYPE) { | |
224 handle = handle->peerDB; | |
225 } | |
226 | |
227 /* not a key handle */ | |
228 if (handle == NULL || handle->passwordLock == NULL) { | |
229 return SECFailure; | |
230 } | |
231 | |
232 PZ_Lock(handle->passwordLock); | |
233 if (handle->passwordKey.data == NULL) { | |
234 PZ_Unlock(handle->passwordLock); | |
235 /* PORT_SetError */ | |
236 return SECFailure; | |
237 } | |
238 rv = sftkdb_DecryptAttribute( oldKey ? oldKey : &handle->passwordKey, | |
239 cipherText, plainText); | |
240 PZ_Unlock(handle->passwordLock); | |
241 | |
242 return rv; | |
243 } | |
244 | |
245 static const char *LEGACY_LIB_NAME = | |
246 SHLIB_PREFIX"nssdbm"SHLIB_VERSION"."SHLIB_SUFFIX; | |
247 /* | |
248 * 2 bools to tell us if we've check the legacy library successfully or | |
249 * not. Initialize on startup to false by the C BSS segment; | |
250 */ | |
251 static PRBool legacy_glue_libCheckFailed; /* set if we failed the check */ | |
252 static PRBool legacy_glue_libCheckSucceeded; /* set if we passed the check */ | |
253 static PRLibrary *legacy_glue_lib = NULL; | |
254 static SECStatus | |
255 sftkdbLoad_Legacy(PRBool isFIPS) | |
256 { | |
257 PRLibrary *lib = NULL; | |
258 LGSetCryptFunc setCryptFunction = NULL; | |
259 | |
260 if (legacy_glue_lib) { | |
261 /* this check is necessary because it's possible we loaded the | |
262 * legacydb to read secmod.db, which told us whether we were in | |
263 * FIPS mode or not. */ | |
264 if (isFIPS && !legacy_glue_libCheckSucceeded) { | |
265 if (legacy_glue_libCheckFailed || | |
266 !BLAPI_SHVerify(LEGACY_LIB_NAME,(PRFuncPtr)legacy_glue_open)) { | |
267 legacy_glue_libCheckFailed = PR_TRUE; | |
268 /* don't clobber legacy glue to avoid race. just let it | |
269 * get cleared in shutdown */ | |
270 return SECFailure; | |
271 } | |
272 legacy_glue_libCheckSucceeded = PR_TRUE; | |
273 } | |
274 return SECSuccess; | |
275 } | |
276 | |
277 #ifdef NSS_STATIC | |
278 #ifdef NSS_DISABLE_DBM | |
279 return SECFailure; | |
280 #else | |
281 lib = (PRLibrary *) 0x8; | |
282 | |
283 legacy_glue_open = legacy_Open; | |
284 legacy_glue_readSecmod = legacy_ReadSecmodDB; | |
285 legacy_glue_releaseSecmod = legacy_ReleaseSecmodDBData; | |
286 legacy_glue_deleteSecmod = legacy_DeleteSecmodDB; | |
287 legacy_glue_addSecmod = legacy_AddSecmodDB; | |
288 legacy_glue_shutdown = legacy_Shutdown; | |
289 setCryptFunction = legacy_SetCryptFunctions; | |
290 #endif | |
291 #else | |
292 lib = sftkdb_LoadLibrary(LEGACY_LIB_NAME); | |
293 if (lib == NULL) { | |
294 return SECFailure; | |
295 } | |
296 | |
297 legacy_glue_open = (LGOpenFunc)PR_FindFunctionSymbol(lib, "legacy_Open"); | |
298 legacy_glue_readSecmod = (LGReadSecmodFunc) PR_FindFunctionSymbol(lib, | |
299 "legacy_ReadSecmodDB"); | |
300 legacy_glue_releaseSecmod = (LGReleaseSecmodFunc) PR_FindFunctionSymbol(lib, | |
301 "legacy_ReleaseSecmodDBData"); | |
302 legacy_glue_deleteSecmod = (LGDeleteSecmodFunc) PR_FindFunctionSymbol(lib, | |
303 "legacy_DeleteSecmodDB"); | |
304 legacy_glue_addSecmod = (LGAddSecmodFunc)PR_FindFunctionSymbol(lib, | |
305 "legacy_AddSecmodDB"); | |
306 legacy_glue_shutdown = (LGShutdownFunc) PR_FindFunctionSymbol(lib, | |
307 "legacy_Shutdown"); | |
308 setCryptFunction = (LGSetCryptFunc) PR_FindFunctionSymbol(lib, | |
309 "legacy_SetCryptFunctions"); | |
310 | |
311 if (!legacy_glue_open || !legacy_glue_readSecmod || | |
312 !legacy_glue_releaseSecmod || !legacy_glue_deleteSecmod || | |
313 !legacy_glue_addSecmod || !setCryptFunction) { | |
314 PR_UnloadLibrary(lib); | |
315 return SECFailure; | |
316 } | |
317 #endif /* NSS_STATIC */ | |
318 | |
319 /* verify the loaded library if we are in FIPS mode */ | |
320 if (isFIPS) { | |
321 if (!BLAPI_SHVerify(LEGACY_LIB_NAME,(PRFuncPtr)legacy_glue_open)) { | |
322 #ifndef NSS_STATIC | |
323 PR_UnloadLibrary(lib); | |
324 #endif | |
325 return SECFailure; | |
326 } | |
327 legacy_glue_libCheckSucceeded = PR_TRUE; | |
328 } | |
329 | |
330 setCryptFunction(sftkdb_encrypt_stub,sftkdb_decrypt_stub); | |
331 legacy_glue_lib = lib; | |
332 return SECSuccess; | |
333 } | |
334 | |
335 CK_RV | |
336 sftkdbCall_open(const char *dir, const char *certPrefix, const char *keyPrefix, | |
337 int certVersion, int keyVersion, int flags, PRBool isFIPS, | |
338 SDB **certDB, SDB **keyDB) | |
339 { | |
340 SECStatus rv; | |
341 | |
342 rv = sftkdbLoad_Legacy(isFIPS); | |
343 if (rv != SECSuccess) { | |
344 return CKR_GENERAL_ERROR; | |
345 } | |
346 if (!legacy_glue_open) { | |
347 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | |
348 return SECFailure; | |
349 } | |
350 return (*legacy_glue_open)(dir, certPrefix, keyPrefix, | |
351 certVersion, keyVersion, | |
352 flags, certDB, keyDB); | |
353 } | |
354 | |
355 char ** | |
356 sftkdbCall_ReadSecmodDB(const char *appName, const char *filename, | |
357 const char *dbname, char *params, PRBool rw) | |
358 { | |
359 SECStatus rv; | |
360 | |
361 rv = sftkdbLoad_Legacy(PR_FALSE); | |
362 if (rv != SECSuccess) { | |
363 return NULL; | |
364 } | |
365 if (!legacy_glue_readSecmod) { | |
366 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | |
367 return NULL; | |
368 } | |
369 return (*legacy_glue_readSecmod)(appName, filename, dbname, params, rw); | |
370 } | |
371 | |
372 SECStatus | |
373 sftkdbCall_ReleaseSecmodDBData(const char *appName, | |
374 const char *filename, const char *dbname, | |
375 char **moduleSpecList, PRBool rw) | |
376 { | |
377 SECStatus rv; | |
378 | |
379 rv = sftkdbLoad_Legacy(PR_FALSE); | |
380 if (rv != SECSuccess) { | |
381 return rv; | |
382 } | |
383 if (!legacy_glue_releaseSecmod) { | |
384 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | |
385 return SECFailure; | |
386 } | |
387 return (*legacy_glue_releaseSecmod)(appName, filename, dbname, | |
388 moduleSpecList, rw); | |
389 } | |
390 | |
391 SECStatus | |
392 sftkdbCall_DeleteSecmodDB(const char *appName, | |
393 const char *filename, const char *dbname, | |
394 char *args, PRBool rw) | |
395 { | |
396 SECStatus rv; | |
397 | |
398 rv = sftkdbLoad_Legacy(PR_FALSE); | |
399 if (rv != SECSuccess) { | |
400 return rv; | |
401 } | |
402 if (!legacy_glue_deleteSecmod) { | |
403 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | |
404 return SECFailure; | |
405 } | |
406 return (*legacy_glue_deleteSecmod)(appName, filename, dbname, args, rw); | |
407 } | |
408 | |
409 SECStatus | |
410 sftkdbCall_AddSecmodDB(const char *appName, | |
411 const char *filename, const char *dbname, | |
412 char *module, PRBool rw) | |
413 { | |
414 SECStatus rv; | |
415 | |
416 rv = sftkdbLoad_Legacy(PR_FALSE); | |
417 if (rv != SECSuccess) { | |
418 return rv; | |
419 } | |
420 if (!legacy_glue_addSecmod) { | |
421 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | |
422 return SECFailure; | |
423 } | |
424 return (*legacy_glue_addSecmod)(appName, filename, dbname, module, rw); | |
425 } | |
426 | |
427 CK_RV | |
428 sftkdbCall_Shutdown(void) | |
429 { | |
430 CK_RV crv = CKR_OK; | |
431 char *disableUnload = NULL; | |
432 if (!legacy_glue_lib) { | |
433 return CKR_OK; | |
434 } | |
435 if (legacy_glue_shutdown) { | |
436 #ifdef NO_FORK_CHECK | |
437 PRBool parentForkedAfterC_Initialize = PR_FALSE; | |
438 #endif | |
439 crv = (*legacy_glue_shutdown)(parentForkedAfterC_Initialize); | |
440 } | |
441 #ifndef NSS_STATIC | |
442 disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD"); | |
443 if (!disableUnload) { | |
444 PR_UnloadLibrary(legacy_glue_lib); | |
445 } | |
446 #endif | |
447 legacy_glue_lib = NULL; | |
448 legacy_glue_open = NULL; | |
449 legacy_glue_readSecmod = NULL; | |
450 legacy_glue_releaseSecmod = NULL; | |
451 legacy_glue_deleteSecmod = NULL; | |
452 legacy_glue_addSecmod = NULL; | |
453 legacy_glue_libCheckFailed = PR_FALSE; | |
454 legacy_glue_libCheckSucceeded = PR_FALSE; | |
455 return crv; | |
456 } | |
457 | |
458 |