symKey->owner = PR_FALSE;
PK11_TokenKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,    int keySize, SECItem *keyid, PRBool isToken, void *wincx){    PK11SymKey *symKey;    CK_ATTRIBUTE genTemplate[6];    CK_ATTRIBUTE *attrs = genTemplate;    int count = sizeof(genTemplate)/sizeof(genTemplate[0]);    CK_SESSION_HANDLE session;    CK_MECHANISM mechanism;    CK_RV crv;    PRBool weird = PR_FALSE;   /* hack for fortezza */    CK_BBOOL cktrue = CK_TRUE;    CK_ULONG ck_key_size;       /* only used for variable-length keys */    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++;        if (keySize != 0) {        ck_key_size = keySize; /* Convert to PK11 type */        PK11_SETATTRS(attrs, CKA_VALUE_LEN, &ck_key_size, sizeof(ck_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++;        PK11_SETATTRS(attrs, CKA_PRIVATE, &cktrue, sizeof(cktrue));  attrs++;    }    PK11_SETATTRS(attrs, CKA_SIGN, &cktrue, sizeof(cktrue));  attrs++;    count = attrs - genTemplate;    PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE));    /* find a slot to generate the key into */    /* 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 {	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 */    mechanism.mechanism = PK11_GetKeyGen(type);    if (mechanism.mechanism == CKM_FAKE_RANDOM) {	PORT_SetError( SEC_ERROR_NO_MODULE );	return NULL;    }    /* Set the parameters for the key gen if provided */    mechanism.pParameter = NULL;    mechanism.ulParameterLen = 0;    if (param) {	mechanism.pParameter = param->data;	mechanism.ulParameterLen = param->len;    }    /* Get session and perform locking */    if (isToken) {	PK11_Authenticate(symKey->slot,PR_TRUE,wincx);        session = PK11_GetRWSession(symKey->slot);  /* Should always be original slot */    } else {        session = symKey->session;        pk11_EnterKeyMonitor(symKey);    }    crv = PK11_GETTAB(symKey->slot)->C_GenerateKey(session,			 &mechanism, genTemplate, count, &symKey->objectID);    /* 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;}