Пример #1
0
NS_IMETHODIMP
nsNSSCertificate::GetAllTokenNames(uint32_t *aLength, PRUnichar*** aTokenNames)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown())
    return NS_ERROR_NOT_AVAILABLE;

  NS_ENSURE_ARG(aLength);
  NS_ENSURE_ARG(aTokenNames);
  *aLength = 0;
  *aTokenNames = NULL;

  /* Get the slots from NSS */
  PK11SlotList *slots = NULL;
  PK11SlotListCleaner slotCleaner(slots);
  PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Getting slots for \"%s\"\n", mCert->nickname));
  slots = PK11_GetAllSlotsForCert(mCert, NULL);
  if (!slots) {
    if (PORT_GetError() == SEC_ERROR_NO_TOKEN)
      return NS_OK; // List of slots is empty, return empty array
    else
      return NS_ERROR_FAILURE;
  }

  /* read the token names from slots */
  PK11SlotListElement *le;

  for (le = slots->head; le; le = le->next) {
    ++(*aLength);
  }

  *aTokenNames = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *) * (*aLength));
  if (!*aTokenNames) {
    *aLength = 0;
    return NS_ERROR_OUT_OF_MEMORY;
  }

  uint32_t iToken;
  for (le = slots->head, iToken = 0; le; le = le->next, ++iToken) {
    char *token = PK11_GetTokenName(le->slot);
    (*aTokenNames)[iToken] = ToNewUnicode(NS_ConvertUTF8toUTF16(token));
    if (!(*aTokenNames)[iToken]) {
      NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(iToken, *aTokenNames);
      *aLength = 0;
      *aTokenNames = NULL;
      return NS_ERROR_OUT_OF_MEMORY;
    }
  }

  return NS_OK;
}
Пример #2
0
void
nsNSSCertificateDB::get_default_nickname(CERTCertificate *cert, 
                                         nsIInterfaceRequestor* ctx,
                                         nsCString &nickname)
{
  nickname.Truncate();

  nsNSSShutDownPreventionLock locker;
  nsresult rv;
  CK_OBJECT_HANDLE keyHandle;

  CERTCertDBHandle *defaultcertdb = CERT_GetDefaultCertDB();
  nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
  if (NS_FAILED(rv))
    return;

  nsCAutoString username;
  char *temp_un = CERT_GetCommonName(&cert->subject);
  if (temp_un) {
    username = temp_un;
    PORT_Free(temp_un);
    temp_un = nsnull;
  }

  nsCAutoString caname;
  char *temp_ca = CERT_GetOrgName(&cert->issuer);
  if (temp_ca) {
    caname = temp_ca;
    PORT_Free(temp_ca);
    temp_ca = nsnull;
  }

  nsAutoString tmpNickFmt;
  nssComponent->GetPIPNSSBundleString("nick_template", tmpNickFmt);
  NS_ConvertUTF16toUTF8 nickFmt(tmpNickFmt);

  nsCAutoString baseName;
  char *temp_nn = PR_smprintf(nickFmt.get(), username.get(), caname.get());
  if (!temp_nn) {
    return;
  } else {
    baseName = temp_nn;
    PR_smprintf_free(temp_nn);
    temp_nn = nsnull;
  }

  nickname = baseName;

  /*
   * We need to see if the private key exists on a token, if it does
   * then we need to check for nicknames that already exist on the smart
   * card.
   */
  PK11SlotInfo *slot = PK11_KeyForCertExists(cert, &keyHandle, ctx);
  PK11SlotInfoCleaner slotCleaner(slot);
  if (!slot)
    return;

  if (!PK11_IsInternal(slot)) {
    char *tmp = PR_smprintf("%s:%s", PK11_GetTokenName(slot), baseName.get());
    if (!tmp) {
      nickname.Truncate();
      return;
    }
    baseName = tmp;
    PR_smprintf_free(tmp);

    nickname = baseName;
  }

  int count = 1;
  while (true) {
    if ( count > 1 ) {
      char *tmp = PR_smprintf("%s #%d", baseName.get(), count);
      if (!tmp) {
        nickname.Truncate();
        return;
      }
      nickname = tmp;
      PR_smprintf_free(tmp);
    }

    CERTCertificate *dummycert = nsnull;
    CERTCertificateCleaner dummycertCleaner(dummycert);

    if (PK11_IsInternal(slot)) {
      /* look up the nickname to make sure it isn't in use already */
      dummycert = CERT_FindCertByNickname(defaultcertdb, nickname.get());

    } else {
      /*
       * Check the cert against others that already live on the smart 
       * card.
       */
      dummycert = PK11_FindCertFromNickname(nickname.get(), ctx);
      if (dummycert != NULL) {
	/*
	 * Make sure the subject names are different.
	 */ 
	if (CERT_CompareName(&cert->subject, &dummycert->subject) == SECEqual)
	{
	  /*
	   * There is another certificate with the same nickname and
	   * the same subject name on the smart card, so let's use this
	   * nickname.
	   */
	  CERT_DestroyCertificate(dummycert);
	  dummycert = NULL;
	}
      }
    }
    if (!dummycert) 
      break;
    
    count++;
  }
}