--- a/security/manager/ssl/nsNSSCertificateDB.cpp
+++ b/security/manager/ssl/nsNSSCertificateDB.cpp
@@ -340,19 +340,27 @@ nsNSSCertificateDB::handleCACertDownload
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Created nick \"%s\"\n", nickname.get()));
nsNSSCertTrust trust;
trust.SetValidCA();
trust.AddCATrust(!!(trustBits & nsIX509CertDB::TRUSTED_SSL),
!!(trustBits & nsIX509CertDB::TRUSTED_EMAIL),
!!(trustBits & nsIX509CertDB::TRUSTED_OBJSIGN));
- if (CERT_AddTempCertToPerm(tmpCert.get(), nickname.get(),
- trust.GetTrust()) != SECSuccess) {
- return NS_ERROR_FAILURE;
+ UniquePK11SlotInfo slot(PK11_GetInternalKeySlot());
+ SECStatus srv = PK11_ImportCert(slot.get(), tmpCert.get(), CK_INVALID_HANDLE,
+ nickname.get(),
+ false); // this parameter is ignored by NSS
+ if (srv != SECSuccess) {
+ return MapSECStatus(srv);
+ }
+ // NSS ignores the first argument to CERT_ChangeCertTrust
+ srv = CERT_ChangeCertTrust(nullptr, tmpCert.get(), trust.GetTrust());
+ if (srv != SECSuccess) {
+ return MapSECStatus(srv);
}
// Import additional delivered certificates that can be verified.
// build a CertList for filtering
UniqueCERTCertList certList(CERT_NewCertList());
if (!certList) {
return NS_ERROR_FAILURE;
@@ -502,44 +510,40 @@ ImportCertsIntoTempStorage(int numcerts,
if (CERT_FilterCertListByUsage(filteredCerts.get(), usage, caOnly)
!= SECSuccess) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
-static SECStatus
-ImportCertsIntoPermanentStorage(const UniqueCERTCertList& certChain,
- const SECCertUsage usage, const bool caOnly)
+static nsresult
+ImportCertsIntoPermanentStorage(const UniqueCERTCertList& certChain)
{
- int chainLen = 0;
- for (CERTCertListNode *chainNode = CERT_LIST_HEAD(certChain);
+ bool encounteredFailure = false;
+ PRErrorCode savedErrorCode = 0;
+ UniquePK11SlotInfo slot(PK11_GetInternalKeySlot());
+ for (CERTCertListNode* chainNode = CERT_LIST_HEAD(certChain);
!CERT_LIST_END(chainNode, certChain);
chainNode = CERT_LIST_NEXT(chainNode)) {
- chainLen++;
+ UniquePORTString nickname(CERT_MakeCANickname(chainNode->cert));
+ SECStatus srv = PK11_ImportCert(slot.get(), chainNode->cert,
+ CK_INVALID_HANDLE, nickname.get(),
+ false); // this parameter is ignored by NSS
+ if (srv != SECSuccess) {
+ encounteredFailure = true;
+ savedErrorCode = PR_GetError();
+ }
}
- SECItem **rawArray;
- rawArray = (SECItem **) PORT_Alloc(chainLen * sizeof(SECItem *));
- if (!rawArray) {
- return SECFailure;
+ if (encounteredFailure) {
+ return GetXPCOMFromNSSError(savedErrorCode);
}
- int i = 0;
- for (CERTCertListNode *chainNode = CERT_LIST_HEAD(certChain);
- !CERT_LIST_END(chainNode, certChain);
- chainNode = CERT_LIST_NEXT(chainNode), i++) {
- rawArray[i] = &chainNode->cert->derCert;
- }
- SECStatus srv = CERT_ImportCerts(CERT_GetDefaultCertDB(), usage, chainLen,
- rawArray, nullptr, true, caOnly, nullptr);
-
- PORT_Free(rawArray);
- return srv;
+ return NS_OK;
}
NS_IMETHODIMP
nsNSSCertificateDB::ImportEmailCertificate(uint8_t* data, uint32_t length,
nsIInterfaceRequestor* ctx)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
@@ -588,21 +592,19 @@ nsNSSCertificateDB::ImportEmailCertifica
mozilla::pkix::Result result =
certVerifier->VerifyCert(node->cert, certificateUsageEmailRecipient,
mozilla::pkix::Now(), ctx, nullptr, certChain);
if (result != mozilla::pkix::Success) {
nsCOMPtr<nsIX509Cert> certToShow = nsNSSCertificate::Create(node->cert);
DisplayCertificateAlert(ctx, "NotImportingUnverifiedCert", certToShow, locker);
continue;
}
- SECStatus srv = ImportCertsIntoPermanentStorage(certChain,
- certUsageEmailRecipient,
- false);
- if (srv != SECSuccess) {
- return NS_ERROR_FAILURE;
+ rv = ImportCertsIntoPermanentStorage(certChain);
+ if (NS_FAILED(rv)) {
+ return rv;
}
CERT_SaveSMimeProfile(node->cert, nullptr, nullptr);
}
return NS_OK;
}
nsresult
@@ -645,20 +647,19 @@ nsNSSCertificateDB::ImportValidCACertsIn
certVerifier->VerifyCert(node->cert, certificateUsageVerifyCA,
mozilla::pkix::Now(), ctx, nullptr, certChain);
if (result != mozilla::pkix::Success) {
nsCOMPtr<nsIX509Cert> certToShow = nsNSSCertificate::Create(node->cert);
DisplayCertificateAlert(ctx, "NotImportingUnverifiedCert", certToShow, proofOfLock);
continue;
}
- SECStatus srv = ImportCertsIntoPermanentStorage(certChain, certUsageAnyCA,
- true);
- if (srv != SECSuccess) {
- return NS_ERROR_FAILURE;
+ nsresult rv = ImportCertsIntoPermanentStorage(certChain);
+ if (NS_FAILED(rv)) {
+ return rv;
}
}
return NS_OK;
}
void nsNSSCertificateDB::DisplayCertificateAlert(nsIInterfaceRequestor *ctx,
const char *stringID,
@@ -1274,18 +1275,25 @@ nsNSSCertificateDB::AddCertFromBase64(co
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Created nick \"%s\"\n", nickname.get()));
rv = attemptToLogInWithDefaultPassword();
if (NS_WARN_IF(rv != NS_OK)) {
return rv;
}
- SECStatus srv = CERT_AddTempCertToPerm(tmpCert.get(), nickname.get(),
- trust.GetTrust());
+ UniquePK11SlotInfo slot(PK11_GetInternalKeySlot());
+ SECStatus srv = PK11_ImportCert(slot.get(), tmpCert.get(), CK_INVALID_HANDLE,
+ nickname.get(),
+ false); // this parameter is ignored by NSS
+ if (srv != SECSuccess) {
+ return MapSECStatus(srv);
+ }
+ // NSS ignores the first argument to CERT_ChangeCertTrust
+ srv = CERT_ChangeCertTrust(nullptr, tmpCert.get(), trust.GetTrust());
if (srv != SECSuccess) {
return MapSECStatus(srv);
}
newCert.forget(addedCertificate);
return NS_OK;
}
NS_IMETHODIMP