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

« back to all changes in this revision

Viewing changes to mozilla/security/nss/lib/pk11wrap/pk11util.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:
179
179
SECStatus
180
180
SECMOD_AddModuleToDBOnlyList(SECMODModule *newModule)
181
181
{
182
 
    if (defaultDBModule == NULL) {
 
182
    if (defaultDBModule && SECMOD_GetDefaultModDBFlag(newModule)) {
 
183
        SECMOD_DestroyModule(defaultDBModule);
 
184
        defaultDBModule = SECMOD_ReferenceModule(newModule);
 
185
    } else if (defaultDBModule == NULL) {
183
186
        defaultDBModule = SECMOD_ReferenceModule(newModule);
184
187
    }
185
188
    return secmod_AddModuleToList(&modulesDB,newModule);
223
226
    SECMODModuleList *mlp;
224
227
    SECMODModule *module = NULL;
225
228
 
 
229
    if (!moduleLock) {
 
230
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
 
231
        return module;
 
232
    }
226
233
    SECMOD_GetReadLock(moduleLock);
227
234
    for(mlp = modules; mlp != NULL; mlp = mlp->next) {
228
235
        if (PORT_Strcmp(name,mlp->module->commonName) == 0) {
258
265
    SECMODModuleList *mlp;
259
266
    SECMODModule *module = NULL;
260
267
 
 
268
    if (!moduleLock) {
 
269
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
 
270
        return module;
 
271
    }
261
272
    SECMOD_GetReadLock(moduleLock);
262
273
    for(mlp = modules; mlp != NULL; mlp = mlp->next) {
263
274
        if (id == mlp->module->moduleID) {
274
285
}
275
286
 
276
287
/*
 
288
 * find the function pointer.
 
289
 */
 
290
SECMODModule *
 
291
secmod_FindModuleByFuncPtr(void *funcPtr) 
 
292
{
 
293
    SECMODModuleList *mlp;
 
294
    SECMODModule *module = NULL;
 
295
 
 
296
    SECMOD_GetReadLock(moduleLock);
 
297
    for(mlp = modules; mlp != NULL; mlp = mlp->next) {
 
298
        /* paranoia, shouldn't ever happen */
 
299
        if (!mlp->module) {
 
300
            continue;
 
301
        }
 
302
        if (funcPtr == mlp->module->functionList) {
 
303
            module = mlp->module;
 
304
            SECMOD_ReferenceModule(module);
 
305
            break;
 
306
        }
 
307
    }
 
308
    SECMOD_ReleaseReadLock(moduleLock);
 
309
    if (module == NULL) {
 
310
        PORT_SetError(SEC_ERROR_NO_MODULE);
 
311
    }
 
312
    return module;
 
313
}
 
314
 
 
315
/*
277
316
 * Find the Slot based on ID and the module.
278
317
 */
279
318
PK11SlotInfo *
282
321
    int i;
283
322
    PK11SlotInfo *slot = NULL;
284
323
 
 
324
    if (!moduleLock) {
 
325
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
 
326
        return slot;
 
327
    }
285
328
    SECMOD_GetReadLock(moduleLock);
286
329
    for (i=0; i < module->slotCount; i++) {
287
330
        PK11SlotInfo *cSlot = module->slots[i];
329
372
    SECMODModuleList **mlpp;
330
373
    SECStatus rv = SECFailure;
331
374
 
 
375
    if (!moduleLock) {
 
376
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
 
377
        return rv;
 
378
    }
 
379
 
332
380
    *type = SECMOD_EXTERNAL;
333
381
 
334
382
    SECMOD_GetWriteLock(moduleLock);
405
453
        PORT_SetError(SEC_ERROR_MODULE_STUCK);
406
454
        return rv;
407
455
    }
 
456
    if (!moduleLock) {
 
457
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
 
458
        return rv;
 
459
    }
408
460
 
409
461
    SECMOD_GetWriteLock(moduleLock);
410
462
    for(mlpp = &modules,mlp = modules; 
484
536
        /* module already exists. */
485
537
    }
486
538
 
487
 
    rv = SECMOD_LoadPKCS11Module(newModule);
 
539
    rv = secmod_LoadPKCS11Module(newModule, NULL);
488
540
    if (rv != SECSuccess) {
489
541
        return rv;
490
542
    }
508
560
    char *string;
509
561
    PK11SlotInfo *retSlot = NULL;
510
562
 
 
563
    if (!moduleLock) {
 
564
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
 
565
        return retSlot;
 
566
    }
511
567
    SECMOD_GetReadLock(moduleLock);
512
568
    for (i=0; i < module->slotCount; i++) {
513
569
        PK11SlotInfo *slot = module->slots[i];
574
630
    PK11SlotInfo* slot;
575
631
 
576
632
    PR_SetErrorText(0, NULL);
 
633
    if (!moduleLock) {
 
634
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
 
635
        return result;
 
636
    }
577
637
 
578
638
    module = SECMOD_CreateModule(dllPath, moduleName, modparms, nssparms);
579
639
 
693
753
SECMOD_IsModulePresent( unsigned long int pubCipherEnableFlags )
694
754
{
695
755
    PRBool result = PR_FALSE;
696
 
    SECMODModuleList *mods = SECMOD_GetDefaultModuleList();
 
756
    SECMODModuleList *mods;
 
757
 
 
758
    if (!moduleLock) {
 
759
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
 
760
        return result;
 
761
    }
697
762
    SECMOD_GetReadLock(moduleLock);
698
 
 
699
 
 
 
763
    mods = SECMOD_GetDefaultModuleList();
700
764
    for ( ; mods != NULL; mods = mods->next) {
701
765
        if (mods->module->ssl[0] & 
702
766
                SECMOD_PubCipherFlagstoInternal(pubCipherEnableFlags)) {
867
931
    PK11SlotInfo **newSlots = NULL;
868
932
    PK11SlotInfo **oldSlots = NULL;
869
933
 
 
934
    if (!moduleLock) {
 
935
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
 
936
        return SECFailure;
 
937
    }
 
938
 
870
939
    /* C_GetSlotList is not a session function, make sure 
871
940
     * calls are serialized */
872
941
    PZ_Lock(mod->refLock);
988
1057
    int i;
989
1058
    int error = SEC_ERROR_NO_EVENT;
990
1059
 
 
1060
    if (!moduleLock) {
 
1061
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
 
1062
        return NULL;
 
1063
    }
991
1064
    PZ_Lock(mod->refLock);
992
1065
    if (mod->evControlMask & SECMOD_END_WAIT) {
993
1066
        mod->evControlMask &= ~SECMOD_END_WAIT;
1157
1230
         * we intend to use it again */
1158
1231
        if (CKR_OK == crv) {
1159
1232
            PRBool alreadyLoaded;
1160
 
            secmod_ModuleInit(mod, &alreadyLoaded);
 
1233
            secmod_ModuleInit(mod, NULL, &alreadyLoaded);
1161
1234
        } else {
1162
1235
            /* Finalized failed for some reason,  notify the application
1163
1236
             * so maybe it has a prayer of recovering... */
1184
1257
    int i;
1185
1258
    PRBool ret = PR_FALSE;
1186
1259
 
 
1260
    if (!moduleLock) {
 
1261
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
 
1262
        return ret;
 
1263
    }
1187
1264
    SECMOD_GetReadLock(moduleLock);
1188
1265
    for (i=0; i < mod->slotCount; i++) {
1189
1266
        PK11SlotInfo *slot = mod->slots[i];
1202
1279
 * helper function to actually create and destroy user defined slots
1203
1280
 */
1204
1281
static SECStatus
1205
 
secmod_UserDBOp(CK_OBJECT_CLASS objClass, const char *sendSpec)
 
1282
secmod_UserDBOp(PK11SlotInfo *slot, CK_OBJECT_CLASS objClass, 
 
1283
                const char *sendSpec)
1206
1284
{
1207
 
    PK11SlotInfo *slot = PK11_GetInternalSlot();
1208
1285
    CK_OBJECT_HANDLE dummy;
1209
1286
    CK_ATTRIBUTE template[2] ;
1210
1287
    CK_ATTRIBUTE *attrs = template;
1211
 
    SECStatus rv;
1212
1288
    CK_RV crv;
1213
1289
 
1214
1290
    PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass)); attrs++;
1224
1300
    PK11_ExitSlotMonitor(slot);
1225
1301
 
1226
1302
    if (crv != CKR_OK) {
1227
 
        PK11_FreeSlot(slot);
1228
1303
        PORT_SetError(PK11_MapError(crv));
1229
1304
        return SECFailure;
1230
1305
    }
1231
 
    rv = SECMOD_UpdateSlotList(slot->module);
 
1306
    return SECMOD_UpdateSlotList(slot->module);
 
1307
}
 
1308
 
 
1309
/*
 
1310
 * return true if the selected slot ID is not present or doesn't exist
 
1311
 */
 
1312
static PRBool
 
1313
secmod_SlotIsEmpty(SECMODModule *mod,  CK_SLOT_ID slotID)
 
1314
{
 
1315
    PK11SlotInfo *slot = SECMOD_LookupSlot(mod->moduleID, slotID);
 
1316
    if (slot) {
 
1317
        PRBool present = PK11_IsPresent(slot);
 
1318
        PK11_FreeSlot(slot);
 
1319
        if (present) {
 
1320
            return PR_FALSE;
 
1321
        }
 
1322
    }
 
1323
    /* it doesn't exist or isn't present, it's available */
 
1324
    return PR_TRUE;
 
1325
}
 
1326
 
 
1327
/*
 
1328
 * Find an unused slot id in module.
 
1329
 */
 
1330
static CK_SLOT_ID
 
1331
secmod_FindFreeSlot(SECMODModule *mod)
 
1332
{
 
1333
    CK_SLOT_ID i, minSlotID, maxSlotID;
 
1334
 
 
1335
    /* look for a free slot id on the internal module */
 
1336
    if (mod->internal && mod->isFIPS) {
 
1337
        minSlotID = SFTK_MIN_FIPS_USER_SLOT_ID;
 
1338
        maxSlotID = SFTK_MAX_FIPS_USER_SLOT_ID;
 
1339
    } else {
 
1340
        minSlotID = SFTK_MIN_USER_SLOT_ID;
 
1341
        maxSlotID = SFTK_MAX_USER_SLOT_ID;
 
1342
    }
 
1343
    for (i=minSlotID; i < maxSlotID; i++) {
 
1344
        if (secmod_SlotIsEmpty(mod,i)) {
 
1345
            return i;
 
1346
        }
 
1347
    }
 
1348
    PORT_SetError(SEC_ERROR_NO_SLOT_SELECTED);
 
1349
    return (CK_SLOT_ID) -1;
 
1350
}
 
1351
 
 
1352
/*
 
1353
 * Attempt to open a new slot.
 
1354
 *
 
1355
 * This works the same os OpenUserDB except it can be called against
 
1356
 * any module that understands the softoken protocol for opening new
 
1357
 * slots, not just the softoken itself. If the selected module does not
 
1358
 * understand the protocol, C_CreateObject will fail with 
 
1359
 * CKR_INVALID_ATTRIBUTE, and SECMOD_OpenNewSlot will return NULL and set
 
1360
 * SEC_ERROR_BAD_DATA.
 
1361
 * 
 
1362
 * NewSlots can be closed with SECMOD_CloseUserDB();
 
1363
 *
 
1364
 * Modulespec is module dependent.
 
1365
 */
 
1366
PK11SlotInfo *
 
1367
SECMOD_OpenNewSlot(SECMODModule *mod, const char *moduleSpec)
 
1368
{
 
1369
    CK_SLOT_ID slotID = 0;
 
1370
    PK11SlotInfo *slot;
 
1371
    char *escSpec;
 
1372
    char *sendSpec;
 
1373
    SECStatus rv;
 
1374
 
 
1375
    slotID = secmod_FindFreeSlot(mod);
 
1376
    if (slotID == (CK_SLOT_ID) -1) {
 
1377
        return NULL;
 
1378
    }
 
1379
 
 
1380
    if (mod->slotCount == 0) {
 
1381
        return NULL;
 
1382
    }
 
1383
 
 
1384
    /* just grab the first slot in the module, any present slot should work */
 
1385
    slot = PK11_ReferenceSlot(mod->slots[0]);
 
1386
    if (slot == NULL) {
 
1387
        return NULL;
 
1388
    }
 
1389
 
 
1390
    /* we've found the slot, now build the moduleSpec */
 
1391
    escSpec = secmod_DoubleEscape(moduleSpec, '>', ']');
 
1392
    if (escSpec == NULL) {
 
1393
        PK11_FreeSlot(slot);
 
1394
        return NULL;
 
1395
    }
 
1396
    sendSpec = PR_smprintf("tokens=[0x%x=<%s>]", slotID, escSpec);
 
1397
    PORT_Free(escSpec);
 
1398
 
 
1399
    if (sendSpec == NULL) {
 
1400
        /* PR_smprintf does not set SEC_ERROR_NO_MEMORY on failure. */
 
1401
        PK11_FreeSlot(slot);
 
1402
        PORT_SetError(SEC_ERROR_NO_MEMORY);
 
1403
        return NULL;
 
1404
    }
 
1405
    rv = secmod_UserDBOp(slot, CKO_NETSCAPE_NEWSLOT, sendSpec);
 
1406
    PR_smprintf_free(sendSpec);
1232
1407
    PK11_FreeSlot(slot);
1233
 
    return rv;
1234
 
}
1235
 
 
1236
 
/*
1237
 
 * add escapes to protect quote characters...
1238
 
 */
1239
 
static char *
1240
 
nss_addEscape(const char *string, char quote)
1241
 
{
1242
 
    char *newString = 0;
1243
 
    int escapes = 0, size = 0;
1244
 
    const char *src;
1245
 
    char *dest;
1246
 
 
1247
 
    for (src=string; *src ; src++) {
1248
 
        if ((*src == quote) || (*src == '\\')) escapes++;
1249
 
        size++;
1250
 
    }
1251
 
 
1252
 
    newString = PORT_ZAlloc(escapes+size+1);
1253
 
    if (newString == NULL) {
1254
 
        return NULL;
1255
 
    }
1256
 
 
1257
 
    for (src=string, dest=newString; *src; src++,dest++) {
1258
 
        if ((*src == '\\') || (*src == quote)) {
1259
 
            *dest++ = '\\';
1260
 
        }
1261
 
        *dest = *src;
1262
 
    }
1263
 
 
1264
 
    return newString;
1265
 
}
1266
 
 
1267
 
static char *
1268
 
nss_doubleEscape(const char *string)
1269
 
{
1270
 
    char *round1 = NULL;
1271
 
    char *retValue = NULL;
1272
 
    if (string == NULL) {
1273
 
        goto done;
1274
 
    }
1275
 
    round1 = nss_addEscape(string,'>');
1276
 
    if (round1) {
1277
 
        retValue = nss_addEscape(round1,']');
1278
 
        PORT_Free(round1);
1279
 
    }
1280
 
 
1281
 
done:
1282
 
    if (retValue == NULL) {
1283
 
        retValue = PORT_Strdup("");
1284
 
    }
1285
 
    return retValue;
 
1408
    if (rv != SECSuccess) {
 
1409
        return NULL;
 
1410
    }
 
1411
 
 
1412
    return SECMOD_FindSlotByID(mod, slotID);
1286
1413
}
1287
1414
 
1288
1415
/*
1337
1464
PK11SlotInfo *
1338
1465
SECMOD_OpenUserDB(const char *moduleSpec)
1339
1466
{
1340
 
    CK_SLOT_ID slotID = 0;
1341
 
    char *escSpec;
1342
 
    char *sendSpec;
1343
 
    SECStatus rv;
1344
1467
    SECMODModule *mod;
1345
 
    CK_SLOT_ID i, minSlotID, maxSlotID;
1346
 
    PRBool found = PR_FALSE;
1347
1468
 
1348
1469
    if (moduleSpec == NULL) {
1349
1470
        return NULL;
1357
1478
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
1358
1479
        return NULL;
1359
1480
    }
1360
 
 
1361
 
    /* look for a free slot id on the internal module */
1362
 
    if (mod->isFIPS) {
1363
 
        minSlotID = SFTK_MIN_FIPS_USER_SLOT_ID;
1364
 
        maxSlotID = SFTK_MAX_FIPS_USER_SLOT_ID;
1365
 
    } else {
1366
 
        minSlotID = SFTK_MIN_USER_SLOT_ID;
1367
 
        maxSlotID = SFTK_MAX_USER_SLOT_ID;
1368
 
    }
1369
 
    for (i=minSlotID; i < maxSlotID; i++) {
1370
 
        PK11SlotInfo *slot = SECMOD_LookupSlot(mod->moduleID, i);
1371
 
        if (slot) {
1372
 
            PRBool present = PK11_IsPresent(slot);
1373
 
            PK11_FreeSlot(slot);
1374
 
            if (present) {
1375
 
                continue;
1376
 
            }
1377
 
            /* not present means it's available */
1378
 
        }
1379
 
        /* it doesn't exist or isn't present, it's available */
1380
 
        slotID = i;
1381
 
        found = PR_TRUE;
1382
 
        break;
1383
 
    }
1384
 
 
1385
 
    if (!found) {
1386
 
        /* this could happen if we try to open too many slots */
1387
 
        PORT_SetError(SEC_ERROR_NO_SLOT_SELECTED);
1388
 
        return NULL;
1389
 
    }
1390
 
 
1391
 
    /* we've found the slot, now build the moduleSpec */
1392
 
 
1393
 
    escSpec = nss_doubleEscape(moduleSpec);
1394
 
    if (escSpec == NULL) {
1395
 
        return NULL;
1396
 
    }
1397
 
    sendSpec = PR_smprintf("tokens=[0x%x=<%s>]", slotID, escSpec);
1398
 
    PORT_Free(escSpec);
1399
 
 
1400
 
    if (sendSpec == NULL) {
1401
 
        /* PR_smprintf does not set no memory error */
1402
 
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1403
 
        return NULL;
1404
 
    }
1405
 
    rv = secmod_UserDBOp(CKO_NETSCAPE_NEWSLOT, sendSpec);
1406
 
    PR_smprintf_free(sendSpec);
1407
 
    if (rv != SECSuccess) {
1408
 
        return NULL;
1409
 
    }
1410
 
 
1411
 
    return SECMOD_FindSlotByID(mod, slotID);
 
1481
    return SECMOD_OpenNewSlot(mod, moduleSpec);
1412
1482
}
1413
1483
 
 
1484
 
1414
1485
/*
1415
1486
 * close an already opened user database. NOTE: the database must be
1416
1487
 * in the internal token, and must be one created with SECMOD_OpenUserDB().
1417
1488
 * Once the database is closed, the slot will remain as an empty slot
1418
 
 * until it's used again with SECMOD_OpenUserDB().
 
1489
 * until it's used again with SECMOD_OpenUserDB() or SECMOD_OpenNewSlot().
1419
1490
 */
1420
1491
SECStatus
1421
1492
SECMOD_CloseUserDB(PK11SlotInfo *slot)
1422
1493
{
1423
1494
    SECStatus rv;
1424
1495
    char *sendSpec;
1425
 
 
1426
 
    if (!slot->isInternal) {
1427
 
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
1428
 
        return SECFailure;
1429
 
    }
1430
1496
    
1431
1497
    sendSpec = PR_smprintf("tokens=[0x%x=<>]", slot->slotID);
1432
1498
    if (sendSpec == NULL) {
1434
1500
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1435
1501
        return SECFailure;
1436
1502
    }
1437
 
    rv = secmod_UserDBOp(CKO_NETSCAPE_DELSLOT, sendSpec);
 
1503
    rv = secmod_UserDBOp(slot, CKO_NETSCAPE_DELSLOT, sendSpec);
1438
1504
    PR_smprintf_free(sendSpec);
1439
1505
    return rv;
1440
1506
}