首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Windows、Mac和Linux上使用Mozilla NSS根证书存储?

如何在Windows、Mac和Linux上使用Mozilla NSS根证书存储?
EN

Stack Overflow用户
提问于 2015-07-24 19:34:27
回答 1查看 755关注 0票数 0

NSS附带的文档非常少,并且带有严重的残留API。它怎麽工作?它用于Window和Mac上的firefox,以及linux上的Chrome。如何安装、卸载和检查我自己的根证书的安装?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-24 19:34:27

看这个要点,这里:https://gist.github.com/pehrlich/08852e8f7da81e136d70

它的肉是CertificateNSS.cpp,在这里复制:

代码语言:javascript
复制
#include "stdafx.h"
#include "CertificateNSS.h"
#include "Certificate.h"
#include <boost/filesystem/operations.hpp>

#include <nss.h>
#include <cert.h>
#include <certdb.h>

ProfileLocker::ProfileLocker(const boost::filesystem::path& profilePath) : m_isValid(false)
{
  GetSharedMutex().lock();
  m_isValid = (NSS_InitReadWrite(profilePath.string().c_str()) == SECSuccess);
  if (!m_isValid) {
    GetSharedMutex().unlock();
  }
}

ProfileLocker::~ProfileLocker()
{
  if (m_isValid) {
    NSS_Shutdown();
    GetSharedMutex().unlock();
  }
}

std::mutex& ProfileLocker::GetSharedMutex()
{
  static std::mutex s_mutex;
  return s_mutex;
}

std::vector<boost::filesystem::path> CertificateNSS::GetUserProfiles()
{
  std::vector<boost::filesystem::path> profiles;

  const auto path = GetProfilesDirectory();
  if (!boost::filesystem::is_directory(path)) {
    return profiles;
  }
  boost::filesystem::directory_iterator endIt;
  for (boost::filesystem::directory_iterator it(path); it != endIt; ++it) {
    if (boost::filesystem::is_directory(it->status())) {
      profiles.push_back(it->path());
    }
  }
  return profiles;
}

bool CertificateNSS::Install() const
{
  std::string derCert = m_cert.GetBytes(CertEncoding::DER);
  if (derCert.empty()) {
    return false;
  }
  bool wasInstalled = false;
  CERTCertDBHandle* certdb = CERT_GetDefaultCertDB();
  if (certdb) {
    SECItem cert = { siBuffer, (unsigned char*)derCert.c_str(), static_cast<unsigned int>(derCert.size()) };
    SECItem* certArray[1] = { &cert };
    SECCertUsage noOpUsage = certUsageUserCertImport; // Not used, but required

    CERTCertificate** certificates = nullptr;
    wasInstalled = (CERT_ImportCerts(certdb, noOpUsage, 1, certArray, &certificates, PR_TRUE, PR_TRUE,
      const_cast<char*>(Certificate::GetNickname().c_str())) == SECSuccess);
    if (certificates[0]) {
      CERTCertTrust trust = { CERTDB_TRUSTED_CA | CERTDB_VALID_CA, 0, 0 };
      CERT_ChangeCertTrust(certdb, certificates[0], &trust);
      CERT_DestroyCertificate(certificates[0]);
    }
  }
  return wasInstalled;
}

bool CertificateNSS::IsInstalled() const
{
  std::string derCert = m_cert.GetBytes(CertEncoding::DER);
  if (derCert.empty()) {
    return false;
  }
  bool wasInstalled = false;
  SECItem cert = { siBuffer, (unsigned char*)derCert.c_str(), static_cast<unsigned int>(derCert.size()) };
  CERTCertDBHandle* certdb = CERT_GetDefaultCertDB();
  if (certdb) {
    CERTCertificate* certificate = CERT_FindCertByDERCert(certdb, &cert);
    if (certificate) {
      wasInstalled = true;
      CERT_DestroyCertificate(certificate);
    }
  }
  return wasInstalled;
}

bool CertificateNSS::Uninstall() const
{
  std::string derCert = m_cert.GetBytes(CertEncoding::DER);
  if (derCert.empty()) {
    return false;
  }
  bool wasUninstalled = false;
  SECItem cert = { siBuffer, (unsigned char*)derCert.c_str(), static_cast<unsigned int>(derCert.size()) };
  CERTCertDBHandle* certdb = CERT_GetDefaultCertDB();
  if (certdb) {
    CERTCertificate* certificate = CERT_FindCertByDERCert(certdb, &cert);
    if (certificate) {
      wasUninstalled = (SEC_DeletePermCertificate(certificate) == SECSuccess);
      CERT_DestroyCertificate(certificate);
    }
  }
  return wasUninstalled;
}

bool CertificateNSS::UninstallAll()
{
  bool wasUninstalled = true;
  CERTCertDBHandle* certdb = CERT_GetDefaultCertDB();
  if (!certdb) {
    return true;
  }
  // Delete up to 100 profiles
  for (int i = 0; i < 100; i++) {
    bool failed = true;
    CERTCertificate* certificate = CERT_FindCertByNickname(certdb, Certificate::GetNickname().c_str());
    if (certificate) {
      wasUninstalled = (SEC_DeletePermCertificate(certificate) == SECSuccess);
      if (wasUninstalled) {
        failed = false;
      }
      CERT_DestroyCertificate(certificate);
    }
    if (failed) {
      break;
    }
  }
  return wasUninstalled;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31618447

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档