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
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)