if(rv == SECFailure) { if(arena != NULL) { PORT_FreeArena(arena, PR_TRUE); } epki = NULL; }
PK11_ExportEncryptedPrivateKeyInfo(PK11SlotInfo *slot, SECOidTag algTag,   SECItem *pwitem, CERTCertificate *cert, int iteration, void *wincx){    SECKEYEncryptedPrivateKeyInfo *epki = NULL;    SECKEYPrivateKey *pk = NULL;    PRArenaPool *arena = NULL;    SECAlgorithmID *algid;    CK_MECHANISM_TYPE mechanism;    SECItem *pbe_param = NULL, crypto_param;    PK11SymKey *key = NULL;    SECStatus rv = SECSuccess;    CK_MECHANISM pbeMech, cryptoMech;    CK_ULONG encBufLenPtr;    CK_RV crv;    SECItem encryptedKey = {siBuffer,NULL,0};    int encryptBufLen;    if(!pwitem)	return NULL;    crypto_param.data = NULL;    arena = PORT_NewArena(2048);    epki = (SECKEYEncryptedPrivateKeyInfo *)PORT_ArenaZAlloc(arena,     		sizeof(SECKEYEncryptedPrivateKeyInfo));    if(epki == NULL) {	rv = SECFailure;	goto loser;    }    epki->arena = arena;    pk = PK11_FindKeyByAnyCert(cert, wincx);    if(pk == NULL) {	rv = SECFailure;	goto loser;    }    /* if we didn't specify a slot, use the slot the private key was in */    if (!slot) {	slot = pk->pkcs11Slot;    }    algid = SEC_PKCS5CreateAlgorithmID(algTag, NULL, iteration);    if(algid == NULL) {	rv = SECFailure;	goto loser;    }    mechanism = PK11_AlgtagToMechanism(SECOID_FindOIDTag(&algid->algorithm));    pbe_param = PK11_ParamFromAlgid(algid);    pbeMech.mechanism = mechanism;    pbeMech.pParameter = pbe_param->data;    pbeMech.ulParameterLen = pbe_param->len;    /* if we specified a different slot, and the private key slot can do the     * pbe key gen, generate the key in the private key slot so we don't have      * to move it later */    if (slot != pk->pkcs11Slot) {	if (PK11_DoesMechanism(pk->pkcs11Slot,mechanism)) {	    slot = pk->pkcs11Slot;	}    }    key = PK11_RawPBEKeyGen(slot, mechanism, pbe_param, pwitem, 							PR_FALSE, wincx);    if((key == NULL) || (pbe_param == NULL)) {	rv = SECFailure;	goto loser;    }    crv = PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, 						pwitem, PR_FALSE);    if(crv != CKR_OK) {	rv = SECFailure;	goto loser;    }    cryptoMech.mechanism = PK11_GetPadMechanism(cryptoMech.mechanism);    crypto_param.data = (unsigned char *)cryptoMech.pParameter;    crypto_param.len = cryptoMech.ulParameterLen;    encryptBufLen = pk11_private_key_encrypt_buffer_length(pk);     if(encryptBufLen == -1) {	rv = SECFailure;	goto loser;    }    encryptedKey.len = (unsigned int)encryptBufLen;    encBufLenPtr = (CK_ULONG) encryptBufLen;    encryptedKey.data = (unsigned char *)PORT_ZAlloc(encryptedKey.len);    if(!encryptedKey.data) {	rv = SECFailure;	goto loser;    }    /* If the key isn't in the private key slot, move it */    if (key->slot != pk->pkcs11Slot) {	PK11SymKey *newkey = pk11_CopyToSlot(pk->pkcs11Slot,						key->type, CKA_WRAP, key);	if (newkey == NULL) {	    rv= SECFailure;	    goto loser;	}	/* free the old key and use the new key */	PK11_FreeSymKey(key);	key = newkey;    }	    /* we are extracting an encrypted privateKey structure.     * which needs to be freed along with the buffer into which it is     * returned.  eventually, we should retrieve an encrypted key using     * pkcs8/pkcs5.     */    PK11_EnterSlotMonitor(pk->pkcs11Slot);    crv = PK11_GETTAB(pk->pkcs11Slot)->C_WrapKey(pk->pkcs11Slot->session,     		&cryptoMech, key->objectID, pk->pkcs11ID, encryptedKey.data, 		&encBufLenPtr);     PK11_ExitSlotMonitor(pk->pkcs11Slot);    encryptedKey.len = (unsigned int) encBufLenPtr;    if(crv != CKR_OK) {	rv = SECFailure;	goto loser;    }    if(!encryptedKey.len) {	rv = SECFailure;	goto loser;    }        rv = SECITEM_CopyItem(arena, &epki->encryptedData, &encryptedKey);    if(rv != SECSuccess) {	goto loser;    }    rv = SECOID_CopyAlgorithmID(arena, &epki->algorithm, algid);loser:    if(pbe_param != NULL) {	SECITEM_ZfreeItem(pbe_param, PR_TRUE);	pbe_param = NULL;    }    if(crypto_param.data != NULL) {	SECITEM_ZfreeItem(&crypto_param, PR_FALSE);	crypto_param.data = NULL;    }    if(key != NULL) {    	PK11_FreeSymKey(key);    }    if (pk != NULL) {	SECKEY_DestroyPrivateKey(pk);    }    if(rv == SECFailure) {	if(arena != NULL) {	    PORT_FreeArena(arena, PR_TRUE);	}	epki = NULL;    }    return epki;}