~ubuntu-branches/ubuntu/raring/nss/raring-security

« back to all changes in this revision

Viewing changes to mozilla/security/nss/lib/pk11wrap/pk11load.c

  • Committer: Bazaar Package Importer
  • Author(s): Chris Coulson
  • Date: 2010-03-25 13:46:06 UTC
  • mfrom: (1.1.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20100325134606-bl6liuok2w9l7snv
Tags: 3.12.6-0ubuntu1
* New upstream release 3.12.6 RTM (NSS_3_12_6_RTM)
  - fixes CVE-2009-3555 aka US-CERT VU#120541
* Adjust patches to changed upstream code base
  - update debian/patches/38_kbsd.patch
  - update debian/patches/38_mips64_build.patch
  - update debian/patches/85_security_load.patch
* Remove patches that are merged upstream
  - delete debian/patches/91_nonexec_stack.patch
  - update debian/patches/series
* Bump nspr dependency to 4.8
  - update debian/control
* Add new symbols for 3.12.6
  - update debian/libnss3-1d.symbols

Show diffs side-by-side

added added

removed removed

Lines of Context:
120
120
}
121
121
 
122
122
/*
 
123
 * Allow specification loading the same module more than once at init time.
 
124
 * This enables 2 things.
 
125
 *
 
126
 *    1) we can load additional databases by manipulating secmod.db/pkcs11.txt.
 
127
 *    2) we can handle the case where some library has already initialized NSS
 
128
 *    before the main application.
 
129
 *
 
130
 * oldModule is the module we have already initialized.
 
131
 * char *modulespec is the full module spec for the library we want to
 
132
 * initialize.
 
133
 */
 
134
static SECStatus
 
135
secmod_handleReload(SECMODModule *oldModule, SECMODModule *newModule)
 
136
{
 
137
    PK11SlotInfo *slot;
 
138
    char *modulespec;
 
139
    char *newModuleSpec;
 
140
    char **children;
 
141
    CK_SLOT_ID *ids;
 
142
    SECStatus rv;
 
143
    SECMODConfigList *conflist;
 
144
    int count = 0;
 
145
 
 
146
    /* first look for tokens= key words from the module spec */
 
147
    modulespec = newModule->libraryParams;
 
148
    newModuleSpec = secmod_ParseModuleSpecForTokens(PR_TRUE,
 
149
                                newModule->isFIPS, modulespec, &children, &ids);
 
150
    if (!newModuleSpec) {
 
151
        return SECFailure;
 
152
    }
 
153
 
 
154
    /* 
 
155
     * We are now trying to open a new slot on an already loaded module.
 
156
     * If that slot represents a cert/key database, we don't want to open
 
157
     * multiple copies of that same database. Unfortunately we understand
 
158
     * the softoken flags well enough to be able to do this, so we can only get
 
159
     * the list of already loaded databases if we are trying to open another
 
160
     * internal module. 
 
161
     */
 
162
    if (oldModule->internal) {
 
163
        conflist = secmod_GetConfigList(oldModule->isFIPS, 
 
164
                                        oldModule->libraryParams, &count);
 
165
    }
 
166
 
 
167
 
 
168
    /* don't open multiple of the same db */
 
169
    if (conflist && secmod_MatchConfigList(newModuleSpec, conflist, count)) { 
 
170
        rv = SECSuccess;
 
171
        goto loser;
 
172
    }
 
173
    slot = SECMOD_OpenNewSlot(oldModule, newModuleSpec);
 
174
    if (slot) {
 
175
        int newID;
 
176
        char **thisChild;
 
177
        CK_SLOT_ID *thisID;
 
178
        char *oldModuleSpec;
 
179
 
 
180
        if (secmod_IsInternalKeySlot(newModule)) {
 
181
            pk11_SetInternalKeySlot(slot);
 
182
        }
 
183
        newID = slot->slotID;
 
184
        PK11_FreeSlot(slot);
 
185
        for (thisChild=children, thisID=ids; thisChild && *thisChild; 
 
186
                                                thisChild++,thisID++) {
 
187
            if (conflist &&
 
188
                       secmod_MatchConfigList(*thisChild, conflist, count)) {
 
189
                *thisID = (CK_SLOT_ID) -1;
 
190
                continue;
 
191
            }
 
192
            slot = SECMOD_OpenNewSlot(oldModule, *thisChild);
 
193
            if (slot) {
 
194
                *thisID = slot->slotID;
 
195
                PK11_FreeSlot(slot);
 
196
            } else {
 
197
                *thisID = (CK_SLOT_ID) -1;
 
198
            }
 
199
        }
 
200
 
 
201
        /* update the old module initialization string in case we need to
 
202
         * shutdown and reinit the whole mess (this is rare, but can happen
 
203
         * when trying to stop smart card insertion/removal threads)... */
 
204
        oldModuleSpec = secmod_MkAppendTokensList(oldModule->arena, 
 
205
                oldModule->libraryParams, newModuleSpec, newID, 
 
206
                children, ids);
 
207
        if (oldModuleSpec) {
 
208
            oldModule->libraryParams = oldModuleSpec;
 
209
        }
 
210
        
 
211
        rv = SECSuccess;
 
212
    }
 
213
 
 
214
loser:
 
215
    secmod_FreeChildren(children, ids);
 
216
    PORT_Free(newModuleSpec);
 
217
    if (conflist) {
 
218
        secmod_FreeConfigList(conflist, count);
 
219
    }
 
220
    return rv;
 
221
}
 
222
 
 
223
/*
123
224
 * collect the steps we need to initialize a module in a single function
124
225
 */
125
226
SECStatus
126
 
secmod_ModuleInit(SECMODModule *mod, PRBool* alreadyLoaded)
 
227
secmod_ModuleInit(SECMODModule *mod, SECMODModule **reload, 
 
228
                  PRBool* alreadyLoaded)
127
229
{
128
230
    CK_C_INITIALIZE_ARGS moduleArgs;
129
231
    CK_VOID_PTR pInitArgs;
130
232
    CK_RV crv;
131
233
 
 
234
    if (reload) {
 
235
        *reload = NULL;
 
236
    }
 
237
 
132
238
    if (!mod || !alreadyLoaded) {
133
239
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
134
240
        return SECFailure;
144
250
        pInitArgs = &moduleArgs;
145
251
    }
146
252
    crv = PK11_GETTAB(mod)->C_Initialize(pInitArgs);
147
 
    if ((CKR_CRYPTOKI_ALREADY_INITIALIZED == crv) &&
148
 
        (!enforceAlreadyInitializedError)) {
149
 
        *alreadyLoaded = PR_TRUE;
150
 
        return SECSuccess;
 
253
    if (CKR_CRYPTOKI_ALREADY_INITIALIZED == crv) {
 
254
        SECMODModule *oldModule = NULL;
 
255
 
 
256
        /* Library has already been loaded once, if caller expects it, and it
 
257
         * has additional configuration, try reloading it as well. */
 
258
        if (reload != NULL && mod->libraryParams) {
 
259
            oldModule = secmod_FindModuleByFuncPtr(mod->functionList);
 
260
        }
 
261
        /* Library has been loaded by NSS. It means it may be capable of
 
262
         * reloading */
 
263
        if (oldModule) {
 
264
            SECStatus rv;
 
265
            rv = secmod_handleReload(oldModule, mod);
 
266
            if (rv == SECSuccess) {
 
267
                /* This module should go away soon, since we've
 
268
                 * simply expanded the slots on the old module.
 
269
                 * When it goes away, it should not Finalize since
 
270
                 * that will close our old module as well. Setting
 
271
                 * the function list to NULL will prevent that close */
 
272
                mod->functionList = NULL;
 
273
                *reload = oldModule;
 
274
                return SECSuccess;
 
275
            }
 
276
            SECMOD_DestroyModule(oldModule);
 
277
        }
 
278
        /* reload not possible, fall back to old semantics */
 
279
        if (!enforceAlreadyInitializedError) {
 
280
            *alreadyLoaded = PR_TRUE;
 
281
            return SECSuccess;
 
282
        }
151
283
    }
152
284
    if (crv != CKR_OK) {
153
285
        if (pInitArgs == NULL ||
217
349
    }
218
350
}
219
351
 
220
 
static const char* NameOfThisSharedLib =
 
352
static const char* my_shlib_name =
221
353
    SHLIB_PREFIX"nss"SHLIB_VERSION"."SHLIB_SUFFIX;
222
 
static const char* softoken_default_name =
 
354
static const char* softoken_shlib_name =
223
355
    SHLIB_PREFIX"softokn"SOFTOKEN_SHLIB_VERSION"."SHLIB_SUFFIX;
224
356
static const PRCallOnceType pristineCallOnce;
225
357
static PRCallOnceType loadSoftokenOnce;
231
363
#include <stdio.h>
232
364
#include "prsystem.h"
233
365
 
234
 
#include "../freebl/genload.c"
235
 
 
236
366
/* This function must be run only once. */
237
367
/*  determine if hybrid platform, then actually load the DSO. */
238
368
static PRStatus
239
369
softoken_LoadDSO( void ) 
240
370
{
241
371
  PRLibrary *  handle;
242
 
  const char * name = softoken_default_name;
243
 
 
244
 
  if (!name) {
245
 
    PR_SetError(PR_LOAD_LIBRARY_ERROR, 0);
246
 
    return PR_FAILURE;
247
 
  }
248
 
 
249
 
  handle = loader_LoadLibrary(name);
 
372
 
 
373
  handle = PORT_LoadLibraryFromOrigin(my_shlib_name,
 
374
                                      (PRFuncPtr) &softoken_LoadDSO,
 
375
                                      softoken_shlib_name);
250
376
  if (handle) {
251
377
    softokenLib = handle;
252
378
    return PR_SUCCESS;
258
384
 * load a new module into our address space and initialize it.
259
385
 */
260
386
SECStatus
261
 
SECMOD_LoadPKCS11Module(SECMODModule *mod) {
 
387
secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule) {
262
388
    PRLibrary *library = NULL;
263
389
    CK_C_GetFunctionList entry = NULL;
264
390
    char * full_name;
271
397
    if (mod->loaded) return SECSuccess;
272
398
 
273
399
    /* intenal modules get loaded from their internal list */
274
 
    if (mod->internal) {
 
400
    if (mod->internal && (mod->dllName == NULL)) {
275
401
    /*
276
402
     * Loads softoken as a dynamic library,
277
403
     * even though the rest of NSS assumes this as the "internal" module.
308
434
            return SECFailure;
309
435
        }
310
436
 
311
 
#ifdef notdef
312
 
        /* look up the library name */
313
 
        full_name = PR_GetLibraryName(PR_GetLibraryPath(),mod->dllName);
314
 
        if (full_name == NULL) {
315
 
            return SECFailure;
316
 
        }
317
 
#else
318
437
        full_name = PORT_Strdup(mod->dllName);
319
 
#endif
320
438
 
321
439
        /* load the library. If this succeeds, then we have to remember to
322
440
         * unload the library if anything goes wrong from here on out...
323
441
         */
324
442
        library = PR_LoadLibrary(full_name);
325
443
        mod->library = (void *)library;
326
 
#ifdef notdef
327
 
        PR_FreeLibraryName(full_name);
328
 
#else
329
444
        PORT_Free(full_name);
330
 
#endif
331
445
 
332
446
        if (library == NULL) {
333
447
            return SECFailure;
375
489
    mod->isThreadSafe = PR_TRUE;
376
490
 
377
491
    /* Now we initialize the module */
378
 
    rv = secmod_ModuleInit(mod, &alreadyLoaded);
 
492
    rv = secmod_ModuleInit(mod, oldModule, &alreadyLoaded);
379
493
    if (rv != SECSuccess) {
380
494
        goto fail;
381
495
    }
382
496
 
 
497
    /* module has been reloaded, this module itself is done, 
 
498
     * return to the caller */
 
499
    if (mod->functionList == NULL) {
 
500
        mod->loaded = PR_TRUE; /* technically the module is loaded.. */
 
501
        return SECSuccess;
 
502
    }
 
503
 
383
504
    /* check the version number */
384
505
    if (PK11_GETTAB(mod)->C_GetInfo(&info) != CKR_OK) goto fail2;
385
506
    if (info.cryptokiVersion.major != 2) goto fail2;
460
581
        return SECFailure;
461
582
    }
462
583
    if (finalizeModules) {
463
 
        if (!mod->moduleDBOnly) PK11_GETTAB(mod)->C_Finalize(NULL);
 
584
        if (mod->functionList &&!mod->moduleDBOnly) {
 
585
            PK11_GETTAB(mod)->C_Finalize(NULL);
 
586
        }
464
587
    }
465
588
    mod->moduleID = 0;
466
589
    mod->loaded = PR_FALSE;