/* * create a new context which is the clone of the state of old context. */ PK11Context * PK11_CloneContext(PK11Context *old) { PK11Context *newcx; PRBool needFree = PR_FALSE; SECStatus rv = SECSuccess; void *data; unsigned long len; newcx = pk11_CreateNewContextInSlot(old->type, old->slot, old->operation, old->key, old->param); if (newcx == NULL) return NULL; /* now clone the save state. First we need to find the save state * of the old session. If the old context owns it's session, * the state needs to be saved, otherwise the state is in saveData. */ if (old->ownSession) { PK11_EnterContextMonitor(old); data = pk11_saveContext(old, NULL, &len); PK11_ExitContextMonitor(old); needFree = PR_TRUE; } else { data = old->savedData; len = old->savedLength; } if (data == NULL) { PK11_DestroyContext(newcx, PR_TRUE); return NULL; } /* now copy that state into our new context. Again we have different * work if the new context owns it's own session. If it does, we * restore the state gathered above. If it doesn't, we copy the * saveData pointer... */ if (newcx->ownSession) { PK11_EnterContextMonitor(newcx); rv = pk11_restoreContext(newcx, data, len); PK11_ExitContextMonitor(newcx); } else { PORT_Assert(newcx->savedData != NULL); if ((newcx->savedData == NULL) || (newcx->savedLength < len)) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); rv = SECFailure; } else { PORT_Memcpy(newcx->savedData, data, len); newcx->savedLength = len; } } if (needFree) PORT_Free(data); if (rv != SECSuccess) { PK11_DestroyContext(newcx, PR_TRUE); return NULL; } return newcx; }
/* * Digest contexts don't need keys, but the do need to find a slot. * Macing should use PK11_CreateContextBySymKey. */ PK11Context * PK11_CreateDigestContext(SECOidTag hashAlg) { /* digesting has to work without authentication to the slot */ CK_MECHANISM_TYPE type; PK11SlotInfo *slot; PK11Context *context; SECItem param; type = PK11_AlgtagToMechanism(hashAlg); slot = PK11_GetBestSlot(type, NULL); if (slot == NULL) { PORT_SetError( SEC_ERROR_NO_MODULE ); return NULL; } /* maybe should really be PK11_GenerateNewParam?? */ param.data = NULL; param.len = 0; param.type = 0; context = pk11_CreateNewContextInSlot(type, slot, CKA_DIGEST, NULL, ¶m); PK11_FreeSlot(slot); return context; }
/* * Create a context from a key. We really should make sure we aren't using * the same key in multiple session! */ PK11Context * PK11_CreateContextBySymKey(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey, SECItem *param) { PK11SymKey *newKey; PK11Context *context; /* if this slot doesn't support the mechanism, go to a slot that does */ newKey = pk11_ForceSlot(symKey, type, operation); if (newKey == NULL) { PK11_ReferenceSymKey(symKey); } else { symKey = newKey; } /* Context Adopts the symKey.... */ context = pk11_CreateNewContextInSlot(type, symKey->slot, operation, symKey, param); PK11_FreeSymKey(symKey); return context; }