summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthayes%netscape.com <devnull@localhost>2000-06-10 19:00:45 +0000
committerthayes%netscape.com <devnull@localhost>2000-06-10 19:00:45 +0000
commit779b2555bb69fda1a21e3d494b4a1aac2e662f9d (patch)
treef2be9df2f1092d66345ebff4712687438e442b87
parent09d7413f35b2d70553a53db04e9ee6ee5488f3c8 (diff)
parentbd042e2db48225ac17f436ba5347b365a7a1c422 (diff)
downloadnss-hg-779b2555bb69fda1a21e3d494b4a1aac2e662f9d.tar.gz
Add permanent (token) key for supporting Secret Decoder Ring (SDR)
Bug 26085
-rw-r--r--security/nss/lib/pk11wrap/pk11func.h4
-rw-r--r--security/nss/lib/pk11wrap/pk11sdr.c17
-rw-r--r--security/nss/lib/pk11wrap/pk11skey.c106
-rw-r--r--security/nss/lib/softoken/pkcs11.c328
4 files changed, 397 insertions, 58 deletions
diff --git a/security/nss/lib/pk11wrap/pk11func.h b/security/nss/lib/pk11wrap/pk11func.h
index a6a6b5a0f..21003d1ce 100644
--- a/security/nss/lib/pk11wrap/pk11func.h
+++ b/security/nss/lib/pk11wrap/pk11func.h
@@ -233,6 +233,10 @@ CK_OBJECT_HANDLE PK11_ImportPublicKey(PK11SlotInfo *slot,
SECKEYPublicKey *pubKey, PRBool isToken);
PK11SymKey *PK11_KeyGen(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
SECItem *param, int keySize,void *wincx);
+
+/* Key Generation specialized for SDR (fixed DES3 key) */
+PK11SymKey *PK11_GenDES3TokenKey(PK11SlotInfo *slot, SECItem *keyid, void *cx);
+
SECStatus PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey,
PK11SymKey *symKey, SECItem *wrappedKey);
SECStatus PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *params,
diff --git a/security/nss/lib/pk11wrap/pk11sdr.c b/security/nss/lib/pk11wrap/pk11sdr.c
index 460591835..07d9c1354 100644
--- a/security/nss/lib/pk11wrap/pk11sdr.c
+++ b/security/nss/lib/pk11wrap/pk11sdr.c
@@ -63,8 +63,8 @@ static SEC_ASN1Template template[] = {
};
static unsigned char keyID[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
};
static SECItem keyIDItem = {
@@ -168,9 +168,18 @@ PK11SDR_Encrypt(SECItem *keyid, SECItem *data, SECItem *result, void *cx)
/* Find the key to use */
pKeyID = keyid;
- if (pKeyID->len == 0) pKeyID = &keyIDItem; /* Use default value */
+ if (pKeyID->len == 0) {
+ pKeyID = &keyIDItem; /* Use default value */
+
+ /* Try to find the key */
+ key = PK11_FindFixedKey(slot, type, pKeyID, cx);
+
+ /* If the default key doesn't exist yet, try to create it */
+ if (!key) key = PK11_GenDES3TokenKey(slot, pKeyID, cx);
+ } else {
+ key = PK11_FindFixedKey(slot, type, pKeyID, cx);
+ }
- key = PK11_FindFixedKey(slot, type, pKeyID, cx);
if (!key) { rv = SECFailure; goto loser; }
params = PK11_GenerateNewParam(type, key);
diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c
index 63c13527a..52f2ce30d 100644
--- a/security/nss/lib/pk11wrap/pk11skey.c
+++ b/security/nss/lib/pk11wrap/pk11skey.c
@@ -130,6 +130,7 @@ PK11_CreateNewObject(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
PORT_SetError( PK11_MapError(crv) );
rv = SECFailure;
}
+
if (session == CK_INVALID_SESSION) {
if (token) {
PK11_RestoreROSession(slot, rwsession);
@@ -137,6 +138,7 @@ PK11_CreateNewObject(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
PK11_ExitSlotMonitor(slot);
}
}
+
return rv;
}
@@ -1132,58 +1134,78 @@ pk11_ForceSlot(PK11SymKey *symKey,CK_MECHANISM_TYPE type,
* from this interface!
*/
PK11SymKey *
-PK11_KeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
- int keySize, void *wincx)
+PK11_TokenKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
+ int keySize, SECItem *keyid, PRBool isToken, void *wincx)
{
- CK_ULONG key_size = 0;
- /* we have to use these native types because when we call PKCS 11 modules
- * we have to make sure that we are using the correct sizes for all the
- * parameters. */
- CK_BBOOL ckfalse = CK_FALSE;
- CK_BBOOL cktrue = CK_TRUE;
- CK_ATTRIBUTE genTemplate[2];
+ PK11SymKey *symKey;
+ CK_ATTRIBUTE genTemplate[4];
+ CK_ATTRIBUTE *attrs = genTemplate;
int count = sizeof(genTemplate)/sizeof(genTemplate[0]);
+ CK_SESSION_HANDLE session;
CK_MECHANISM mechanism;
- CK_MECHANISM_TYPE key_gen_mechanism;
- PK11SymKey *symKey;
CK_RV crv;
- CK_ATTRIBUTE *attrs = genTemplate;
PRBool weird = PR_FALSE; /* hack for fortezza */
+ CK_BBOOL ckfalse = CK_FALSE;
+ CK_BBOOL cktrue = CK_TRUE;
if ((keySize == -1) && (type == CKM_SKIPJACK_CBC64)) {
weird = PR_TRUE;
keySize = 0;
}
+ /* TNH: Isn't this redundant, since "handleKey" will set defaults? */
PK11_SETATTRS(attrs, (!weird)
? CKA_ENCRYPT : CKA_DECRYPT, &cktrue, sizeof(CK_BBOOL)); attrs++;
- key_size = keySize;
- if (key_size != 0) {
+
+ if (keySize != 0) {
+ CK_ULONG key_size = keySize; /* Convert to PK11 type */
+
PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size));
attrs++;
}
+
+ /* Include key id value if provided */
+ if (keyid) {
+ PK11_SETATTRS(attrs, CKA_ID, keyid->data, keyid->len); attrs++;
+ }
+
+ if (isToken) {
+ PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue)); attrs++;
+ }
+
count = attrs - genTemplate;
PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE));
/* find a slot to generate the key into */
- if ((slot == NULL) || (!PK11_DoesMechanism(slot,type))) {
- slot = PK11_GetBestSlot(type,wincx);
- if (slot == NULL) {
+ /* Only do slot management if this is not a token key */
+ if (!isToken && (slot == NULL || !PK11_DoesMechanism(slot,type))) {
+ PK11SlotInfo *bestSlot;
+
+ bestSlot = PK11_GetBestSlot(type,wincx); /* TNH: references the slot? */
+ if (bestSlot == NULL) {
PORT_SetError( SEC_ERROR_NO_MODULE );
return NULL;
}
+
+ symKey = PK11_CreateSymKey(bestSlot,type,wincx);
+
+ PK11_FreeSlot(bestSlot);
} else {
- PK11_ReferenceSlot(slot);
+ symKey = PK11_CreateSymKey(slot, type, wincx);
}
+ if (symKey == NULL) return NULL;
+
+ symKey->size = keySize;
+ symKey->origin = (!weird) ? PK11_OriginGenerated : PK11_OriginFortezzaHack;
/* Initialize the Key Gen Mechanism */
- key_gen_mechanism = PK11_GetKeyGen(type);
- if (key_gen_mechanism == CKM_FAKE_RANDOM) {
- PK11_FreeSlot(slot);
+ mechanism.mechanism = PK11_GetKeyGen(type);
+ if (mechanism.mechanism == CKM_FAKE_RANDOM) {
PORT_SetError( SEC_ERROR_NO_MODULE );
return NULL;
}
- mechanism.mechanism = key_gen_mechanism;
+
+ /* Set the parameters for the key gen if provided */
mechanism.pParameter = NULL;
mechanism.ulParameterLen = 0;
if (param) {
@@ -1191,27 +1213,47 @@ PK11_KeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
mechanism.ulParameterLen = param->len;
}
- /* get our key Structure */
- symKey = PK11_CreateSymKey(slot,type,wincx);
- PK11_FreeSlot(slot);
- if (symKey == NULL) {
- return NULL;
+ /* Get session and perform locking */
+ if (isToken) {
+ session = PK11_GetRWSession(symKey->slot); /* Should always be original slot */
+ } else {
+ session = symKey->session;
+ pk11_EnterKeyMonitor(symKey);
}
- symKey->size = keySize;
- symKey->origin = (!weird) ? PK11_OriginGenerated : PK11_OriginFortezzaHack;
- pk11_EnterKeyMonitor(symKey);
- crv = PK11_GETTAB(symKey->slot)->C_GenerateKey(symKey->session,
+ crv = PK11_GETTAB(symKey->slot)->C_GenerateKey(session,
&mechanism, genTemplate, count, &symKey->objectID);
- pk11_ExitKeyMonitor(symKey);
+
+ /* Release lock and session */
+ if (isToken) {
+ PK11_RestoreROSession(symKey->slot, session);
+ } else {
+ pk11_ExitKeyMonitor(symKey);
+ }
+
if (crv != CKR_OK) {
PK11_FreeSymKey(symKey);
PORT_SetError( PK11_MapError(crv) );
return NULL;
}
+
return symKey;
}
+PK11SymKey *
+PK11_KeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
+ int keySize, void *wincx)
+{
+ return PK11_TokenKeyGen(slot, type, param, keySize, 0, PR_FALSE, wincx);
+}
+
+/* --- */
+PK11SymKey *
+PK11_GenDES3TokenKey(PK11SlotInfo *slot, SECItem *keyid, void *cx)
+{
+ return PK11_TokenKeyGen(slot, CKM_DES3_CBC, 0, 0, keyid, PR_TRUE, cx);
+}
+
/*
* PKCS #11 pairwise consistency check utilized to validate key pair.
*/
diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c
index fee744351..fc70b782a 100644
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -966,19 +966,16 @@ pk11_handlePrivateKeyObject(PK11Object *object,CK_KEY_TYPE key_type)
/* forward delcare the DES formating function for handleSecretKey */
void pk11_FormatDESKey(unsigned char *key, int length);
+static SECKEYLowPrivateKey *pk11_mkSecretKeyRep(PK11Object *object);
-/*
- * check the consistancy and initialize a Secret Key Object
- */
+/* Validate secret key data, and set defaults */
static CK_RV
-pk11_handleSecretKeyObject(PK11Object *object,CK_KEY_TYPE key_type,
- PRBool isFIPS)
+validateSecretKey(PK11Object *object, CK_KEY_TYPE key_type, PRBool isFIPS)
{
CK_RV crv;
CK_BBOOL cktrue = CK_TRUE;
CK_BBOOL ckfalse = CK_FALSE;
PK11Attribute *attribute = NULL;
-
crv = pk11_defaultAttribute(object,CKA_SENSITIVE,
isFIPS?&cktrue:&ckfalse,sizeof(CK_BBOOL));
if (crv != CKR_OK) return crv;
@@ -1045,6 +1042,53 @@ pk11_handleSecretKeyObject(PK11Object *object,CK_KEY_TYPE key_type,
return crv;
}
+/*
+ * check the consistancy and initialize a Secret Key Object
+ */
+static CK_RV
+pk11_handleSecretKeyObject(PK11Object *object,CK_KEY_TYPE key_type,
+ PRBool isFIPS)
+{
+ CK_RV crv;
+ CK_BBOOL cktrue = CK_TRUE;
+ CK_BBOOL ckfalse = CK_FALSE;
+ PK11Attribute *attribute = NULL;
+ SECKEYLowPrivateKey *privKey = NULL;
+ SECItem pubKey;
+
+ pubKey.data = 0;
+
+ /* First validate and set defaults */
+ crv = validateSecretKey(object, key_type, isFIPS);
+ if (crv != CKR_OK) goto loser;
+
+ /* If the object is a TOKEN object, store in the database */
+ if (pk11_isTrue(object,CKA_TOKEN)) {
+ char *label;
+ SECStatus rv = SECSuccess;
+
+ privKey=pk11_mkSecretKeyRep(object);
+ if (privKey == NULL) return CKR_HOST_MEMORY;
+
+ label = object->label = pk11_getString(object,CKA_LABEL);
+
+ crv = pk11_Attribute2SecItem(NULL,&pubKey,object,CKA_ID); /* Should this be ID? */
+ if (crv != CKR_OK) goto loser;
+
+ rv = SECKEY_StoreKeyByPublicKey(SECKEY_GetDefaultKeyDB(),
+ privKey, &pubKey, label,
+ (SECKEYGetPasswordKey) pk11_givePass, object->slot);
+
+ object->inDB = PR_TRUE;
+ object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
+ }
+
+loser:
+ if (privKey) SECKEY_LowDestroyPrivateKey(privKey);
+ if (pubKey.data) PORT_Free(pubKey.data);
+
+ return crv;
+}
/*
* check the consistancy and initialize a Key Object
@@ -1058,18 +1102,6 @@ pk11_handleKeyObject(PK11Session *session, PK11Object *object)
CK_BBOOL ckfalse = CK_FALSE;
CK_RV crv;
- /* Only private keys can be private or token */
- if ((object->objclass != CKO_PRIVATE_KEY) && (object->objclass != CKO_PUBLIC_KEY)
- &&
- (pk11_isTrue(object,CKA_PRIVATE) || pk11_isTrue(object,CKA_TOKEN))) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- /* Make sure that the private key is CKA_PRIVATE if it's a token */
- if (pk11_isTrue(object,CKA_TOKEN) && (object->objclass == CKO_SECRET_KEY)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
/* verify the required fields */
if ( !pk11_hasAttribute(object,CKA_KEY_TYPE) ) {
return CKR_TEMPLATE_INCOMPLETE;
@@ -2067,16 +2099,174 @@ pk11_IsWeakKey(unsigned char *key,CK_KEY_TYPE key_type)
}
-
+/* make a fake private key representing a symmetric key */
+static SECKEYLowPrivateKey *
+pk11_mkSecretKeyRep(PK11Object *object)
+{
+ SECKEYLowPrivateKey *privKey;
+ PLArenaPool *arena = 0;
+ CK_RV crv;
+ SECStatus rv;
+ static unsigned char derZero[1] = { 0 };
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena == NULL) { crv = CKR_HOST_MEMORY; goto loser; }
+
+ privKey = (SECKEYLowPrivateKey *)
+ PORT_ArenaAlloc(arena,sizeof(SECKEYLowPrivateKey));
+ if (privKey == NULL) { crv = CKR_HOST_MEMORY; goto loser; }
+
+ privKey->arena = arena;
+
+ /* Secret keys are represented in the database as "fake" RSA keys. The RSA key
+ * is marked as a secret key representation by setting the public exponent field
+ * to 0, which is an invalid RSA exponent. The other fields are set as follows:
+ * modulus - CKA_ID value for the secret key
+ * private exponent - CKA_VALUE (the key itself)
+ * coefficient - CKA_KEY_TYPE, which indicates what encryption algorithm
+ * is used for the key.
+ * all others - set to integer 0
+ */
+ privKey->keyType = rsaKey;
+
+ /* The modulus is set to the key id of the symmetric key */
+ crv=pk11_Attribute2SecItem(arena,&privKey->u.rsa.modulus,object,CKA_ID);
+ if (crv != CKR_OK) goto loser;
+
+ /* The public exponent is set to 0 length to indicate a special key */
+ privKey->u.rsa.publicExponent.len = sizeof derZero;
+ privKey->u.rsa.publicExponent.data = derZero;
+
+ /* The private exponent is the actual key value */
+ crv=pk11_Attribute2SecItem(arena,&privKey->u.rsa.privateExponent,object,CKA_VALUE);
+ if (crv != CKR_OK) goto loser;
+
+ /* All other fields empty - needs testing */
+ privKey->u.rsa.prime1.len = sizeof derZero;
+ privKey->u.rsa.prime1.data = derZero;
+
+ privKey->u.rsa.prime2.len = sizeof derZero;
+ privKey->u.rsa.prime2.data = derZero;
+
+ privKey->u.rsa.exponent1.len = sizeof derZero;
+ privKey->u.rsa.exponent1.data = derZero;
+
+ privKey->u.rsa.exponent2.len = sizeof derZero;
+ privKey->u.rsa.exponent2.data = derZero;
+
+ /* Coeficient set to KEY_TYPE */
+ crv=pk11_Attribute2SecItem(arena,&privKey->u.rsa.coefficient,object,CKA_KEY_TYPE);
+ if (crv != CKR_OK) goto loser;
+
+ /* Private key version field set normally for compatibility */
+ rv = DER_SetUInteger(privKey->arena, &privKey->u.rsa.version,SEC_PRIVATE_KEY_VERSION);
+ if (rv != SECSuccess) { crv = CKR_HOST_MEMORY; goto loser; }
+
+loser:
+ if (crv != CKR_OK) {
+ PORT_FreeArena(arena,PR_FALSE);
+ privKey = 0;
+ }
+
+ return privKey;
+}
+
+static PRBool
+isSecretKey(SECKEYLowPrivateKey *privKey)
+{
+ if (privKey->keyType == rsaKey && privKey->u.rsa.publicExponent.len == 1 &&
+ privKey->u.rsa.publicExponent.data[0] == 0)
+ return PR_TRUE;
+
+ return PR_FALSE;
+}
+
+/* Import a Secret Key */
+static PRBool
+importSecretKey(PK11Slot *slot, SECKEYLowPrivateKey *priv)
+{
+ PK11Object *object;
+ CK_OBJECT_CLASS secretClass = CKO_SECRET_KEY;
+ CK_BBOOL cktrue = CK_TRUE;
+ CK_BBOOL ckfalse = CK_FALSE;
+ CK_KEY_TYPE key_type;
+
+ /* Check for secret key representation, return if it isn't one */
+ if (!isSecretKey(priv))
+ return PR_FALSE;
+
+ /*
+ * now lets create an object to hang the attributes off of
+ */
+ object = pk11_NewObject(slot); /* fill in the handle later */
+ if (object == NULL) {
+ goto loser;
+ }
+
+ /* Set the ID value */
+ if (pk11_AddAttributeType(object, CKA_ID,
+ priv->u.rsa.modulus.data, priv->u.rsa.modulus.len)) {
+ pk11_FreeObject(object);
+ goto loser;
+ }
+
+ /* initalize the object attributes */
+ if (pk11_AddAttributeType(object, CKA_CLASS, &secretClass,
+ sizeof(secretClass)) != CKR_OK) {
+ pk11_FreeObject(object);
+ goto loser;
+ }
+
+ if (pk11_AddAttributeType(object, CKA_TOKEN, &cktrue,
+ sizeof(cktrue)) != CKR_OK) {
+ pk11_FreeObject(object);
+ goto loser;
+ }
+
+ if (pk11_AddAttributeType(object, CKA_PRIVATE, &ckfalse,
+ sizeof(CK_BBOOL)) != CKR_OK) {
+ pk11_FreeObject(object);
+ goto loser;
+ }
+
+ if (pk11_AddAttributeType(object, CKA_VALUE,
+ pk11_item_expand(&priv->u.rsa.privateExponent)) != CKR_OK) {
+ pk11_FreeObject(object);
+ goto loser;
+ }
+
+ if (pk11_AddAttributeType(object, CKA_KEY_TYPE,
+ pk11_item_expand(&priv->u.rsa.coefficient)) != CKR_OK) {
+ pk11_FreeObject(object);
+ goto loser;
+ }
+ key_type = *(CK_KEY_TYPE*)priv->u.rsa.coefficient.data;
+
+ /* Validate and add default attributes */
+ validateSecretKey(object, key_type, (PRBool)(slot->slotID == FIPS_SLOT_ID));
+
+ /* now just verify the required date fields */
+ PK11_USE_THREADS(PR_Lock(slot->objectLock);)
+ object->handle = slot->tokenIDCount++;
+ object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
+ PK11_USE_THREADS(PR_Unlock(slot->objectLock);)
+
+ object->objclass = secretClass;
+ object->slot = slot;
+ object->inDB = PR_TRUE;
+ pk11_AddSlotObject(slot, object);
+
+loser:
+ return PR_TRUE;
+}
+
/**********************************************************************
*
* Start of PKCS 11 functions
*
**********************************************************************/
-
-
-
+
/* return the function list */
CK_RV NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
@@ -3316,6 +3506,94 @@ decodeKeyDBGlobalSalt(DBT *saltData)
}
#endif
+#if 0
+/*
+ * Create a (fixed) DES3 key [ testing ]
+ */
+static unsigned char keyValue[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17
+};
+
+static SECItem keyItem = {
+ 0,
+ keyValue,
+ sizeof keyValue
+};
+
+static unsigned char keyID[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static SECItem keyIDItem = {
+ 0,
+ keyID,
+ sizeof keyID
+};
+/* +AAA */
+static CK_RV
+pk11_createFixedDES3Key(PK11Slot *slot)
+{
+ CK_RV rv = CKR_OK;
+ PK11Object *keyObject;
+ CK_BBOOL true = CK_TRUE;
+ CK_OBJECT_CLASS class = CKO_SECRET_KEY;
+ CK_KEY_TYPE keyType = CKK_DES3;
+
+ /*
+ * Create the object
+ */
+ keyObject = pk11_NewObject(slot); /* fill in the handle later */
+ if (keyObject == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+
+ /* Add attributes to the object */
+ rv = pk11_AddAttributeType(keyObject, CKA_ID, keyID, sizeof keyID);
+ if (rv != CKR_OK) {
+ pk11_FreeObject(keyObject);
+ return rv;
+ }
+
+ rv = pk11_AddAttributeType(keyObject, CKA_VALUE, keyValue, sizeof keyValue);
+ if (rv != CKR_OK) {
+ pk11_FreeObject(keyObject);
+ return rv;
+ }
+
+ rv = pk11_AddAttributeType(keyObject, CKA_TOKEN, &true, sizeof true);
+ if (rv != CKR_OK) {
+ pk11_FreeObject(keyObject);
+ return rv;
+ }
+
+ rv = pk11_AddAttributeType(keyObject, CKA_CLASS, &class, sizeof class);
+ if (rv != CKR_OK) {
+ pk11_FreeObject(keyObject);
+ return rv;
+ }
+
+ rv = pk11_AddAttributeType(keyObject, CKA_KEY_TYPE, &keyType, sizeof keyType);
+ if (rv != CKR_OK) {
+ pk11_FreeObject(keyObject);
+ return rv;
+ }
+
+ pk11_handleSecretKeyObject(keyObject, keyType, PR_TRUE);
+
+ PK11_USE_THREADS(PR_Lock(slot->objectLock);)
+ keyObject->handle = slot->tokenIDCount++;
+ PK11_USE_THREADS(PR_Unlock(slot->objectLock);)
+ keyObject->slot = slot;
+ keyObject->objclass = CKO_SECRET_KEY;
+ pk11_AddSlotObject(slot, keyObject);
+
+ return rv;
+}
+#endif /* Fixed DES key */
+
/*
* load up our token database
*/
@@ -3360,6 +3638,11 @@ pk11_importKeyDB(PK11Slot *slot)
* pkcs11 world
*/
for (node = keylist.head; node != NULL; node=node->next ) {
+ /* Check for "special" private key that wraps a symmetric key */
+ if (isSecretKey(node->privKey)) {
+ importSecretKey(slot, node->privKey);
+ goto end_loop;
+ }
/* create the private key object */
privateKeyObject = pk11_importPrivateKey(slot, node->privKey,
@@ -3410,6 +3693,7 @@ end_loop:
}
PORT_FreeArena(keylist.arena, PR_FALSE);
+
return CKR_OK;
}