mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 05:11:03 +00:00
81d61fa324
- Bug 1265036 - Use NS_ABORT_OOM() if try_realloc() fails. r=billm (c30f4f83d5) - Bug 1263292 - Handle calling realloc(0) (r=jld) (f292859ee9) - Bug 1256366 - Remove linear and exponential stats collection from histogram.cc. r=gfritzsche (f9a1c869a1) - Bug 1263953 - Reduce the growth rate of Pickle. r=wmccloskey (6eb5228490) - Bug 1233275 - Copy environment for IPC using NSPR. r=jld (2004db748e) - Bug 1261094 - Improve how MessageChannel::mInterruptStack is used in IPC code, r=jld (56e2c114a4) - Bug 1246931: Include dbus.h in DBus IPC headers, r=shuang (43e797c2d8) - Bug 1264887: Make DBus helpers available on desktop builds, r=shuang (58bff1f640) - Bug 1268130, part 1 - Reimplement ByteLengthIsValid using CheckedInt. r=froydnj (6018e22ae0) - Bug 1268130, part 2 - Make ByteLengthIsValid failures fatal in release builds. r=froydnj (f9d934a498) - Bug 1269365, part 1 - Swap fallible and infallible TArray ParamTraits. r=froydnj (ad423bc04d) - Bug 1269365, part 2 - Make ParamTraits<nsTArray<E>>::Read use infallible allocation. r=froydnj (9b902a5bc4) - Bug 1269365, part 3 - Use infallible array allocation in implementSpecialArrayPickling. r=froydnj (592fe648d3) - Bug 1264820 - Measure IPC reply size in telemetry (r=mccr8) (62c54d3141) - Bug 1268938 - Use the name of the original message in Send for reply telemetry. r=billm (a2de5c6a91) - Bug 1266954: Remove temporary |ScopedClose| from PDU receive code, r=jacheng (cb06315c33) - Bug 1142109 - Fix IPDL tests (r=dvander) (df3f0cda32) - Bug 1177013 - Fix IPDL tests for not allowing CPOWs during sync (r=dvander) (5da0a8a4c9) - Bug 1261307: Convert RIL sockets to |UniquePtr|, r=nfroyd (08609783b3) - Bug 1253622 - Move the mozilla-trace.h generation into moz.build; r=ted (f01dc418bc) - Bug 1267318 ignore cert expiration for mozilla-signed packages, r=dkeeler (7a1ddd6090) - Bug 1029173 - Clean up nsDataSignatureVerifier. r=keeler (f9602341ea) - bug 1267463 - add a more nuanced subject common name fallback option for prerelease channels r=Cykesiopka,jcj (9b55320c9b) - Bug 1253108 - Enable ESLint "strict" rule for PSM. r=keeler (54802bdc38) - Bug 1255425 - part 1 - clearly delineate steps when outputting HSTS preload list; r=keeler (79f73189c8) - Bug 1251801 - Fully implement nsNSSShutDownObject and obviate manual NSS resource management. r=keeler (af32315d3f) - Bug 1251801 - Improve handling of PK11_* function error codes. r=keeler (9f2c8ac64b) - Fix unified-build bustage from bug 1264706. r=bustage (11bc0417c7) - Bug 1265164 - Always use nsCOMPtrs with getNSSDialogs(). r=keeler (ce5a703972)
213 lines
6.4 KiB
C++
213 lines
6.4 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "nsCertPicker.h"
|
|
|
|
#include "ScopedNSSTypes.h"
|
|
#include "cert.h"
|
|
#include "mozilla/RefPtr.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsICertPickDialogs.h"
|
|
#include "nsIInterfaceRequestor.h"
|
|
#include "nsIServiceManager.h"
|
|
#include "nsMemory.h"
|
|
#include "nsNSSCertHelper.h"
|
|
#include "nsNSSCertificate.h"
|
|
#include "nsNSSComponent.h"
|
|
#include "nsNSSHelper.h"
|
|
#include "nsNSSShutDown.h"
|
|
#include "nsReadableUtils.h"
|
|
#include "nsString.h"
|
|
#include "pkix/pkixtypes.h"
|
|
|
|
using namespace mozilla;
|
|
|
|
NS_IMPL_ISUPPORTS(nsCertPicker, nsIUserCertPicker)
|
|
|
|
nsCertPicker::nsCertPicker()
|
|
{
|
|
}
|
|
|
|
nsCertPicker::~nsCertPicker()
|
|
{
|
|
nsNSSShutDownPreventionLock locker;
|
|
if (isAlreadyShutDown()) {
|
|
return;
|
|
}
|
|
|
|
shutdown(calledFromObject);
|
|
}
|
|
|
|
NS_IMETHODIMP nsCertPicker::PickByUsage(nsIInterfaceRequestor *ctx,
|
|
const char16_t *selectedNickname,
|
|
int32_t certUsage,
|
|
bool allowInvalid,
|
|
bool allowDuplicateNicknames,
|
|
const nsAString &emailAddress,
|
|
bool *canceled,
|
|
nsIX509Cert **_retval)
|
|
{
|
|
nsNSSShutDownPreventionLock locker;
|
|
if (isAlreadyShutDown()) {
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
int32_t selectedIndex = -1;
|
|
bool selectionFound = false;
|
|
char16_t **certNicknameList = nullptr;
|
|
char16_t **certDetailsList = nullptr;
|
|
CERTCertListNode* node = nullptr;
|
|
nsresult rv = NS_OK;
|
|
|
|
{
|
|
// Iterate over all certs. This assures that user is logged in to all hardware tokens.
|
|
nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
|
|
ScopedCERTCertList allcerts(PK11_ListCerts(PK11CertListUnique, ctx));
|
|
}
|
|
|
|
/* find all user certs that are valid for the specified usage */
|
|
/* note that we are allowing expired certs in this list */
|
|
|
|
ScopedCERTCertList certList(
|
|
CERT_FindUserCertsByUsage(CERT_GetDefaultCertDB(),
|
|
(SECCertUsage)certUsage,
|
|
!allowDuplicateNicknames,
|
|
!allowInvalid,
|
|
ctx));
|
|
if (!certList) {
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
/* if a (non-empty) emailAddress argument is supplied to PickByUsage, */
|
|
/* remove non-matching certificates from the candidate list */
|
|
|
|
if (!emailAddress.IsEmpty()) {
|
|
node = CERT_LIST_HEAD(certList);
|
|
while (!CERT_LIST_END(node, certList)) {
|
|
/* if the cert has at least one e-mail address, check if suitable */
|
|
if (CERT_GetFirstEmailAddress(node->cert)) {
|
|
RefPtr<nsNSSCertificate> tempCert(nsNSSCertificate::Create(node->cert));
|
|
bool match = false;
|
|
rv = tempCert->ContainsEmailAddress(emailAddress, &match);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
if (!match) {
|
|
/* doesn't contain the specified address, so remove from the list */
|
|
CERTCertListNode* freenode = node;
|
|
node = CERT_LIST_NEXT(node);
|
|
CERT_RemoveCertListNode(freenode);
|
|
continue;
|
|
}
|
|
}
|
|
node = CERT_LIST_NEXT(node);
|
|
}
|
|
}
|
|
|
|
UniqueCERTCertNicknames nicknames(
|
|
getNSSCertNicknamesFromCertList(certList.get()));
|
|
if (!nicknames) {
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
certNicknameList = (char16_t **)moz_xmalloc(sizeof(char16_t *) * nicknames->numnicknames);
|
|
certDetailsList = (char16_t **)moz_xmalloc(sizeof(char16_t *) * nicknames->numnicknames);
|
|
|
|
if (!certNicknameList || !certDetailsList) {
|
|
free(certNicknameList);
|
|
free(certDetailsList);
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
int32_t CertsToUse;
|
|
|
|
for (CertsToUse = 0, node = CERT_LIST_HEAD(certList.get());
|
|
!CERT_LIST_END(node, certList.get()) &&
|
|
CertsToUse < nicknames->numnicknames;
|
|
node = CERT_LIST_NEXT(node)
|
|
)
|
|
{
|
|
RefPtr<nsNSSCertificate> tempCert(nsNSSCertificate::Create(node->cert));
|
|
|
|
if (tempCert) {
|
|
|
|
nsAutoString i_nickname(NS_ConvertUTF8toUTF16(nicknames->nicknames[CertsToUse]));
|
|
nsAutoString nickWithSerial;
|
|
nsAutoString details;
|
|
|
|
if (!selectionFound) {
|
|
/* for the case when selectedNickname refers to a bare nickname */
|
|
if (i_nickname == nsDependentString(selectedNickname)) {
|
|
selectedIndex = CertsToUse;
|
|
selectionFound = true;
|
|
}
|
|
}
|
|
|
|
if (NS_SUCCEEDED(tempCert->FormatUIStrings(i_nickname, nickWithSerial, details))) {
|
|
certNicknameList[CertsToUse] = ToNewUnicode(nickWithSerial);
|
|
certDetailsList[CertsToUse] = ToNewUnicode(details);
|
|
if (!selectionFound) {
|
|
/* for the case when selectedNickname refers to nickname + serial */
|
|
if (nickWithSerial == nsDependentString(selectedNickname)) {
|
|
selectedIndex = CertsToUse;
|
|
selectionFound = true;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
certNicknameList[CertsToUse] = nullptr;
|
|
certDetailsList[CertsToUse] = nullptr;
|
|
}
|
|
|
|
++CertsToUse;
|
|
}
|
|
}
|
|
|
|
if (CertsToUse) {
|
|
nsCOMPtr<nsICertPickDialogs> dialogs;
|
|
rv = getNSSDialogs(getter_AddRefs(dialogs), NS_GET_IID(nsICertPickDialogs),
|
|
NS_CERTPICKDIALOGS_CONTRACTID);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
// Show the cert picker dialog and get the index of the selected cert.
|
|
rv = dialogs->PickCertificate(ctx, (const char16_t**)certNicknameList,
|
|
(const char16_t**)certDetailsList,
|
|
CertsToUse, &selectedIndex, canceled);
|
|
}
|
|
}
|
|
|
|
int32_t i;
|
|
for (i = 0; i < CertsToUse; ++i) {
|
|
free(certNicknameList[i]);
|
|
free(certDetailsList[i]);
|
|
}
|
|
free(certNicknameList);
|
|
free(certDetailsList);
|
|
|
|
if (!CertsToUse) {
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
if (NS_SUCCEEDED(rv) && !*canceled) {
|
|
for (i = 0, node = CERT_LIST_HEAD(certList);
|
|
!CERT_LIST_END(node, certList);
|
|
++i, node = CERT_LIST_NEXT(node)) {
|
|
|
|
if (i == selectedIndex) {
|
|
RefPtr<nsNSSCertificate> cert = nsNSSCertificate::Create(node->cert);
|
|
if (!cert) {
|
|
rv = NS_ERROR_OUT_OF_MEMORY;
|
|
break;
|
|
}
|
|
|
|
cert.forget(_retval);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return rv;
|
|
}
|