如何在 Windows、Mac 和 Linux 上使用 Mozilla NSS 根证书存储?
How do I use the Mozilla NSS Root Certificate store on Windows, Mac, and Linux?
NSS 附带的文档非常少,而且残留严重API。它是如何工作的?它用于 Window 和 Mac 以及 Chrome 和 linux 上的 firefox。如何安装、卸载和检查我自己的根证书的安装?
在此处查看要点:https://gist.github.com/pehrlich/08852e8f7da81e136d70
它的内容是 CertificateNSS.cpp
,复制在这里:
#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;
}
NSS 附带的文档非常少,而且残留严重API。它是如何工作的?它用于 Window 和 Mac 以及 Chrome 和 linux 上的 firefox。如何安装、卸载和检查我自己的根证书的安装?
在此处查看要点:https://gist.github.com/pehrlich/08852e8f7da81e136d70
它的内容是 CertificateNSS.cpp
,复制在这里:
#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;
}