Esempio n. 1
0
// sort blocklist items into lists of serials for each issuer
PLDHashOperator
ProcessBlocklistEntry(BlocklistItemKey* aHashKey, void* aUserArg)
{
  BlocklistSaveInfo* saveInfo = reinterpret_cast<BlocklistSaveInfo*>(aUserArg);
  CertBlocklistItem item = aHashKey->GetKey();

  if (!item.mIsCurrent) {
    return PL_DHASH_NEXT;
  }

  nsAutoCString encDN;
  nsAutoCString encOther;

  nsresult rv = item.ToBase64(encDN, encOther);
  if (NS_FAILED(rv)) {
    saveInfo->success = false;
    return PL_DHASH_STOP;
  }

  // If it's a subject / public key block, write it straight out
  if (item.mItemMechanism == BlockBySubjectAndPubKey) {
    WriteLine(saveInfo->outputStream, encDN);
    WriteLine(saveInfo->outputStream, NS_LITERAL_CSTRING("\t") + encOther);
    return PL_DHASH_NEXT;
  }

  // Otherwise, we have to group entries by issuer
  saveInfo->issuers.PutEntry(encDN);
  BlocklistStringSet* issuerSet = saveInfo->issuerTable.Get(encDN);
  if (!issuerSet) {
    issuerSet = new BlocklistStringSet();
    saveInfo->issuerTable.Put(encDN, issuerSet);
  }
  issuerSet->PutEntry(encOther);
  return PL_DHASH_NEXT;
}
Esempio n. 2
0
// void saveEntries();
// Store the blockist in a text file containing base64 encoded issuers and
// serial numbers.
//
// Each item is stored on a separate line; each issuer is followed by its
// revoked serial numbers, indented by one space.
//
// lines starting with a # character are ignored
NS_IMETHODIMP
CertBlocklist::SaveEntries()
{
  MOZ_LOG(gCertBlockPRLog, LogLevel::Debug,
      ("CertBlocklist::SaveEntries - not initialized"));
  MutexAutoLock lock(mMutex);
  if (!mModified) {
    return NS_OK;
  }

  nsresult rv = EnsureBackingFileInitialized(lock);
  if (NS_FAILED(rv)) {
    return rv;
  }

  if (!mBackingFile) {
    // We allow this to succeed with no profile directory for tests
    MOZ_LOG(gCertBlockPRLog, LogLevel::Warning,
           ("CertBlocklist::SaveEntries no file in profile to write to"));
    return NS_OK;
  }

  // Data needed for writing blocklist items out to the revocations file
  IssuerTable issuerTable;
  BlocklistStringSet issuers;
  nsCOMPtr<nsIOutputStream> outputStream;

  rv = NS_NewAtomicFileOutputStream(getter_AddRefs(outputStream),
                                    mBackingFile, -1, -1, 0);
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = WriteLine(outputStream,
                 NS_LITERAL_CSTRING("# Auto generated contents. Do not edit."));
  if (NS_FAILED(rv)) {
    return rv;
  }

  // Sort blocklist items into lists of serials for each issuer
  for (auto iter = mBlocklist.Iter(); !iter.Done(); iter.Next()) {
    CertBlocklistItem item = iter.Get()->GetKey();
    if (!item.mIsCurrent) {
      continue;
    }

    nsAutoCString encDN;
    nsAutoCString encOther;

    nsresult rv = item.ToBase64(encDN, encOther);
    if (NS_FAILED(rv)) {
      MOZ_LOG(gCertBlockPRLog, LogLevel::Warning,
             ("CertBlocklist::SaveEntries writing revocation data failed"));
      return NS_ERROR_FAILURE;
    }

    // If it's a subject / public key block, write it straight out
    if (item.mItemMechanism == BlockBySubjectAndPubKey) {
      WriteLine(outputStream, encDN);
      WriteLine(outputStream, NS_LITERAL_CSTRING("\t") + encOther);
      continue;
    }

    // Otherwise, we have to group entries by issuer
    issuers.PutEntry(encDN);
    BlocklistStringSet* issuerSet = issuerTable.Get(encDN);
    if (!issuerSet) {
      issuerSet = new BlocklistStringSet();
      issuerTable.Put(encDN, issuerSet);
    }
    issuerSet->PutEntry(encOther);
  }

  for (auto iter = issuers.Iter(); !iter.Done(); iter.Next()) {
    nsCStringHashKey* hashKey = iter.Get();
    nsAutoPtr<BlocklistStringSet> issuerSet;
    issuerTable.RemoveAndForget(hashKey->GetKey(), issuerSet);

    nsresult rv = WriteLine(outputStream, hashKey->GetKey());
    if (NS_FAILED(rv)) {
      break;
    }

    // Write serial data to the output stream
    for (auto iter = issuerSet->Iter(); !iter.Done(); iter.Next()) {
      nsresult rv = WriteLine(outputStream,
                              NS_LITERAL_CSTRING(" ") + iter.Get()->GetKey());
      if (NS_FAILED(rv)) {
        MOZ_LOG(gCertBlockPRLog, LogLevel::Warning,
               ("CertBlocklist::SaveEntries writing revocation data failed"));
        return NS_ERROR_FAILURE;
      }
    }
  }

  nsCOMPtr<nsISafeOutputStream> safeStream = do_QueryInterface(outputStream);
  NS_ASSERTION(safeStream, "expected a safe output stream!");
  if (!safeStream) {
    return NS_ERROR_FAILURE;
  }
  rv = safeStream->Finish();
  if (NS_FAILED(rv)) {
    MOZ_LOG(gCertBlockPRLog, LogLevel::Warning,
           ("CertBlocklist::SaveEntries saving revocation data failed"));
    return rv;
  }
  mModified = false;
  return NS_OK;
}