int i;
static SECItem *sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp){    NSSLOWKEYPrivateKey *lk = NULL;    NSSLOWKEYPrivateKeyInfo *pki = NULL;    SFTKAttribute *attribute = NULL;    PLArenaPool *arena = NULL;    SECOidTag algorithm = SEC_OID_UNKNOWN;    void *dummy, *param = NULL;    SECStatus rv = SECSuccess;    SECItem *encodedKey = NULL;#ifdef NSS_ENABLE_ECC    SECItem *fordebug;    int savelen;    int i;#endif    if(!key) {	*crvp = CKR_KEY_HANDLE_INVALID; /* really can't happen */	return NULL;    }    attribute = sftk_FindAttribute(key, CKA_KEY_TYPE);    if(!attribute) {	*crvp = CKR_KEY_TYPE_INCONSISTENT;	return NULL;    }    lk = sftk_GetPrivKey(key, *(CK_KEY_TYPE *)attribute->attrib.pValue, crvp);    sftk_FreeAttribute(attribute);    if(!lk) {	return NULL;    }    arena = PORT_NewArena(2048); 	/* XXX different size? */    if(!arena) {	*crvp = CKR_HOST_MEMORY;	rv = SECFailure;	goto loser;    }    pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena, 					sizeof(NSSLOWKEYPrivateKeyInfo));    if(!pki) {	*crvp = CKR_HOST_MEMORY;	rv = SECFailure;	goto loser;    }    pki->arena = arena;    param = NULL;    switch(lk->keyType) {	case NSSLOWKEYRSAKey:	    prepare_low_rsa_priv_key_for_asn1(lk);	    dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,				       nsslowkey_RSAPrivateKeyTemplate);	    algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;	    break;	case NSSLOWKEYDSAKey:            prepare_low_dsa_priv_key_export_for_asn1(lk);	    dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,				       nsslowkey_DSAPrivateKeyExportTemplate);	    prepare_low_pqg_params_for_asn1(&lk->u.dsa.params);	    param = SEC_ASN1EncodeItem(NULL, NULL, &(lk->u.dsa.params),				       nsslowkey_PQGParamsTemplate);	    algorithm = SEC_OID_ANSIX9_DSA_SIGNATURE;	    break;#ifdef NSS_ENABLE_ECC	            case NSSLOWKEYECKey:            prepare_low_ec_priv_key_for_asn1(lk);	    /* Public value is encoded as a bit string so adjust length	     * to be in bits before ASN encoding and readjust 	     * immediately after.	     *	     * Since the SECG specification recommends not including the	     * parameters as part of ECPrivateKey, we zero out the curveOID	     * length before encoding and restore it later.	     */	    lk->u.ec.publicValue.len <<= 3;	    savelen = lk->u.ec.ecParams.curveOID.len;	    lk->u.ec.ecParams.curveOID.len = 0;	    dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,				       nsslowkey_ECPrivateKeyTemplate);	    lk->u.ec.ecParams.curveOID.len = savelen;	    lk->u.ec.publicValue.len >>= 3;	    fordebug = &pki->privateKey;	    SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKey", lk->keyType,		      fordebug);	    param = SECITEM_DupItem(&lk->u.ec.ecParams.DEREncoding);	    algorithm = SEC_OID_ANSIX962_EC_PUBLIC_KEY;	    break;#endif /* NSS_ENABLE_ECC */	case NSSLOWKEYDHKey:	default:	    dummy = NULL;	    break;    }     if(!dummy || ((lk->keyType == NSSLOWKEYDSAKey) && !param)) {	*crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */	rv = SECFailure;	goto loser;    }        rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, algorithm, 			       (SECItem*)param);    if(rv != SECSuccess) {	*crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */	rv = SECFailure;	goto loser;    }    dummy = SEC_ASN1EncodeInteger(arena, &pki->version,				  NSSLOWKEY_PRIVATE_KEY_INFO_VERSION);    if(!dummy) {	*crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */	rv = SECFailure;	goto loser;    }    encodedKey = SEC_ASN1EncodeItem(NULL, NULL, pki, 				    nsslowkey_PrivateKeyInfoTemplate);    *crvp = encodedKey ? CKR_OK : CKR_DEVICE_ERROR;#ifdef NSS_ENABLE_ECC    fordebug = encodedKey;    SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKeyInfo", lk->keyType,	      fordebug);#endifloser:    if(arena) {	PORT_FreeArena(arena, PR_TRUE);    }    if(lk && (lk != key->objectInfo)) {	nsslowkey_DestroyPrivateKey(lk);    }     if(param) {	SECITEM_ZfreeItem((SECItem*)param, PR_TRUE);    }    if(rv != SECSuccess) {	return NULL;    }    return encodedKey;}