Bug 278689 - Multiple Certificates with the same subject are not shown in the digital signature select cert combo (only one is shown) r=dkeeler

This commit is contained in:
Kaspar Brand 2015-09-05 07:52:00 +02:00
parent e1026febc7
commit 84007f05ef
2 changed files with 43 additions and 10 deletions

View File

@ -36,6 +36,7 @@ NS_IMETHODIMP nsCertPicker::PickByUsage(nsIInterfaceRequestor *ctx,
int32_t certUsage,
bool allowInvalid,
bool allowDuplicateNicknames,
const nsAString &emailAddress,
bool *canceled,
nsIX509Cert **_retval)
{
@ -53,7 +54,7 @@ NS_IMETHODIMP nsCertPicker::PickByUsage(nsIInterfaceRequestor *ctx,
ScopedCERTCertList allcerts(PK11_ListCerts(PK11CertListUnique, ctx));
}
/* find all user certs that are valid and for SSL */
/* find all user certs that are valid for the specified usage */
/* note that we are allowing expired certs in this list */
ScopedCERTCertList certList(
@ -66,6 +67,32 @@ NS_IMETHODIMP nsCertPicker::PickByUsage(nsIInterfaceRequestor *ctx,
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);
}
}
ScopedCERTCertNicknames nicknames(getNSSCertNicknamesFromCertList(certList.get()));
if (!nicknames) {
return NS_ERROR_NOT_AVAILABLE;
@ -88,20 +115,16 @@ NS_IMETHODIMP nsCertPicker::PickByUsage(nsIInterfaceRequestor *ctx,
node = CERT_LIST_NEXT(node)
)
{
nsNSSCertificate *tempCert = nsNSSCertificate::Create(node->cert);
RefPtr<nsNSSCertificate> tempCert(nsNSSCertificate::Create(node->cert));
if (tempCert) {
// XXX we really should be using an nsCOMPtr instead of manually add-refing,
// but nsNSSCertificate does not have a default constructor.
NS_ADDREF(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;
@ -111,14 +134,19 @@ NS_IMETHODIMP nsCertPicker::PickByUsage(nsIInterfaceRequestor *ctx,
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;
}
NS_RELEASE(tempCert);
++CertsToUse;
}
}

View File

@ -8,13 +8,18 @@
interface nsIX509Cert;
interface nsIInterfaceRequestor;
[scriptable, uuid(06d018e0-d41b-4629-a4fc-daaa6029888e)]
[scriptable, uuid(92396323-23f2-49e0-bf98-a25a725231ab)]
interface nsIUserCertPicker : nsISupports {
nsIX509Cert pickByUsage(in nsIInterfaceRequestor ctx,
in wstring selectedNickname,
in long certUsage, // as defined by NSS enum SECCertUsage
in boolean allowInvalid,
in boolean allowDuplicateNicknames,
in AString emailAddress, // optional - if non-empty,
// skip certificates which
// have at least one e-mail
// address but do not
// include this specific one
out boolean canceled);
};