Bug 1281665 - Change nsIClientAuthDialogs.chooseCertificate() to use hostname instead of CN. r=keeler

chooseCertificate() currently uses a concatenation of the Common Name of the
server cert and the port of the server to allow the user to identify the server
requesting client authentication. Unfortunately, this approach is flawed, since
it doesn't take into account things like SAN entries, which might be very
different from the CN.

Using the hostname instead avoids this problem.

MozReview-Commit-ID: 6XjGCknWNi9

--HG--
extra : transplant_source : k%10N%7B%E8%A4%9B%C9%9A%23Q%D1%99%D2%A3%C0.%2B%7F%A5
This commit is contained in:
Cykesiopka 2016-07-26 20:16:58 +08:00
parent 98189913b6
commit 8297eb8984
7 changed files with 39 additions and 35 deletions

View File

@ -212,13 +212,14 @@ NSSDialogs.prototype = {
this.showPrompt(p);
},
chooseCertificate: function(ctx, cnAndPort, organization, issuerOrg, certList,
selectedIndex) {
chooseCertificate: function(ctx, hostname, port, organization, issuerOrg,
certList, selectedIndex) {
let rememberSetting =
Services.prefs.getBoolPref("security.remember_cert_checkbox_default_setting");
let serverRequestedDetails = [
this.escapeHTML(cnAndPort),
this.formatString("clientAuthAsk.hostnameAndPort",
[hostname, port.toString()]),
this.formatString("clientAuthAsk.organization", [organization]),
this.formatString("clientAuthAsk.issuer", [issuerOrg]),
].join("<br/>");

View File

@ -24,6 +24,10 @@ clientAuthAsk.remember.label=Remember this decision
# %1$S is the nickname of the cert.
# %2$S is the serial number of the cert in AA:BB:CC hex format.
clientAuthAsk.nickAndSerial=%1$S [%2$S]
# LOCALIZATION NOTE(clientAuthAsk.hostnameAndPort):
# %1$S is the hostname of the server.
# %2$S is the port of the server.
clientAuthAsk.hostnameAndPort=%1$S:%2$S
# LOCALIZATION NOTE(clientAuthAsk.organization): %S is the Organization of the
# server cert.
clientAuthAsk.organization=Organization: "%S"

View File

@ -58,6 +58,10 @@ clientAuthRemember=Remember this decision
# %1$S is the nickname of the cert.
# %2$S is the serial number of the cert in AA:BB:CC hex format.
clientAuthNickAndSerial=%1$S [%2$S]
# LOCALIZATION NOTE(clientAuthHostnameAndPort):
# %1$S is the hostname of the server.
# %2$S is the port of the server.
clientAuthHostnameAndPort=%1$S:%2$S
# LOCALIZATION NOTE(clientAuthMessage1): %S is the Organization of the server
# cert.
clientAuthMessage1=Organization: “%S”

View File

@ -158,9 +158,10 @@ nsNSSDialogs::ConfirmDownloadCACert(nsIInterfaceRequestor *ctx,
NS_IMETHODIMP
nsNSSDialogs::ChooseCertificate(nsIInterfaceRequestor* ctx,
const nsAString& cnAndPort,
const nsAString& organization,
const nsAString& issuerOrg,
const nsACString& hostname,
int32_t port,
const nsACString& organization,
const nsACString& issuerOrg,
nsIArray* certList,
/*out*/ uint32_t* selectedIndex,
/*out*/ bool* certificateChosen)
@ -196,15 +197,20 @@ nsNSSDialogs::ChooseCertificate(nsIInterfaceRequestor* ctx,
return rv;
}
rv = block->SetString(0, PromiseFlatString(cnAndPort).get());
rv = block->SetString(0, NS_ConvertUTF8toUTF16(hostname).get());
if (NS_FAILED(rv)) {
return rv;
}
rv = block->SetString(1, PromiseFlatString(organization).get());
rv = block->SetString(1, NS_ConvertUTF8toUTF16(organization).get());
if (NS_FAILED(rv)) {
return rv;
}
rv = block->SetString(2, PromiseFlatString(issuerOrg).get());
rv = block->SetString(2, NS_ConvertUTF8toUTF16(issuerOrg).get());
if (NS_FAILED(rv)) {
return rv;
}
rv = block->SetInt(0, port);
if (NS_FAILED(rv)) {
return rv;
}

View File

@ -42,13 +42,17 @@ function onLoad() {
rememberBox.label = bundle.getString("clientAuthRemember");
rememberBox.checked = rememberSetting;
let cnAndPort = dialogParams.GetString(0);
let hostname = dialogParams.GetString(0);
let org = dialogParams.GetString(1);
let issuerOrg = dialogParams.GetString(2);
let port = dialogParams.GetInt(0);
let formattedOrg = bundle.getFormattedString("clientAuthMessage1", [org]);
let formattedIssuerOrg = bundle.getFormattedString("clientAuthMessage2",
[issuerOrg]);
setText("hostname", cnAndPort);
let formattedHostnameAndPort =
bundle.getFormattedString("clientAuthHostnameAndPort",
[hostname, port.toString()]);
setText("hostname", formattedHostnameAndPort);
setText("organization", formattedOrg);
setText("issuer", formattedIssuerOrg);

View File

@ -18,7 +18,8 @@ interface nsIClientAuthDialogs : nsISupports
*
* @param ctx Context that allows at least nsIClientAuthUserDecision to be
* queried.
* @param cnAndPort Common Name of the server cert and the port of the server.
* @param hostname Hostname of the server.
* @param port Port of the server.
* @param organization Organization field of the server cert.
* @param issuerOrg Organization field of the issuer cert of the server cert.
* @param certList List of certificates the user can choose from.
@ -27,9 +28,10 @@ interface nsIClientAuthDialogs : nsISupports
* @return true if a certificate was chosen. false if the user canceled.
*/
boolean chooseCertificate(in nsIInterfaceRequestor ctx,
in AString cnAndPort,
in AString organization,
in AString issuerOrg,
in AUTF8String hostname,
in long port,
in AUTF8String organization,
in AUTF8String issuerOrg,
in nsIArray certList,
out unsigned long selectedIndex);
};

View File

@ -2226,31 +2226,14 @@ ClientAuthDataRunnable::RunOnTargetThread()
goto loser;
}
// Get CN and O of the subject and O of the issuer
UniquePORTString ccn(CERT_GetCommonName(&mServerCert->subject));
NS_ConvertUTF8toUTF16 cn(ccn.get());
int32_t port;
mSocketInfo->GetPort(&port);
nsAutoString cn_host_port;
if (ccn && strcmp(ccn.get(), hostname) == 0) {
cn_host_port.Append(cn);
cn_host_port.Append(':');
cn_host_port.AppendInt(port);
} else {
cn_host_port.Append(cn);
cn_host_port.AppendLiteral(" (");
cn_host_port.Append(':');
cn_host_port.AppendInt(port);
cn_host_port.Append(')');
}
UniquePORTString corg(CERT_GetOrgName(&mServerCert->subject));
NS_ConvertUTF8toUTF16 org(corg.get());
nsAutoCString org(corg.get());
UniquePORTString cissuer(CERT_GetOrgName(&mServerCert->issuer));
NS_ConvertUTF8toUTF16 issuer(cissuer.get());
nsAutoCString issuer(cissuer.get());
nsCOMPtr<nsIMutableArray> certArray = nsArrayBase::Create();
if (!certArray) {
@ -2282,7 +2265,7 @@ ClientAuthDataRunnable::RunOnTargetThread()
uint32_t selectedIndex = 0;
bool certChosen = false;
rv = dialogs->ChooseCertificate(mSocketInfo, cn_host_port, org, issuer,
rv = dialogs->ChooseCertificate(mSocketInfo, hostname, port, org, issuer,
certArray, &selectedIndex, &certChosen);
if (NS_FAILED(rv)) {
goto loser;