static nsresult
GetCertFingerprintByOidTag(nsIX509Cert *aCert,
                           SECOidTag aOidTag,
                           nsCString &fp)
{
    nsCOMPtr<nsIX509Cert2> cert2 = do_QueryInterface(aCert);
    if (!cert2)
        return NS_ERROR_FAILURE;

    CERTCertificate* nsscert = cert2->GetCert();
    if (!nsscert)
        return NS_ERROR_FAILURE;

    CERTCertificateCleaner nsscertCleaner(nsscert);
    return GetCertFingerprintByOidTag(nsscert, aOidTag, fp);
}
static nsresult
GetCertFingerprintByDottedOidString(nsIX509Cert *aCert,
                                    const nsCString &dottedOid,
                                    nsCString &fp)
{
    nsCOMPtr<nsIX509Cert2> cert2 = do_QueryInterface(aCert);
    if (!cert2)
        return NS_ERROR_FAILURE;

    CERTCertificate* nsscert = cert2->GetCert();
    if (!nsscert)
        return NS_ERROR_FAILURE;

    CERTCertificateCleaner nsscertCleaner(nsscert);
    return GetCertFingerprintByDottedOidString(nsscert, dottedOid, fp);
}
NS_IMETHODIMP
nsCertOverrideService::RememberValidityOverride(const nsACString & aHostName, PRInt32 aPort,
        nsIX509Cert *aCert,
        PRUint32 aOverrideBits,
        PRBool aTemporary)
{
    NS_ENSURE_ARG_POINTER(aCert);
    if (aHostName.IsEmpty())
        return NS_ERROR_INVALID_ARG;
    if (aPort < -1)
        return NS_ERROR_INVALID_ARG;

    nsCOMPtr<nsIX509Cert2> cert2 = do_QueryInterface(aCert);
    if (!cert2)
        return NS_ERROR_FAILURE;

    CERTCertificate* nsscert = cert2->GetCert();
    if (!nsscert)
        return NS_ERROR_FAILURE;

    CERTCertificateCleaner nsscertCleaner(nsscert);

    nsCAutoString nickname;
    nickname = nsNSSCertificate::defaultServerNickname(nsscert);
    if (!aTemporary && !nickname.IsEmpty())
    {
        PK11SlotInfo *slot = PK11_GetInternalKeySlot();
        if (!slot)
            return NS_ERROR_FAILURE;

        SECStatus srv = PK11_ImportCert(slot, nsscert, CK_INVALID_HANDLE,
                                        const_cast<char*>(nickname.get()), PR_FALSE);
        PK11_FreeSlot(slot);

        if (srv != SECSuccess)
            return NS_ERROR_FAILURE;
    }

    nsCAutoString fpStr;
    nsresult rv = GetCertFingerprintByOidTag(nsscert,
                  mOidTagForStoringNewHashes, fpStr);
    if (NS_FAILED(rv))
        return rv;

    char *dbkey = NULL;
    rv = aCert->GetDbKey(&dbkey);
    if (NS_FAILED(rv) || !dbkey)
        return rv;

    // change \n and \r to spaces in the possibly multi-line-base64-encoded key
    for (char *dbkey_walk = dbkey;
            *dbkey_walk;
            ++dbkey_walk) {
        char c = *dbkey_walk;
        if (c == '\r' || c == '\n') {
            *dbkey_walk = ' ';
        }
    }

    {
        nsAutoMonitor lock(monitor);
        AddEntryToList(aHostName, aPort,
                       aTemporary ? aCert : nsnull,
                       // keep a reference to the cert for temporary overrides
                       aTemporary,
                       mDottedOidForStoringNewHashes, fpStr,
                       (nsCertOverride::OverrideBits)aOverrideBits,
                       nsDependentCString(dbkey));
        Write();
    }

    PR_Free(dbkey);
    return NS_OK;
}
Esempio n. 4
0
NS_IMETHODIMP 
nsCertTree::DeleteEntryObject(PRUint32 index)
{
  if (!mTreeArray) {
    return NS_ERROR_FAILURE;
  }

  nsCOMPtr<nsIX509CertDB> certdb = 
    do_GetService("@mozilla.org/security/x509certdb;1");
  if (!certdb) {
    return NS_ERROR_FAILURE;
  }

  int i;
  PRUint32 idx = 0, cIndex = 0, nc;
  // Loop over the threads
  for (i=0; i<mNumOrgs; i++) {
    if (index == idx)
      return NS_OK; // index is for thread
    idx++; // get past the thread
    nc = (mTreeArray[i].open) ? mTreeArray[i].numChildren : 0;
    if (index < idx + nc) { // cert is within range of this thread
      PRInt32 certIndex = cIndex + index - idx;

      bool canRemoveEntry = false;
      nsRefPtr<nsCertTreeDispInfo> certdi = mDispInfo.SafeElementAt(certIndex, NULL);
      
      // We will remove the element from the visual tree.
      // Only if we have a certdi, then we can check for additional actions.
      nsCOMPtr<nsIX509Cert> cert = nsnull;
      if (certdi) {
        if (certdi->mAddonInfo) {
          cert = certdi->mAddonInfo->mCert;
        }
        nsCertAddonInfo *addonInfo = certdi->mAddonInfo ? certdi->mAddonInfo : nsnull;
        if (certdi->mTypeOfEntry == nsCertTreeDispInfo::host_port_override) {
          mOverrideService->ClearValidityOverride(certdi->mAsciiHost, certdi->mPort);
          if (addonInfo) {
            addonInfo->mUsageCount--;
            if (addonInfo->mUsageCount == 0) {
              // The certificate stored in the database is no longer
              // referenced by any other object displayed.
              // That means we no longer need to keep it around
              // and really can remove it.
              canRemoveEntry = true;
            }
          } 
        }
        else {
          if (addonInfo && addonInfo->mUsageCount > 1) {
            // user is trying to delete a perm trusted cert,
            // although there are still overrides stored,
            // so, we keep the cert, but remove the trust

            CERTCertificate *nsscert = nsnull;
            CERTCertificateCleaner nsscertCleaner(nsscert);

            nsCOMPtr<nsIX509Cert2> cert2 = do_QueryInterface(cert);
            if (cert2) {
              nsscert = cert2->GetCert();
            }

            if (nsscert) {
              CERTCertTrust trust;
              memset((void*)&trust, 0, sizeof(trust));
            
              SECStatus srv = CERT_DecodeTrustString(&trust, ""); // no override 
              if (srv == SECSuccess) {
                CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), nsscert, &trust);
              }
            }
          }
          else {
            canRemoveEntry = true;
          }
        }
      }

      mDispInfo.RemoveElementAt(certIndex);

      if (canRemoveEntry) {
        RemoveCacheEntry(cert);
        certdb->DeleteCertificate(cert);
      }

      delete [] mTreeArray;
      mTreeArray = nsnull;
      return UpdateUIContents();
    }
    if (mTreeArray[i].open)
      idx += mTreeArray[i].numChildren;
    cIndex += mTreeArray[i].numChildren;
    if (idx > index)
      break;
  }
  return NS_ERROR_FAILURE;
}