Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(254)

Unified Diff: nss/lib/pk11wrap/pk11merge.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « nss/lib/pk11wrap/pk11mech.c ('k') | nss/lib/pk11wrap/pk11nobj.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: nss/lib/pk11wrap/pk11merge.c
diff --git a/nss/lib/pk11wrap/pk11merge.c b/nss/lib/pk11wrap/pk11merge.c
deleted file mode 100644
index 8fadc7caf318e92b10b02e99e38b2913a0fb0cb0..0000000000000000000000000000000000000000
--- a/nss/lib/pk11wrap/pk11merge.c
+++ /dev/null
@@ -1,1420 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Merge the source token into the target token.
- */
-
-#include "secmod.h"
-#include "secmodi.h"
-#include "secmodti.h"
-#include "pk11pub.h"
-#include "pk11priv.h"
-#include "pkcs11.h"
-#include "seccomon.h"
-#include "secerr.h"
-#include "keyhi.h"
-#include "hasht.h"
-#include "cert.h"
-#include "certdb.h"
-
-/*************************************************************************
- *
- * short utilities to aid in the merge
- *
- *************************************************************************/
-
-/*
- * write a bunch of attributes out to an existing object.
- */
-static SECStatus
-pk11_setAttributes(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
- CK_ATTRIBUTE *setTemplate, CK_ULONG setTemplCount)
-{
- CK_RV crv;
- CK_SESSION_HANDLE rwsession;
-
- rwsession = PK11_GetRWSession(slot);
- if (rwsession == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
- crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession, id,
- setTemplate, setTemplCount);
- PK11_RestoreROSession(slot, rwsession);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
- return SECSuccess;
-}
-
-
-/*
- * copy a template of attributes from a source object to a target object.
- * if target object is not given, create it.
- */
-static SECStatus
-pk11_copyAttributes(PLArenaPool *arena,
- PK11SlotInfo *targetSlot, CK_OBJECT_HANDLE targetID,
- PK11SlotInfo *sourceSlot, CK_OBJECT_HANDLE sourceID,
- CK_ATTRIBUTE *copyTemplate, CK_ULONG copyTemplateCount)
-{
- SECStatus rv = PK11_GetAttributes(arena, sourceSlot, sourceID,
- copyTemplate, copyTemplateCount);
- if (rv != SECSuccess) {
- return rv;
- }
- if (targetID == CK_INVALID_HANDLE) {
- /* we need to create the object */
- rv = PK11_CreateNewObject(targetSlot, CK_INVALID_SESSION,
- copyTemplate, copyTemplateCount, PR_TRUE, &targetID);
- } else {
- /* update the existing object with the new attributes */
- rv = pk11_setAttributes(targetSlot, targetID,
- copyTemplate, copyTemplateCount);
- }
- return rv;
-}
-
-/*
- * look for a matching object across tokens.
- */
-static SECStatus
-pk11_matchAcrossTokens(PLArenaPool *arena, PK11SlotInfo *targetSlot,
- PK11SlotInfo *sourceSlot,
- CK_ATTRIBUTE *template, CK_ULONG tsize,
- CK_OBJECT_HANDLE id, CK_OBJECT_HANDLE *peer)
-{
-
- CK_RV crv;
- *peer = CK_INVALID_HANDLE;
-
- crv = PK11_GetAttributes(arena, sourceSlot, id, template, tsize);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- goto loser;
- }
-
- if (template[0].ulValueLen == -1) {
- crv = CKR_ATTRIBUTE_TYPE_INVALID;
- PORT_SetError( PK11_MapError(crv) );
- goto loser;
- }
-
- *peer = pk11_FindObjectByTemplate(targetSlot, template, tsize);
- return SECSuccess;
-
-loser:
- return SECFailure;
-}
-
-/*
- * Encrypt using key and parameters
- */
-SECStatus
-pk11_encrypt(PK11SymKey *symKey, CK_MECHANISM_TYPE mechType, SECItem *param,
- SECItem *input, SECItem **output)
-{
- PK11Context *ctxt = NULL;
- SECStatus rv = SECSuccess;
-
- if (*output) {
- SECITEM_FreeItem(*output,PR_TRUE);
- }
- *output = SECITEM_AllocItem(NULL, NULL, input->len+20 /*slop*/);
- if (!*output) {
- rv = SECFailure;
- goto done;
- }
-
- ctxt = PK11_CreateContextBySymKey(mechType, CKA_ENCRYPT, symKey, param);
- if (ctxt == NULL) {
- rv = SECFailure;
- goto done;
- }
-
- rv = PK11_CipherOp(ctxt, (*output)->data,
- (int *)&((*output)->len),
- (*output)->len, input->data, input->len);
-
-done:
- if (ctxt) {
- PK11_Finalize(ctxt);
- PK11_DestroyContext(ctxt,PR_TRUE);
- }
- if (rv != SECSuccess) {
- if (*output) {
- SECITEM_FreeItem(*output, PR_TRUE);
- *output = NULL;
- }
- }
- return rv;
-}
-
-
-
-/*************************************************************************
- *
- * Private Keys
- *
- *************************************************************************/
-
-/*
- * Fetch the key usage based on the pkcs #11 flags
- */
-unsigned int
-pk11_getPrivateKeyUsage(PK11SlotInfo *slot, CK_OBJECT_HANDLE id)
-{
- unsigned int usage = 0;
-
- if ((PK11_HasAttributeSet(slot, id, CKA_UNWRAP,PR_FALSE) ||
- PK11_HasAttributeSet(slot,id, CKA_DECRYPT,PR_FALSE))) {
- usage |= KU_KEY_ENCIPHERMENT;
- }
- if (PK11_HasAttributeSet(slot, id, CKA_DERIVE, PR_FALSE)) {
- usage |= KU_KEY_AGREEMENT;
- }
- if ((PK11_HasAttributeSet(slot, id, CKA_SIGN_RECOVER, PR_FALSE) ||
- PK11_HasAttributeSet(slot, id, CKA_SIGN, PR_FALSE))) {
- usage |= KU_DIGITAL_SIGNATURE;
- }
- return usage;
-}
-
-
-/*
- * merge a private key,
- *
- * Private keys are merged using PBE wrapped keys with a random
- * value as the 'password'. Once the base key is moved, The remaining
- * attributes (SUBJECT) is copied.
- */
-static SECStatus
-pk11_mergePrivateKey(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
-{
- SECKEYPrivateKey *sourceKey = NULL;
- CK_OBJECT_HANDLE targetKeyID;
- SECKEYEncryptedPrivateKeyInfo *epki = NULL;
- char *nickname = NULL;
- SECItem nickItem;
- SECItem pwitem;
- SECItem publicValue;
- PLArenaPool *arena = NULL;
- SECStatus rv = SECSuccess;
- unsigned int keyUsage;
- unsigned char randomData[SHA1_LENGTH];
- SECOidTag algTag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC;
- CK_ATTRIBUTE privTemplate[] = {
- { CKA_ID, NULL, 0 },
- { CKA_CLASS, NULL, 0 }
- };
- CK_ULONG privTemplateCount = sizeof(privTemplate)/sizeof(privTemplate[0]);
- CK_ATTRIBUTE privCopyTemplate[] = {
- { CKA_SUBJECT, NULL, 0 }
- };
- CK_ULONG privCopyTemplateCount =
- sizeof(privCopyTemplate)/sizeof(privCopyTemplate[0]);
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- rv = SECFailure;
- goto done;
- }
-
- /* check to see if the key is already in the target slot */
- rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, privTemplate,
- privTemplateCount, id, &targetKeyID);
- if (rv != SECSuccess) {
- goto done;
- }
-
- if (targetKeyID != CK_INVALID_HANDLE) {
- /* match found, not an error ... */
- goto done;
- }
-
- /* get an NSS representation of our source key */
- sourceKey = PK11_MakePrivKey(sourceSlot, nullKey, PR_FALSE,
- id, sourcePwArg);
- if (sourceKey == NULL) {
- rv = SECFailure;
- goto done;
- }
-
- /* Load the private key */
- /* generate a random pwitem */
- rv = PK11_GenerateRandom(randomData, sizeof(randomData));
- if (rv != SECSuccess) {
- goto done;
- }
- pwitem.data = randomData;
- pwitem.len = sizeof(randomData);
- /* fetch the private key encrypted */
- epki = PK11_ExportEncryptedPrivKeyInfo(sourceSlot, algTag, &pwitem,
- sourceKey, 1, sourcePwArg);
- if (epki == NULL) {
- rv = SECFailure;
- goto done;
- }
- nickname = PK11_GetObjectNickname(sourceSlot, id);
- /* NULL nickanme is fine (in fact is often normal) */
- if (nickname) {
- nickItem.data = (unsigned char *)nickname;
- nickItem.len = PORT_Strlen(nickname);
- }
- keyUsage = pk11_getPrivateKeyUsage(sourceSlot, id);
- /* pass in the CKA_ID */
- publicValue.data = privTemplate[0].pValue;
- publicValue.len = privTemplate[0].ulValueLen;
- rv = PK11_ImportEncryptedPrivateKeyInfo(targetSlot, epki, &pwitem,
- nickname? &nickItem : NULL , &publicValue,
- PR_TRUE, PR_TRUE, sourceKey->keyType, keyUsage,
- targetPwArg);
- if (rv != SECSuccess) {
- goto done;
- }
-
- /* make sure it made it */
- rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, privTemplate,
- privTemplateCount, id, &targetKeyID);
- if (rv != SECSuccess) {
- goto done;
- }
-
- if (targetKeyID == CK_INVALID_HANDLE) {
- /* this time the key should exist */
- rv = SECFailure;
- goto done;
- }
-
- /* fill in remaining attributes */
- rv = pk11_copyAttributes(arena, targetSlot, targetKeyID, sourceSlot, id,
- privCopyTemplate, privCopyTemplateCount);
-done:
- /* make sure the 'key' is cleared */
- PORT_Memset(randomData, 0, sizeof(randomData));
- if (nickname) {
- PORT_Free(nickname);
- }
- if (sourceKey) {
- SECKEY_DestroyPrivateKey(sourceKey);
- }
- if (epki) {
- SECKEY_DestroyEncryptedPrivateKeyInfo(epki, PR_TRUE);
- }
- if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
- }
- return rv;
-}
-
-
-/*************************************************************************
- *
- * Secret Keys
- *
- *************************************************************************/
-
-/*
- * we need to find a unique CKA_ID.
- * The basic idea is to just increment the lowest byte.
- * This code also handles the following corner cases:
- * 1) the single byte overflows. On overflow we increment the next byte up
- * and so forth until we have overflowed the entire CKA_ID.
- * 2) If we overflow the entire CKA_ID we expand it by one byte.
- * 3) the CKA_ID is non-existent, we create a new one with one byte.
- * This means no matter what CKA_ID is passed, the result of this function
- * is always a new CKA_ID, and this function will never return the same
- * CKA_ID the it has returned in the passed.
- */
-static SECStatus
-pk11_incrementID(PLArenaPool *arena, CK_ATTRIBUTE *ptemplate)
-{
- unsigned char *buf = ptemplate->pValue;
- CK_ULONG len = ptemplate->ulValueLen;
-
- if (buf == NULL || len == (CK_ULONG)-1) {
- /* we have no valid CKAID, we'll create a basic one byte CKA_ID below */
- len = 0;
- } else {
- CK_ULONG i;
-
- /* walk from the back to front, incrementing
- * the CKA_ID until we no longer have a carry,
- * or have hit the front of the id. */
- for (i=len; i != 0; i--) {
- buf[i-1]++;
- if (buf[i-1] != 0) {
- /* no more carries, the increment is complete */
- return SECSuccess;
- }
- }
- /* we've now overflowed, fall through and expand the CKA_ID by
- * one byte */
- }
- /* if we are here we've run the counter to zero (indicating an overflow).
- * create an CKA_ID that is all zeros, but has one more zero than
- * the previous CKA_ID */
- buf = PORT_ArenaZAlloc(arena, len+1);
- if (buf == NULL) {
- return SECFailure;
- }
- ptemplate->pValue = buf;
- ptemplate->ulValueLen = len+1;
- return SECSuccess;
-}
-
-
-static CK_FLAGS
-pk11_getSecretKeyFlags(PK11SlotInfo *slot, CK_OBJECT_HANDLE id)
-{
- CK_FLAGS flags = 0;
-
- if (PK11_HasAttributeSet(slot, id, CKA_UNWRAP, PR_FALSE)) {
- flags |= CKF_UNWRAP;
- }
- if (PK11_HasAttributeSet(slot, id, CKA_WRAP, PR_FALSE)) {
- flags |= CKF_WRAP;
- }
- if (PK11_HasAttributeSet(slot, id, CKA_ENCRYPT, PR_FALSE)) {
- flags |= CKF_ENCRYPT;
- }
- if (PK11_HasAttributeSet(slot, id, CKA_DECRYPT, PR_FALSE)) {
- flags |= CKF_DECRYPT;
- }
- if (PK11_HasAttributeSet(slot, id, CKA_DERIVE, PR_FALSE)) {
- flags |= CKF_DERIVE;
- }
- if (PK11_HasAttributeSet(slot, id, CKA_SIGN, PR_FALSE)) {
- flags |= CKF_SIGN;
- }
- if (PK11_HasAttributeSet(slot, id, CKA_SIGN_RECOVER, PR_FALSE)) {
- flags |= CKF_SIGN_RECOVER;
- }
- if (PK11_HasAttributeSet(slot, id, CKA_VERIFY, PR_FALSE)) {
- flags |= CKF_VERIFY;
- }
- if (PK11_HasAttributeSet(slot, id, CKA_VERIFY_RECOVER, PR_FALSE)) {
- flags |= CKF_VERIFY_RECOVER;
- }
- return flags;
-}
-
-static const char testString[] =
- "My Encrytion Test Data (should be at least 32 bytes long)";
-/*
- * merge a secret key,
- *
- * Secret keys may collide by CKA_ID as we merge 2 token. If we collide
- * on the CKA_ID, we need to make sure we are dealing with different keys.
- * The reason for this is it is possible that we've merged this database
- * before, and this key could have been merged already. If the keys are
- * the same, we are done. If they are not, we need to update the CKA_ID of
- * the source key and try again.
- *
- * Once we know we have a unique key to merge in, we use NSS's underlying
- * key Move function which will do a key exchange if necessary to move
- * the key from one token to another. Then we set the CKA_ID and additional
- * pkcs #11 attributes.
- */
-static SECStatus
-pk11_mergeSecretKey(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
-{
- PK11SymKey *sourceKey = NULL;
- PK11SymKey *targetKey = NULL;
- SECItem *sourceOutput = NULL;
- SECItem *targetOutput = NULL;
- SECItem *param = NULL;
- int blockSize;
- SECItem input;
- CK_OBJECT_HANDLE targetKeyID;
- CK_FLAGS flags;
- PLArenaPool *arena = NULL;
- SECStatus rv = SECSuccess;
- CK_MECHANISM_TYPE keyMechType, cryptoMechType;
- CK_KEY_TYPE sourceKeyType, targetKeyType;
- CK_ATTRIBUTE symTemplate[] = {
- { CKA_ID, NULL, 0 },
- { CKA_CLASS, NULL, 0 }
- };
- CK_ULONG symTemplateCount = sizeof(symTemplate)/sizeof(symTemplate[0]);
- CK_ATTRIBUTE symCopyTemplate[] = {
- { CKA_LABEL, NULL, 0 }
- };
- CK_ULONG symCopyTemplateCount =
- sizeof(symCopyTemplate)/sizeof(symCopyTemplate[0]);
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- rv = SECFailure;
- goto done;
- }
-
- sourceKeyType = PK11_ReadULongAttribute(sourceSlot, id, CKA_KEY_TYPE);
- if (sourceKeyType == (CK_ULONG) -1) {
- rv = SECFailure;
- goto done;
- }
-
- /* get the key mechanism */
- keyMechType = PK11_GetKeyMechanism(sourceKeyType);
- /* get a mechanism suitable to encryption.
- * PK11_GetKeyMechanism returns a mechanism that is unique to the key
- * type. It tries to return encryption/decryption mechanisms, however
- * CKM_DES3_CBC uses and abmiguous keyType, so keyMechType is returned as
- * 'keygen' mechanism. Detect that case here */
- cryptoMechType = keyMechType;
- if ((keyMechType == CKM_DES3_KEY_GEN) ||
- (keyMechType == CKM_DES2_KEY_GEN)) {
- cryptoMechType = CKM_DES3_CBC;
- }
-
- sourceKey = PK11_SymKeyFromHandle(sourceSlot, NULL, PK11_OriginDerive,
- keyMechType , id, PR_FALSE, sourcePwArg);
- if (sourceKey == NULL) {
- rv = SECFailure;
- goto done;
- }
-
- /* check to see a key with the same CKA_ID already exists in
- * the target slot. If it does, then we need to verify if the keys
- * really matches. If they don't import the key with a new CKA_ID
- * value. */
- rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot,
- symTemplate, symTemplateCount, id, &targetKeyID);
- if (rv != SECSuccess) {
- goto done;
- }
-
- /* set up the input test */
- input.data = (unsigned char *)testString;
- blockSize = PK11_GetBlockSize(cryptoMechType, NULL);
- if (blockSize < 0) {
- rv = SECFailure;
- goto done;
- }
- input.len = blockSize;
- if (input.len == 0) {
- input.len = sizeof (testString);
- }
- while (targetKeyID != CK_INVALID_HANDLE) {
- /* test to see if the keys are identical */
- targetKeyType = PK11_ReadULongAttribute(sourceSlot, id, CKA_KEY_TYPE);
- if (targetKeyType == sourceKeyType) {
- /* same keyType - see if it's the same key */
- targetKey = PK11_SymKeyFromHandle(targetSlot, NULL,
- PK11_OriginDerive, keyMechType, targetKeyID, PR_FALSE,
- targetPwArg);
- /* get a parameter if we don't already have one */
- if (!param) {
- param = PK11_GenerateNewParam(cryptoMechType, sourceKey);
- if (param == NULL) {
- rv = SECFailure;
- goto done;
- }
- }
- /* use the source key to encrypt a reference */
- if (!sourceOutput) {
- rv = pk11_encrypt(sourceKey, cryptoMechType, param, &input,
- &sourceOutput);
- if (rv != SECSuccess) {
- goto done;
- }
- }
- /* encrypt the reference with the target key */
- rv = pk11_encrypt(targetKey, cryptoMechType, param, &input,
- &targetOutput);
- if (rv == SECSuccess) {
- if (SECITEM_ItemsAreEqual(sourceOutput, targetOutput)) {
- /* they produce the same output, they must be the
- * same key */
- goto done;
- }
- SECITEM_FreeItem(targetOutput, PR_TRUE);
- targetOutput = NULL;
- }
- PK11_FreeSymKey(targetKey);
- targetKey = NULL;
- }
- /* keys aren't equal, update the KEY_ID and look again */
- rv = pk11_incrementID(arena, &symTemplate[0]);
- if (rv != SECSuccess) {
- goto done;
- }
- targetKeyID = pk11_FindObjectByTemplate(targetSlot,
- symTemplate, symTemplateCount);
- }
-
- /* we didn't find a matching key, import this one with the new
- * CKAID */
- flags = pk11_getSecretKeyFlags(sourceSlot, id);
- targetKey = PK11_MoveSymKey(targetSlot, PK11_OriginDerive, flags, PR_TRUE,
- sourceKey);
- if (targetKey == NULL) {
- rv = SECFailure;
- goto done;
- }
- /* set the key new CKAID */
- rv = pk11_setAttributes(targetSlot, targetKey->objectID, symTemplate, 1);
- if (rv != SECSuccess) {
- goto done;
- }
-
- /* fill in remaining attributes */
- rv = pk11_copyAttributes(arena, targetSlot, targetKey->objectID,
- sourceSlot, id, symCopyTemplate, symCopyTemplateCount);
-done:
- if (sourceKey) {
- PK11_FreeSymKey(sourceKey);
- }
- if (targetKey) {
- PK11_FreeSymKey(targetKey);
- }
- if (sourceOutput) {
- SECITEM_FreeItem(sourceOutput, PR_TRUE);
- }
- if (targetOutput) {
- SECITEM_FreeItem(targetOutput, PR_TRUE);
- }
- if (param) {
- SECITEM_FreeItem(param, PR_TRUE);
- }
- if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
- }
- return rv;
-}
-
-/*************************************************************************
- *
- * Public Keys
- *
- *************************************************************************/
-
-/*
- * Merge public key
- *
- * Use the high level NSS calls to extract the public key and import it
- * into the token. Extra attributes are then copied to the new token.
- */
-static SECStatus
-pk11_mergePublicKey(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
-{
- SECKEYPublicKey *sourceKey = NULL;
- CK_OBJECT_HANDLE targetKeyID;
- PLArenaPool *arena = NULL;
- SECStatus rv = SECSuccess;
- CK_ATTRIBUTE pubTemplate[] = {
- { CKA_ID, NULL, 0 },
- { CKA_CLASS, NULL, 0 }
- };
- CK_ULONG pubTemplateCount = sizeof(pubTemplate)/sizeof(pubTemplate[0]);
- CK_ATTRIBUTE pubCopyTemplate[] = {
- { CKA_ID, NULL, 0 },
- { CKA_LABEL, NULL, 0 },
- { CKA_SUBJECT, NULL, 0 }
- };
- CK_ULONG pubCopyTemplateCount =
- sizeof(pubCopyTemplate)/sizeof(pubCopyTemplate[0]);
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- rv = SECFailure;
- goto done;
- }
-
-
- /* check to see if the key is already in the target slot */
- rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, pubTemplate,
- pubTemplateCount, id, &targetKeyID);
- if (rv != SECSuccess) {
- goto done;
- }
-
- /* Key is already in the target slot */
- if (targetKeyID != CK_INVALID_HANDLE) {
- /* not an error ... */
- goto done;
- }
-
- /* fetch an NSS representation of the public key */
- sourceKey = PK11_ExtractPublicKey(sourceSlot, nullKey, id);
- if (sourceKey== NULL) {
- rv = SECFailure;
- goto done;
- }
-
- /* load the public key into the target token. */
- targetKeyID = PK11_ImportPublicKey(targetSlot, sourceKey, PR_TRUE);
- if (targetKeyID == CK_INVALID_HANDLE) {
- rv = SECFailure;
- goto done;
- }
-
- /* fill in remaining attributes */
- rv = pk11_copyAttributes(arena, targetSlot, targetKeyID, sourceSlot, id,
- pubCopyTemplate, pubCopyTemplateCount);
-
-
-done:
- if (sourceKey) {
- SECKEY_DestroyPublicKey(sourceKey);
- }
- if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
- }
- return rv;
-}
-
-/*************************************************************************
- *
- * Certificates
- *
- *************************************************************************/
-
-/*
- * Two copies of the source code for this algorithm exist in NSS.
- * Changes must be made in both copies.
- * The other copy is in sftkdb_resolveConflicts() in softoken/sftkdb.c.
- */
-static char *
-pk11_IncrementNickname(char *nickname)
-{
- char *newNickname = NULL;
- int end;
- int digit;
- int len = strlen(nickname);
-
- /* does nickname end with " #n*" ? */
- for (end = len - 1;
- end >= 2 && (digit = nickname[end]) <= '9' && digit >= '0';
- end--) /* just scan */ ;
- if (len >= 3 &&
- end < (len - 1) /* at least one digit */ &&
- nickname[end] == '#' &&
- nickname[end - 1] == ' ') {
- /* Already has a suitable suffix string */
- } else {
- /* ... append " #2" to the name */
- static const char num2[] = " #2";
- newNickname = PORT_Realloc(nickname, len + sizeof(num2));
- if (newNickname) {
- PORT_Strcat(newNickname, num2);
- } else {
- PORT_Free(nickname);
- }
- return newNickname;
- }
-
- for (end = len - 1;
- end >= 0 && (digit = nickname[end]) <= '9' && digit >= '0';
- end--) {
- if (digit < '9') {
- nickname[end]++;
- return nickname;
- }
- nickname[end] = '0';
- }
-
- /* we overflowed, insert a new '1' for a carry in front of the number */
- newNickname = PORT_Realloc(nickname, len + 2);
- if (newNickname) {
- newNickname[++end] = '1';
- PORT_Memset(&newNickname[end + 1], '0', len - end);
- newNickname[len + 1] = 0;
- } else {
- PORT_Free(nickname);
- }
- return newNickname;
-}
-
-/*
- * merge a certificate object
- *
- * Use the high level NSS calls to extract and import the certificate.
- */
-static SECStatus
-pk11_mergeCert(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
-{
- CERTCertificate *sourceCert = NULL;
- CK_OBJECT_HANDLE targetCertID = CK_INVALID_HANDLE;
- char *nickname = NULL;
- SECStatus rv = SECSuccess;
- PLArenaPool *arena = NULL;
- CK_ATTRIBUTE sourceCKAID = {CKA_ID, NULL, 0};
- CK_ATTRIBUTE targetCKAID = {CKA_ID, NULL, 0};
- SECStatus lrv = SECSuccess;
- int error = SEC_ERROR_LIBRARY_FAILURE;
-
- sourceCert = PK11_MakeCertFromHandle(sourceSlot, id, NULL);
- if (sourceCert == NULL) {
- rv = SECFailure;
- goto done;
- }
-
- nickname = PK11_GetObjectNickname(sourceSlot, id);
-
- /* The database code will prevent nickname collisions for certs with
- * different subjects. This code will prevent us from getting
- * actual import errors */
- if (nickname) {
- const char *tokenName = PK11_GetTokenName(targetSlot);
- char *tokenNickname = NULL;
-
- do {
- tokenNickname = PR_smprintf("%s:%s",tokenName, nickname);
- if (!tokenNickname) {
- break;
- }
- if (!SEC_CertNicknameConflict(tokenNickname,
- &sourceCert->derSubject, CERT_GetDefaultCertDB())) {
- break;
- }
- nickname = pk11_IncrementNickname(nickname);
- if (!nickname) {
- break;
- }
- PR_smprintf_free(tokenNickname);
- } while (1);
- if (tokenNickname) {
- PR_smprintf_free(tokenNickname);
- }
- }
-
-
-
- /* see if the cert is already there */
- targetCertID = PK11_FindCertInSlot(targetSlot, sourceCert, targetPwArg);
- if (targetCertID == CK_INVALID_HANDLE) {
- /* cert doesn't exist load the cert in. */
- /* OK for the nickname to be NULL, not all certs have nicknames */
- rv = PK11_ImportCert(targetSlot, sourceCert, CK_INVALID_HANDLE,
- nickname, PR_FALSE);
- goto done;
- }
-
- /* the cert already exists, see if the nickname and/or CKA_ID need
- * to be updated */
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- rv = SECFailure;
- goto done;
- }
-
- /* does our source have a CKA_ID ? */
- rv = PK11_GetAttributes(arena, sourceSlot, id, &sourceCKAID, 1);
- if (rv != SECSuccess) {
- sourceCKAID.ulValueLen = 0;
- }
-
- /* if we have a source CKA_ID, see of we need to update the
- * target's CKA_ID */
- if (sourceCKAID.ulValueLen != 0) {
- rv = PK11_GetAttributes(arena, targetSlot, targetCertID,
- &targetCKAID, 1);
- if (rv != SECSuccess) {
- targetCKAID.ulValueLen = 0;
- }
- /* if the target has no CKA_ID, update it from the source */
- if (targetCKAID.ulValueLen == 0) {
- lrv=pk11_setAttributes(targetSlot, targetCertID, &sourceCKAID, 1);
- if (lrv != SECSuccess) {
- error = PORT_GetError();
- }
- }
- }
- rv = SECSuccess;
-
- /* now check if we need to update the nickname */
- if (nickname && *nickname) {
- char *targetname;
- targetname = PK11_GetObjectNickname(targetSlot, targetCertID);
- if (!targetname || !*targetname) {
- /* target has no nickname, or it's empty, update it */
- rv = PK11_SetObjectNickname(targetSlot, targetCertID, nickname);
- }
- if (targetname) {
- PORT_Free(targetname);
- }
- }
-
- /* restore the error code if CKA_ID failed, but nickname didn't */
- if ((rv == SECSuccess) && (lrv != SECSuccess)) {
- rv = lrv;
- PORT_SetError(error);
- }
-
-done:
- if (nickname) {
- PORT_Free(nickname);
- }
- if (sourceCert) {
- CERT_DestroyCertificate(sourceCert);
- }
- if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
- }
- return rv;
-}
-
-
-/*************************************************************************
- *
- * Crls
- *
- *************************************************************************/
-
-/*
- * Use the raw PKCS #11 interface to merge the CRLs.
- *
- * In the case where of collision, choose the newest CRL that is valid.
- */
-static SECStatus
-pk11_mergeCrl(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
-{
- CK_OBJECT_HANDLE targetCrlID;
- PLArenaPool *arena = NULL;
- SECStatus rv = SECSuccess;
- CK_ATTRIBUTE crlTemplate[] = {
- { CKA_SUBJECT, NULL, 0 },
- { CKA_CLASS, NULL, 0 },
- { CKA_NSS_KRL, NULL, 0 }
- };
- CK_ULONG crlTemplateCount = sizeof(crlTemplate)/sizeof(crlTemplate[0]);
- CK_ATTRIBUTE crlCopyTemplate[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_TOKEN, NULL, 0 },
- { CKA_LABEL, NULL, 0 },
- { CKA_PRIVATE, NULL, 0 },
- { CKA_MODIFIABLE, NULL, 0 },
- { CKA_SUBJECT, NULL, 0 },
- { CKA_NSS_KRL, NULL, 0 },
- { CKA_NSS_URL, NULL, 0 },
- { CKA_VALUE, NULL, 0 }
- };
- CK_ULONG crlCopyTemplateCount =
- sizeof(crlCopyTemplate)/sizeof(crlCopyTemplate[0]);
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- rv = SECFailure;
- goto done;
- }
- /* check to see if the crl is already in the target slot */
- rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, crlTemplate,
- crlTemplateCount, id, &targetCrlID);
- if (rv != SECSuccess) {
- goto done;
- }
- if (targetCrlID != CK_INVALID_HANDLE) {
- /* we already have a CRL, check to see which is more up-to-date. */
- goto done;
- }
-
- /* load the CRL into the target token. */
- rv = pk11_copyAttributes(arena, targetSlot, targetCrlID, sourceSlot, id,
- crlCopyTemplate, crlCopyTemplateCount);
-done:
- if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
- }
- return rv;
-}
-
-/*************************************************************************
- *
- * SMIME objects
- *
- *************************************************************************/
-
-/*
- * use the raw PKCS #11 interface to merge the S/MIME records
- */
-static SECStatus
-pk11_mergeSmime(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
-{
- CK_OBJECT_HANDLE targetSmimeID;
- PLArenaPool *arena = NULL;
- SECStatus rv = SECSuccess;
- CK_ATTRIBUTE smimeTemplate[] = {
- { CKA_SUBJECT, NULL, 0 },
- { CKA_NSS_EMAIL, NULL, 0 },
- { CKA_CLASS, NULL, 0 },
- };
- CK_ULONG smimeTemplateCount =
- sizeof(smimeTemplate)/sizeof(smimeTemplate[0]);
- CK_ATTRIBUTE smimeCopyTemplate[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_TOKEN, NULL, 0 },
- { CKA_LABEL, NULL, 0 },
- { CKA_PRIVATE, NULL, 0 },
- { CKA_MODIFIABLE, NULL, 0 },
- { CKA_SUBJECT, NULL, 0 },
- { CKA_NSS_EMAIL, NULL, 0 },
- { CKA_NSS_SMIME_TIMESTAMP, NULL, 0 },
- { CKA_VALUE, NULL, 0 }
- };
- CK_ULONG smimeCopyTemplateCount =
- sizeof(smimeCopyTemplate)/sizeof(smimeCopyTemplate[0]);
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- rv = SECFailure;
- goto done;
- }
- /* check to see if the crl is already in the target slot */
- rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, smimeTemplate,
- smimeTemplateCount, id, &targetSmimeID);
- if (rv != SECSuccess) {
- goto done;
- }
- if (targetSmimeID != CK_INVALID_HANDLE) {
- /* we already have a SMIME record */
- goto done;
- }
-
- /* load the SMime Record into the target token. */
- rv = pk11_copyAttributes(arena, targetSlot, targetSmimeID, sourceSlot, id,
- smimeCopyTemplate, smimeCopyTemplateCount);
-done:
- if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
- }
- return rv;
-}
-
-/*************************************************************************
- *
- * Trust Objects
- *
- *************************************************************************/
-
-
-/*
- * decide which trust record entry wins. PR_TRUE (source) or PR_FALSE (target)
- */
-#define USE_TARGET PR_FALSE
-#define USE_SOURCE PR_TRUE
-PRBool
-pk11_mergeTrustEntry(CK_ATTRIBUTE *target, CK_ATTRIBUTE *source)
-{
- CK_ULONG targetTrust = (target->ulValueLen == sizeof (CK_LONG)) ?
- *(CK_ULONG *)target->pValue : CKT_NSS_TRUST_UNKNOWN;
- CK_ULONG sourceTrust = (source->ulValueLen == sizeof (CK_LONG)) ?
- *(CK_ULONG *)source->pValue : CKT_NSS_TRUST_UNKNOWN;
-
- /*
- * Examine a single entry and deside if the source or target version
- * should win out. When all the entries have been checked, if there is
- * any case we need to update, we will write the whole source record
- * to the target database. That means for each individual record, if the
- * target wins, we need to update the source (in case later we have a
- * case where the source wins). If the source wins, it already
- */
- if (sourceTrust == targetTrust) {
- return USE_TARGET; /* which equates to 'do nothing' */
- }
-
- if (sourceTrust == CKT_NSS_TRUST_UNKNOWN) {
- return USE_TARGET;
- }
-
- /* target has no idea, use the source's idea of the trust value */
- if (targetTrust == CKT_NSS_TRUST_UNKNOWN) {
- /* source overwrites the target */
- return USE_SOURCE;
- }
-
- /* so both the target and the source have some idea of what this
- * trust attribute should be, and neither agree exactly.
- * At this point, we prefer 'hard' attributes over 'soft' ones.
- * 'hard' ones are CKT_NSS_TRUSTED, CKT_NSS_TRUSTED_DELEGATOR, and
- * CKT_NSS_UNTRUTED. Soft ones are ones which don't change the
- * actual trust of the cert (CKT_MUST_VERIFY, CKT_NSS_VALID,
- * CKT_NSS_VALID_DELEGATOR).
- */
- if ((sourceTrust == CKT_NSS_MUST_VERIFY_TRUST)
- || (sourceTrust == CKT_NSS_VALID_DELEGATOR)) {
- return USE_TARGET;
- }
- if ((targetTrust == CKT_NSS_MUST_VERIFY_TRUST)
- || (targetTrust == CKT_NSS_VALID_DELEGATOR)) {
- /* source overrites the target */
- return USE_SOURCE;
- }
-
- /* both have hard attributes, we have a conflict, let the target win. */
- return USE_TARGET;
-}
-/*
- * use the raw PKCS #11 interface to merge the S/MIME records
- */
-static SECStatus
-pk11_mergeTrust(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
-{
- CK_OBJECT_HANDLE targetTrustID;
- PLArenaPool *arena = NULL;
- SECStatus rv = SECSuccess;
- int error = 0;
- CK_ATTRIBUTE trustTemplate[] = {
- { CKA_ISSUER, NULL, 0 },
- { CKA_SERIAL_NUMBER, NULL, 0 },
- { CKA_CLASS, NULL, 0 },
- };
- CK_ULONG trustTemplateCount =
- sizeof(trustTemplate)/sizeof(trustTemplate[0]);
- CK_ATTRIBUTE trustCopyTemplate[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_TOKEN, NULL, 0 },
- { CKA_LABEL, NULL, 0 },
- { CKA_PRIVATE, NULL, 0 },
- { CKA_MODIFIABLE, NULL, 0 },
- { CKA_ISSUER, NULL, 0},
- { CKA_SERIAL_NUMBER, NULL, 0},
- { CKA_CERT_SHA1_HASH, NULL, 0 },
- { CKA_CERT_MD5_HASH, NULL, 0 },
- { CKA_TRUST_SERVER_AUTH, NULL, 0 },
- { CKA_TRUST_CLIENT_AUTH, NULL, 0 },
- { CKA_TRUST_CODE_SIGNING, NULL, 0 },
- { CKA_TRUST_EMAIL_PROTECTION, NULL, 0 },
- { CKA_TRUST_STEP_UP_APPROVED, NULL, 0 }
- };
- CK_ULONG trustCopyTemplateCount =
- sizeof(trustCopyTemplate)/sizeof(trustCopyTemplate[0]);
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- rv = SECFailure;
- goto done;
- }
- /* check to see if the crl is already in the target slot */
- rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, trustTemplate,
- trustTemplateCount, id, &targetTrustID);
- if (rv != SECSuccess) {
- goto done;
- }
- if (targetTrustID != CK_INVALID_HANDLE) {
- /* a matching trust record already exists, merge it in */
- CK_ATTRIBUTE_TYPE trustAttrs[] = {
- CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH,
- CKA_TRUST_CODE_SIGNING, CKA_TRUST_EMAIL_PROTECTION,
- CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER,
- CKA_TRUST_TIME_STAMPING
- };
- CK_ULONG trustAttrsCount =
- sizeof(trustAttrs)/sizeof(trustAttrs[0]);
-
- CK_ULONG i;
- CK_ATTRIBUTE targetTemplate, sourceTemplate;
-
- /* existing trust record, merge the two together */
- for (i=0; i < trustAttrsCount; i++) {
- targetTemplate.type = sourceTemplate.type = trustAttrs[i];
- targetTemplate.pValue = sourceTemplate.pValue = NULL;
- targetTemplate.ulValueLen = sourceTemplate.ulValueLen = 0;
- PK11_GetAttributes(arena, sourceSlot, id, &sourceTemplate, 1);
- PK11_GetAttributes(arena, targetSlot, targetTrustID,
- &targetTemplate, 1);
- if (pk11_mergeTrustEntry(&targetTemplate, &sourceTemplate)) {
- /* source wins, write out the source attribute to the target */
- SECStatus lrv = pk11_setAttributes(targetSlot, targetTrustID,
- &sourceTemplate, 1);
- if (lrv != SECSuccess) {
- rv = SECFailure;
- error = PORT_GetError();
- }
- }
- }
-
- /* handle step */
- sourceTemplate.type = CKA_TRUST_STEP_UP_APPROVED;
- sourceTemplate.pValue = NULL;
- sourceTemplate.ulValueLen = 0;
-
- /* if the source has steup set, then set it in the target */
- PK11_GetAttributes(arena, sourceSlot, id, &sourceTemplate, 1);
- if ((sourceTemplate.ulValueLen == sizeof(CK_BBOOL)) &&
- (sourceTemplate.pValue) &&
- (*(CK_BBOOL *)sourceTemplate.pValue == CK_TRUE)) {
- SECStatus lrv = pk11_setAttributes(targetSlot, targetTrustID,
- &sourceTemplate, 1);
- if (lrv != SECSuccess) {
- rv = SECFailure;
- error = PORT_GetError();
- }
- }
-
- goto done;
-
- }
-
- /* load the new trust Record into the target token. */
- rv = pk11_copyAttributes(arena, targetSlot, targetTrustID, sourceSlot, id,
- trustCopyTemplate, trustCopyTemplateCount);
-done:
- if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
- }
-
- /* restore the error code */
- if (rv == SECFailure && error) {
- PORT_SetError(error);
- }
-
- return rv;
-}
-
-/*************************************************************************
- *
- * Central merge code
- *
- *************************************************************************/
-/*
- * merge a single object from sourceToken to targetToken
- */
-static SECStatus
-pk11_mergeObject(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
-{
-
- CK_OBJECT_CLASS objClass;
-
-
- objClass = PK11_ReadULongAttribute(sourceSlot, id, CKA_CLASS);
- if (objClass == (CK_ULONG) -1) {
- PORT_SetError( SEC_ERROR_UNKNOWN_OBJECT_TYPE );
- return SECFailure;
- }
-
- switch (objClass) {
- case CKO_CERTIFICATE:
- return pk11_mergeCert(targetSlot, sourceSlot, id,
- targetPwArg, sourcePwArg);
- case CKO_NSS_TRUST:
- return pk11_mergeTrust(targetSlot, sourceSlot, id,
- targetPwArg, sourcePwArg);
- case CKO_PUBLIC_KEY:
- return pk11_mergePublicKey(targetSlot, sourceSlot, id,
- targetPwArg, sourcePwArg);
- case CKO_PRIVATE_KEY:
- return pk11_mergePrivateKey(targetSlot, sourceSlot, id,
- targetPwArg, sourcePwArg);
- case CKO_SECRET_KEY:
- return pk11_mergeSecretKey(targetSlot, sourceSlot, id,
- targetPwArg, sourcePwArg);
- case CKO_NSS_CRL:
- return pk11_mergeCrl(targetSlot, sourceSlot, id,
- targetPwArg, sourcePwArg);
- case CKO_NSS_SMIME:
- return pk11_mergeSmime(targetSlot, sourceSlot, id,
- targetPwArg, sourcePwArg);
- default:
- break;
- }
-
- PORT_SetError( SEC_ERROR_UNKNOWN_OBJECT_TYPE );
- return SECFailure;
-}
-
-PK11MergeLogNode *
-pk11_newMergeLogNode(PLArenaPool *arena,
- PK11SlotInfo *slot, CK_OBJECT_HANDLE id, int error)
-{
- PK11MergeLogNode *newLog;
- PK11GenericObject *obj;
-
- newLog = PORT_ArenaZNew(arena, PK11MergeLogNode);
- if (newLog == NULL) {
- return NULL;
- }
-
- obj = PORT_ArenaZNew(arena, PK11GenericObject);
- if ( !obj ) {
- return NULL;
- }
-
- /* initialize it */
- obj->slot = slot;
- obj->objectID = id;
-
- newLog->object= obj;
- newLog->error = error;
- return newLog;
-}
-
-/*
- * walk down each entry and merge it. keep track of the errors in the log
- */
-static SECStatus
-pk11_mergeByObjectIDs(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE *objectIDs, int count,
- PK11MergeLog *log, void *targetPwArg, void *sourcePwArg)
-{
- SECStatus rv = SECSuccess;
- int error = SEC_ERROR_LIBRARY_FAILURE;
- int i;
-
- for (i=0; i < count; i++) {
- /* try to update the entire database. On failure, keep going,
- * but remember the error to report back to the caller */
- SECStatus lrv;
- PK11MergeLogNode *newLog;
-
- lrv= pk11_mergeObject(targetSlot, sourceSlot, objectIDs[i],
- targetPwArg, sourcePwArg);
- if (lrv == SECSuccess) {
- /* merged with no problem, go to next object */
- continue;
- }
-
- /* remember that we failed and why */
- rv = SECFailure;
- error = PORT_GetError();
-
- /* log the errors */
- if (!log) {
- /* not logging, go to next entry */
- continue;
- }
- newLog = pk11_newMergeLogNode(log->arena, sourceSlot,
- objectIDs[i], error);
- if (!newLog) {
- /* failed to allocate entry, just keep going */
- continue;
- }
-
- /* link in the errorlog entry */
- newLog->next = NULL;
- if (log->tail) {
- log->tail->next = newLog;
- } else {
- log->head = newLog;
- }
- newLog->prev = log->tail;
- log->tail = newLog;
- }
-
- /* restore the last error code */
- if (rv != SECSuccess) {
- PORT_SetError(error);
- }
- return rv;
-}
-
-/*
- * Merge all the records in sourceSlot that aren't in targetSlot
- *
- * This function will return failure if not all the objects
- * successfully merged.
- *
- * Applications can pass in an optional error log which will record
- * each failing object and why it failed to import. PK11MergeLog
- * is modelled after the CERTVerifyLog.
- */
-SECStatus
-PK11_MergeTokens(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- PK11MergeLog *log, void *targetPwArg, void *sourcePwArg)
-{
- SECStatus rv = SECSuccess, lrv = SECSuccess;
- int error = SEC_ERROR_LIBRARY_FAILURE;
- int count = 0;
- CK_ATTRIBUTE search[2];
- CK_OBJECT_HANDLE *objectIDs = NULL;
- CK_BBOOL ck_true = CK_TRUE;
- CK_OBJECT_CLASS privKey = CKO_PRIVATE_KEY;
-
- PK11_SETATTRS(&search[0], CKA_TOKEN, &ck_true, sizeof(ck_true));
- PK11_SETATTRS(&search[1], CKA_CLASS, &privKey, sizeof(privKey));
- /*
- * make sure both tokens are already authenticated if need be.
- */
- rv = PK11_Authenticate(targetSlot, PR_TRUE, targetPwArg);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = PK11_Authenticate(sourceSlot, PR_TRUE, sourcePwArg);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /* turns out the old DB's are rather fragile if the private keys aren't
- * merged in first, so do the private keys explicity. */
- objectIDs = pk11_FindObjectsByTemplate(sourceSlot, search, 2, &count);
- if (objectIDs) {
- lrv = pk11_mergeByObjectIDs(targetSlot, sourceSlot,
- objectIDs, count, log,
- targetPwArg, sourcePwArg);
- if (lrv != SECSuccess) {
- error = PORT_GetError();
- }
- PORT_Free(objectIDs);
- count = 0;
- }
-
- /* now do the rest (NOTE: this will repeat the private keys, but
- * that shouldnt' be an issue as we will notice they are already
- * merged in */
- objectIDs = pk11_FindObjectsByTemplate(sourceSlot, search, 1, &count);
- if (!objectIDs) {
- rv = SECFailure;
- goto loser;
- }
-
- rv = pk11_mergeByObjectIDs(targetSlot, sourceSlot, objectIDs, count, log,
- targetPwArg, sourcePwArg);
- if (rv == SECSuccess) {
- /* if private keys failed, but the rest succeeded, be sure to let
- * the caller know that private keys failed and why.
- * NOTE: this is highly unlikely since the same keys that failed
- * in the previous merge call will most likely fail in this one */
- if (lrv != SECSuccess) {
- rv = lrv;
- PORT_SetError(error);
- }
- }
-
-loser:
- if (objectIDs) {
- PORT_Free(objectIDs);
- }
- return rv;
-}
-
-PK11MergeLog *
-PK11_CreateMergeLog(void)
-{
- PLArenaPool *arena;
- PK11MergeLog *log;
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- return NULL;
- }
-
- log = PORT_ArenaZNew(arena, PK11MergeLog);
- if (log == NULL) {
- PORT_FreeArena(arena,PR_FALSE);
- return NULL;
- }
- log->arena = arena;
- log->version = 1;
- return log;
-}
-
-void
-PK11_DestroyMergeLog(PK11MergeLog *log)
-{
- if (log && log->arena) {
- PORT_FreeArena(log->arena, PR_FALSE);
- }
-}
« no previous file with comments | « nss/lib/pk11wrap/pk11mech.c ('k') | nss/lib/pk11wrap/pk11nobj.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698