if (!NS_FAILED(rv)) {
if (NS_SUCCEEDED(rv)) {
cryptojs_generateOneKeyPair(JSContext *cx, nsKeyPairInfo *keyPairInfo,                             PRInt32 keySize, char *params,                             nsIInterfaceRequestor *uiCxt,                            PK11SlotInfo *slot, PRBool willEscrow)                            {  nsIGeneratingKeypairInfoDialogs * dialogs;  nsKeygenThread *KeygenRunnable = 0;  nsCOMPtr<nsIKeygenThread> runnable;  PRUint32 mechanism = cryptojs_convert_to_mechanism(keyPairInfo->keyGenType);  void *keyGenParams = nsConvertToActualKeyGenParams(mechanism, params,                                                      (params) ? nsCRT::strlen(params):0,                                                      keySize);  // Make sure the token has password already set on it before trying  // to generate the key.  nsresult rv = setPassword(slot, uiCxt);  if (NS_FAILED(rv))    return rv;  if (PK11_Authenticate(slot, PR_TRUE, uiCxt) != SECSuccess)    return NS_ERROR_FAILURE;   // Smart cards will not let you extract a private key once   // it is on the smart card.  If we've been told to escrow  // a private key that will ultimately wind up on a smart card,  // then we'll generate the private key on the internal slot  // as a temporary key, then move it to the destination slot.   // NOTE: We call PK11_GetInternalSlot instead of PK11_GetInternalKeySlot  //       so that the key has zero chance of being store in the  //       user's key3.db file.  Which the slot returned by  //       PK11_GetInternalKeySlot has access to and PK11_GetInternalSlot  //       does not.  PK11SlotInfo *intSlot = nsnull, *origSlot = nsnull;  PRBool isPerm;  if (willEscrow && !PK11_IsInternal(slot)) {    intSlot = PK11_GetInternalSlot();    NS_ASSERTION(intSlot,"Couldn't get the internal slot");    isPerm = PR_FALSE;    origSlot = slot;    slot = intSlot;  } else {    isPerm = PR_TRUE;  }  rv = getNSSDialogs((void**)&dialogs,                     NS_GET_IID(nsIGeneratingKeypairInfoDialogs));  if (NS_SUCCEEDED(rv)) {    KeygenRunnable = new nsKeygenThread();    if (KeygenRunnable) {      NS_ADDREF(KeygenRunnable);    }  }  if (NS_FAILED(rv) || !KeygenRunnable) {    rv = NS_OK;    keyPairInfo->privKey = PK11_GenerateKeyPair(slot, mechanism, keyGenParams,                                                &keyPairInfo->pubKey, isPerm,                                                 isPerm, uiCxt);  } else {    KeygenRunnable->SetParams( slot, mechanism, keyGenParams, isPerm, isPerm, uiCxt );    runnable = do_QueryInterface(KeygenRunnable);    if (runnable) {      rv = dialogs->DisplayGeneratingKeypairInfo(uiCxt, runnable);      // We call join on the thread,       // so we can be sure that no simultaneous access to the passed parameters will happen.      KeygenRunnable->Join();      NS_RELEASE(dialogs);      if (!NS_FAILED(rv)) {        rv = KeygenRunnable->GetParams(&keyPairInfo->privKey, &keyPairInfo->pubKey);      }    }  }  nsFreeKeyGenParams(mechanism, keyGenParams);  if (KeygenRunnable) {    NS_RELEASE(KeygenRunnable);  }  if (!keyPairInfo->privKey || !keyPairInfo->pubKey) {    if (intSlot)      PK11_FreeSlot(intSlot);    return NS_ERROR_FAILURE;  }   //If we generated the key pair on the internal slot because the  // keys were going to be escrowed, move the keys over right now.  if (willEscrow && intSlot) {    SECKEYPrivateKey *newPrivKey = pk11_loadPrivKey(origSlot,                                                     keyPairInfo->privKey,                                                    keyPairInfo->pubKey,                                                    PR_TRUE, PR_TRUE);    if (!newPrivKey)      return NS_ERROR_FAILURE;    // The private key is stored on the selected slot now, and the copy we    // ultimately use for escrowing when the time comes lives     // in the internal slot.  We will delete it from that slot    // after the requests are made.  This call only gives up    // our reference to the key object and does not actually     // physically remove it from the card itself.    SECKEY_DestroyPrivateKey(newPrivKey);    PK11_FreeSlot(intSlot);    intSlot = nsnull;  }    return NS_OK;}