From c4527937e9fa7fc62b19a5e569e898d65a515df2 Mon Sep 17 00:00:00 2001
From: "reed%reedloden.com"
Date: Tue, 30 Oct 2007 20:26:28 +0000
Subject: [PATCH] Bug 398718 - "Better explanatory text for SSL error pages"
[p=kaie/johnath r=rrelyea r=biesi a=blocking1.9+ for M9]
git-svn-id: svn://10.0.0.236/trunk@238348 18797224-902f-48f8-a5cc-f745e15eee43
---
.../en-US/chrome/overrides/netError.dtd | 11 +
.../locale/en-US/global/netError.dtd | 8 +
mozilla/docshell/base/nsDocShell.cpp | 22 +-
.../docshell/resources/content/netError.xhtml | 2 +
mozilla/dom/locales/en-US/chrome/netError.dtd | 8 +
.../base/public/nsINSSErrorsService.idl | 12 +-
.../en-US/chrome/pipnss/pipnss.properties | 20 +-
.../manager/ssl/public/nsIX509Cert3.idl | 4 +-
.../manager/ssl/src/nsNSSCertificate.cpp | 13 +
.../manager/ssl/src/nsNSSComponent.cpp | 32 ++
.../security/manager/ssl/src/nsNSSErrors.cpp | 22 +-
.../security/manager/ssl/src/nsNSSIOLayer.cpp | 306 +++++++++++++++---
.../themes/pinstripe/global/netError.css | 1 +
.../themes/winstripe/global/netError.css | 1 +
14 files changed, 399 insertions(+), 63 deletions(-)
diff --git a/mozilla/browser/locales/en-US/chrome/overrides/netError.dtd b/mozilla/browser/locales/en-US/chrome/overrides/netError.dtd
index 9487d491575..a8e546bb704 100644
--- a/mozilla/browser/locales/en-US/chrome/overrides/netError.dtd
+++ b/mozilla/browser/locales/en-US/chrome/overrides/netError.dtd
@@ -123,6 +123,17 @@
">
+
+
+ This could be a problem with the server's configuration, or it could be
+someone trying to impersonate the server.
+ If you have connected to this server successfully in the past, the error may
+be temporary, and you can try again later.
+ You can see and change your current list of servers with known security problems
+ in your advanced encryption settings.
+
+">
diff --git a/mozilla/camino/embed-replacements/locale/en-US/global/netError.dtd b/mozilla/camino/embed-replacements/locale/en-US/global/netError.dtd
index 406bde0de08..dff0da078b2 100644
--- a/mozilla/camino/embed-replacements/locale/en-US/global/netError.dtd
+++ b/mozilla/camino/embed-replacements/locale/en-US/global/netError.dtd
@@ -54,6 +54,14 @@
The page you are trying to view can not be shown because the authenticity of the received data could not be verified.
- Please contact the web site owners to inform them of this problem.
">
+
+
+This could be a problem with the server's configuration, or it could be someone trying to impersonate the server.
+If you have connected to this server successfully in the past, the error may be temporary, and you can try again later.
+You can see and change your current list of servers with known security problems in your advanced encryption settings.
+
+">
+
Attack sites try to install programs that steal private information, use your computer to attack others, or damage your system.
diff --git a/mozilla/docshell/base/nsDocShell.cpp b/mozilla/docshell/base/nsDocShell.cpp
index 1d33b089882..20bda6c3e2c 100644
--- a/mozilla/docshell/base/nsDocShell.cpp
+++ b/mozilla/docshell/base/nsDocShell.cpp
@@ -2931,6 +2931,15 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI,
error.AssignLiteral("netTimeout");
}
else if (NS_ERROR_GET_MODULE(aError) == NS_ERROR_MODULE_SECURITY) {
+ nsCOMPtr nsserr =
+ do_GetService(NS_NSS_ERRORS_SERVICE_CONTRACTID);
+
+ PRUint32 errorClass;
+ if (!nsserr ||
+ NS_FAILED(nsserr->GetErrorClass(aError, &errorClass))) {
+ errorClass = nsINSSErrorsService::ERROR_CLASS_SSL_PROTOCOL;
+ }
+
nsCOMPtr securityInfo;
nsCOMPtr tsi;
if (aFailedChannel)
@@ -2942,20 +2951,23 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI,
}
else {
// No channel, let's obtain the generic error message
- nsCOMPtr nsserr =
- do_GetService(NS_NSS_ERRORS_SERVICE_CONTRACTID);
if (nsserr) {
nsserr->GetErrorMessage(aError, messageStr);
}
}
- if (!messageStr.IsEmpty())
- error.AssignLiteral("nssFailure2");
+ if (!messageStr.IsEmpty()) {
+ if (errorClass == nsINSSErrorsService::ERROR_CLASS_BAD_CERT) {
+ error.AssignLiteral("nssBadCert");
+ } else {
+ error.AssignLiteral("nssFailure2");
+ }
+ }
} else if (NS_ERROR_PHISHING_URI == aError || NS_ERROR_MALWARE_URI == aError) {
nsCAutoString host;
aURI->GetHost(host);
CopyUTF8toUTF16(host, formatStrs[0]);
formatStrCount = 1;
-
+
// Malware and phishing detectors may want to use an alternate error
// page, but if the pref's not set, we'll fall back on the standard page
nsXPIDLCString alternateErrorPage;
diff --git a/mozilla/docshell/resources/content/netError.xhtml b/mozilla/docshell/resources/content/netError.xhtml
index 886410ebeb3..01d24593633 100644
--- a/mozilla/docshell/resources/content/netError.xhtml
+++ b/mozilla/docshell/resources/content/netError.xhtml
@@ -202,6 +202,7 @@
&proxyConnectFailure.title;
&contentEncodingError.title;
&nssFailure2.title;
+ &nssBadCert.title;
&malwareBlocked.title;
@@ -222,6 +223,7 @@
&proxyConnectFailure.longDesc;
&contentEncodingError.longDesc;
&nssFailure2.longDesc;
+
&nssBadCert.longDesc;
&malwareBlocked.longDesc;
diff --git a/mozilla/dom/locales/en-US/chrome/netError.dtd b/mozilla/dom/locales/en-US/chrome/netError.dtd
index 4ea705029c3..d99b2aebd6e 100644
--- a/mozilla/dom/locales/en-US/chrome/netError.dtd
+++ b/mozilla/dom/locales/en-US/chrome/netError.dtd
@@ -54,6 +54,14 @@
The page you are trying to view can not be shown because the authenticity of the received data could not be verified.- Please contact the web site owners to inform them of this problem.
">
+
+
+This could be a problem with the server's configuration, or it could be someone trying to impersonate the server.
+If you have connected to this server successfully in the past, the error may be temporary, and you can try again later.
+You can see and change your current list of servers with known security problems in your advanced encryption settings.
+
+">
+
Attack sites try to install programs that steal private information, use your computer to attack others, or damage your system.
diff --git a/mozilla/netwerk/base/public/nsINSSErrorsService.idl b/mozilla/netwerk/base/public/nsINSSErrorsService.idl
index 05f0d44d3fc..871bade60d7 100644
--- a/mozilla/netwerk/base/public/nsINSSErrorsService.idl
+++ b/mozilla/netwerk/base/public/nsINSSErrorsService.idl
@@ -39,7 +39,7 @@
#include "nsISupports.idl"
-[scriptable, uuid(c6ac6e5d-9db1-4cad-bedc-e2d226913c21)]
+[scriptable, uuid(3a5c7a0f-f5da-4a8b-a748-d7c5a528f33b)]
interface nsINSSErrorsService : nsISupports
{
/**
@@ -61,4 +61,14 @@ interface nsINSSErrorsService : nsISupports
* return A localized human readable error explanation.
*/
AString getErrorMessage(in nsresult aXPCOMErrorCode);
+
+ /**
+ * Function will fail if aXPCOMErrorCode is not an NSS error code.
+ * @param aXPCOMErrorCode An error code obtain using getXPCOMFromNSSError
+ * return the
+ */
+ PRUint32 getErrorClass(in nsresult aXPCOMErrorCode);
+
+ const unsigned long ERROR_CLASS_SSL_PROTOCOL = 1;
+ const unsigned long ERROR_CLASS_BAD_CERT = 2;
};
diff --git a/mozilla/security/manager/locales/en-US/chrome/pipnss/pipnss.properties b/mozilla/security/manager/locales/en-US/chrome/pipnss/pipnss.properties
index 5b71d083798..a08e96f687c 100644
--- a/mozilla/security/manager/locales/en-US/chrome/pipnss/pipnss.properties
+++ b/mozilla/security/manager/locales/en-US/chrome/pipnss/pipnss.properties
@@ -337,12 +337,24 @@ PSMERR_HostReusedIssuerSerial=You have received an invalid certificate. Please
SSLConnectionErrorPrefix=An error occurred during a connection to %S.
-certErrorIntro=An error occurred during a connection to %S because it uses an invalid security certificate.
-certErrorUntrusted=The certificate is not trusted or its issuer certificate is invalid.
-certErrorMismatch=The certificate is not valid for domain name %S.
-certErrorExpired=The certificate has expired on %S.
+certErrorIntro=%S uses an invalid security certificate.
+
+certErrorTrust_SelfSigned=The certificate is not trusted because it is self signed.
+certErrorTrust_UnknownIssuer=The certificate is not trusted because the issuer certificate is unknown.
+certErrorTrust_CaInvalid=The certificate is not trusted because it was issued by an invalid CA certificate.
+certErrorTrust_Issuer=The certificate is not trusted because the issuer certificate is not trusted.
+certErrorTrust_ExpiredIssuer=The certificate is not trusted because the issuer certificate has expired.
+certErrorTrust_Untrusted=The certificate does not come from a trusted source.
+
+certErrorMismatch=The certificate is not valid for the name %S.
+certErrorMismatchSingle=The certificate is only valid for name %S.
+certErrorMismatchMultiple=The certificate is only valid for the following names:
+
+certErrorExpired=The certificate expired on %S.
certErrorNotYetValid=The certificate will not be valid until %S.
+certErrorCodePrefix=(Error code: %S)
+
CertInfoIssuedFor=Issued to:
CertInfoIssuedBy=Issued by:
CertInfoValid=Valid
diff --git a/mozilla/security/manager/ssl/public/nsIX509Cert3.idl b/mozilla/security/manager/ssl/public/nsIX509Cert3.idl
index 267135ecb55..c32e301feba 100644
--- a/mozilla/security/manager/ssl/public/nsIX509Cert3.idl
+++ b/mozilla/security/manager/ssl/public/nsIX509Cert3.idl
@@ -42,7 +42,7 @@ interface nsICertVerificationListener;
/**
* Extending nsIX509Cert
*/
-[scriptable, uuid(1362ffab-a683-4504-8038-25ce63b45370)]
+[scriptable, uuid(aa67eb02-ccc8-4f55-84da-bcafff9265ae)]
interface nsIX509Cert3 : nsIX509Cert2 {
/**
@@ -72,6 +72,8 @@ interface nsIX509Cert3 : nsIX509Cert2 {
void exportAsCMS(in unsigned long chainMode,
out unsigned long length,
[retval, array, size_is(length)] out octet data);
+
+ readonly attribute boolean isSelfSigned;
};
[scriptable, uuid(2fd0a785-9f2d-4327-8871-8c3e0783891d)]
diff --git a/mozilla/security/manager/ssl/src/nsNSSCertificate.cpp b/mozilla/security/manager/ssl/src/nsNSSCertificate.cpp
index 6567fa5a6f1..a1a8c542bee 100644
--- a/mozilla/security/manager/ssl/src/nsNSSCertificate.cpp
+++ b/mozilla/security/manager/ssl/src/nsNSSCertificate.cpp
@@ -221,6 +221,19 @@ nsNSSCertificate::GetCertType(PRUint32 *aCertType)
return NS_OK;
}
+NS_IMETHODIMP
+nsNSSCertificate::GetIsSelfSigned(PRBool *aIsSelfSigned)
+{
+ NS_ENSURE_ARG(aIsSelfSigned);
+
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ *aIsSelfSigned = mCert->isRoot;
+ return NS_OK;
+}
+
nsresult
nsNSSCertificate::MarkForPermDeletion()
{
diff --git a/mozilla/security/manager/ssl/src/nsNSSComponent.cpp b/mozilla/security/manager/ssl/src/nsNSSComponent.cpp
index 0ea5da373ee..208002fb65b 100644
--- a/mozilla/security/manager/ssl/src/nsNSSComponent.cpp
+++ b/mozilla/security/manager/ssl/src/nsNSSComponent.cpp
@@ -2228,6 +2228,38 @@ nsNSSComponent::GetXPCOMFromNSSError(PRInt32 aNSPRCode, nsresult *aXPCOMErrorCod
return NS_OK;
}
+NS_IMETHODIMP
+nsNSSComponent::GetErrorClass(nsresult aXPCOMErrorCode, PRUint32 *aErrorClass)
+{
+ NS_ENSURE_ARG(aErrorClass);
+
+ if (NS_ERROR_GET_MODULE(aXPCOMErrorCode) != NS_ERROR_MODULE_SECURITY
+ || NS_ERROR_GET_SEVERITY(aXPCOMErrorCode) != NS_ERROR_SEVERITY_ERROR)
+ return NS_ERROR_FAILURE;
+
+ PRInt32 aNSPRCode = -1 * NS_ERROR_GET_CODE(aXPCOMErrorCode);
+
+ if (!IS_SEC_ERROR(aNSPRCode) && !IS_SSL_ERROR(aNSPRCode))
+ return NS_ERROR_FAILURE;
+
+ switch (aNSPRCode)
+ {
+ case SEC_ERROR_UNKNOWN_ISSUER:
+ case SEC_ERROR_CA_CERT_INVALID:
+ case SEC_ERROR_UNTRUSTED_ISSUER:
+ case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
+ case SEC_ERROR_UNTRUSTED_CERT:
+ case SSL_ERROR_BAD_CERT_DOMAIN:
+ case SEC_ERROR_EXPIRED_CERTIFICATE:
+ *aErrorClass = ERROR_CLASS_BAD_CERT;
+ break;
+ default:
+ *aErrorClass = ERROR_CLASS_SSL_PROTOCOL;
+ break;
+ }
+ return NS_OK;
+}
+
NS_IMETHODIMP
nsNSSComponent::GetErrorMessage(nsresult aXPCOMErrorCode, nsAString &aErrorMessage)
{
diff --git a/mozilla/security/manager/ssl/src/nsNSSErrors.cpp b/mozilla/security/manager/ssl/src/nsNSSErrors.cpp
index 85aca4341d9..6c6cde158ae 100644
--- a/mozilla/security/manager/ssl/src/nsNSSErrors.cpp
+++ b/mozilla/security/manager/ssl/src/nsNSSErrors.cpp
@@ -364,16 +364,30 @@ nsNSSErrors::getErrorMessageFromCode(PRInt32 err,
if (NS_SUCCEEDED(rv))
{
returnedMessage.Append(defMsg);
- returnedMessage.Append(NS_LITERAL_STRING(" "));
+ returnedMessage.Append(NS_LITERAL_STRING("\n"));
}
nsCString error_id(nss_error_id_str);
ToLowerCase(error_id);
NS_ConvertASCIItoUTF16 idU(error_id);
- returnedMessage.Append(NS_LITERAL_STRING("("));
- returnedMessage.Append(idU);
- returnedMessage.Append(NS_LITERAL_STRING(")"));
+ const PRUnichar *params[1];
+ params[0] = idU.get();
+
+ nsString formattedString;
+ rv = component->PIPBundleFormatStringFromName("certErrorCodePrefix",
+ params, 1,
+ formattedString);
+ if (NS_SUCCEEDED(rv)) {
+ returnedMessage.Append(NS_LITERAL_STRING("\n"));
+ returnedMessage.Append(formattedString);
+ returnedMessage.Append(NS_LITERAL_STRING("\n"));
+ }
+ else {
+ returnedMessage.Append(NS_LITERAL_STRING("("));
+ returnedMessage.Append(idU);
+ returnedMessage.Append(NS_LITERAL_STRING(")"));
+ }
}
return NS_OK;
diff --git a/mozilla/security/manager/ssl/src/nsNSSIOLayer.cpp b/mozilla/security/manager/ssl/src/nsNSSIOLayer.cpp
index ecf4f63b51a..bc843fa9c96 100644
--- a/mozilla/security/manager/ssl/src/nsNSSIOLayer.cpp
+++ b/mozilla/security/manager/ssl/src/nsNSSIOLayer.cpp
@@ -599,7 +599,10 @@ void nsSSLIOLayerHelpers::Cleanup()
}
static nsresult
-getErrorMessage(PRInt32 err, const nsString &host,
+getErrorMessage(PRInt32 err,
+ const nsString &host,
+ PRInt32 port,
+ PRBool externalErrorReporting,
nsINSSComponent *component,
nsString &returnedMessage)
{
@@ -610,7 +613,24 @@ getErrorMessage(PRInt32 err, const nsString &host,
if (host.Length())
{
- params[0] = host.get();
+ nsString hostWithPort;
+
+ // For now, hide port when it's 443 and we're reporting the error using
+ // external reporting. In the future a better mechanism should be used
+ // to make a decision about showing the port number, possibly by requiring
+ // the context object to implement a specific interface.
+ // The motivation is that Mozilla browser would like to hide the port number
+ // in error pages in the common case.
+
+ if (externalErrorReporting && port == 443) {
+ params[0] = host.get();
+ }
+ else {
+ hostWithPort = host;
+ hostWithPort.AppendLiteral(":");
+ hostWithPort.AppendInt(port);
+ params[0] = hostWithPort.get();
+ }
nsString formattedString;
rv = component->PIPBundleFormatStringFromName("SSLConnectionErrorPrefix",
@@ -619,7 +639,7 @@ getErrorMessage(PRInt32 err, const nsString &host,
if (NS_SUCCEEDED(rv))
{
returnedMessage.Append(formattedString);
- returnedMessage.Append(NS_LITERAL_STRING("\n"));
+ returnedMessage.Append(NS_LITERAL_STRING("\n\n"));
}
}
@@ -633,10 +653,15 @@ getErrorMessage(PRInt32 err, const nsString &host,
static nsresult
getInvalidCertErrorMessage(PRUint32 multipleCollectedErrors,
- PRInt32 errorCodeToReport,
+ PRErrorCode errorCodeToReport,
+ PRErrorCode errTrust,
+ PRErrorCode errMismatch,
+ PRErrorCode errExpired,
const nsString &host,
const nsString &hostWithPort,
+ PRInt32 port,
nsIX509Cert* ix509,
+ PRBool externalErrorReporting,
nsINSSComponent *component,
nsString &returnedMessage)
{
@@ -645,27 +670,65 @@ getInvalidCertErrorMessage(PRUint32 multipleCollectedErrors,
const PRUnichar *params[1];
nsresult rv;
- if (hostWithPort.Length())
- {
+ // For now, hide port when it's 443 and we're reporting the error using
+ // external reporting. In the future a better mechanism should be used
+ // to make a decision about showing the port number, possibly by requiring
+ // the context object to implement a specific interface.
+ // The motivation is that Mozilla browser would like to hide the port number
+ // in error pages in the common case.
+
+ if (externalErrorReporting && port == 443)
+ params[0] = host.get();
+ else
params[0] = hostWithPort.get();
- nsString formattedString;
- rv = component->PIPBundleFormatStringFromName("certErrorIntro",
- params, 1,
- formattedString);
- if (NS_SUCCEEDED(rv))
- {
- returnedMessage.Append(formattedString);
- returnedMessage.Append(NS_LITERAL_STRING("\n"));
- }
+ nsString formattedString;
+ rv = component->PIPBundleFormatStringFromName("certErrorIntro",
+ params, 1,
+ formattedString);
+ if (NS_SUCCEEDED(rv))
+ {
+ returnedMessage.Append(formattedString);
+ returnedMessage.Append(NS_LITERAL_STRING("\n\n"));
}
if (multipleCollectedErrors & nsICertOverrideService::ERROR_UNTRUSTED)
{
params[0] = host.get();
+ const char *errorID = nsnull;
+ nsCOMPtr cert3 = do_QueryInterface(ix509);
+ if (cert3) {
+ PRBool isSelfSigned;
+ if (NS_SUCCEEDED(cert3->GetIsSelfSigned(&isSelfSigned))
+ && isSelfSigned) {
+ errorID = "certErrorTrust_SelfSigned";
+ }
+ }
+
+ if (!errorID) {
+ switch (errTrust) {
+ case SEC_ERROR_UNKNOWN_ISSUER:
+ errorID = "certErrorTrust_UnknownIssuer";
+ break;
+ case SEC_ERROR_CA_CERT_INVALID:
+ errorID = "certErrorTrust_CaInvalid";
+ break;
+ case SEC_ERROR_UNTRUSTED_ISSUER:
+ errorID = "certErrorTrust_Issuer";
+ break;
+ case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
+ errorID = "certErrorTrust_ExpiredIssuer";
+ break;
+ case SEC_ERROR_UNTRUSTED_CERT:
+ default:
+ errorID = "certErrorTrust_Untrusted";
+ break;
+ }
+ }
+
nsString formattedString;
- rv = component->GetPIPNSSBundleString("certErrorUntrusted",
+ rv = component->GetPIPNSSBundleString(errorID,
formattedString);
if (NS_SUCCEEDED(rv))
{
@@ -676,16 +739,125 @@ getInvalidCertErrorMessage(PRUint32 multipleCollectedErrors,
if (multipleCollectedErrors & nsICertOverrideService::ERROR_MISMATCH)
{
- params[0] = host.get();
+ PRBool useSAN = PR_TRUE; // subject alt name extension
+ PRBool multipleNames = PR_FALSE;
+ nsString allNames;
- nsString formattedString;
- rv = component->PIPBundleFormatStringFromName("certErrorMismatch",
- params, 1,
- formattedString);
- if (NS_SUCCEEDED(rv))
- {
- returnedMessage.Append(formattedString);
- returnedMessage.Append(NS_LITERAL_STRING("\n"));
+ CERTCertificate *nssCert = NULL;
+ CERTCertificateCleaner nssCertCleaner(nssCert);
+ nsCOMPtr cert2 = do_QueryInterface(ix509, &rv);
+ if (cert2)
+ nssCert = cert2->GetCert();
+ if (!nssCert)
+ useSAN = PR_FALSE;
+
+ PRArenaPool *san_arena = nsnull;
+ SECItem altNameExtension = {siBuffer, NULL, 0 };
+ CERTGeneralName *sanNameList = nsnull;
+
+ if (useSAN) {
+ rv = CERT_FindCertExtension(nssCert, SEC_OID_X509_SUBJECT_ALT_NAME,
+ &altNameExtension);
+ if (rv != SECSuccess)
+ useSAN = PR_FALSE;
+ }
+
+ if (useSAN) {
+ san_arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!san_arena)
+ useSAN = PR_FALSE;
+ }
+
+ if (useSAN) {
+ sanNameList = CERT_DecodeAltNameExtension(san_arena, &altNameExtension);
+ if (!sanNameList)
+ useSAN = PR_FALSE;
+ }
+
+ SECITEM_FreeItem(&altNameExtension, PR_FALSE);
+
+ if (useSAN) {
+ CERTGeneralName *current = sanNameList;
+ do {
+ nsAutoString name;
+ switch (current->type) {
+ case certDNSName:
+ name.AssignASCII((char*)current->name.other.data, current->name.other.len);
+ if (!allNames.IsEmpty()) {
+ multipleNames = PR_TRUE;
+ allNames.Append(NS_LITERAL_STRING(" , "));
+ }
+ allNames.Append(name);
+ break;
+
+ case certIPAddress:
+ {
+ char buf[INET6_ADDRSTRLEN];
+ PRNetAddr addr;
+ if (current->name.other.len == 4) {
+ addr.inet.family = PR_AF_INET;
+ memcpy(&addr.inet.ip, current->name.other.data, current->name.other.len);
+ PR_NetAddrToString(&addr, buf, sizeof(buf));
+ name.AssignASCII(buf);
+ } else if (current->name.other.len == 16) {
+ addr.ipv6.family = PR_AF_INET6;
+ memcpy(&addr.ipv6.ip, current->name.other.data, current->name.other.len);
+ PR_NetAddrToString(&addr, buf, sizeof(buf));
+ name.AssignASCII(buf);
+ } else {
+ /* invalid IP address */
+ }
+ if (!name.IsEmpty()) {
+ if (!allNames.IsEmpty()) {
+ multipleNames = PR_TRUE;
+ allNames.Append(NS_LITERAL_STRING(" , "));
+ }
+ allNames.Append(name);
+ }
+ break;
+ }
+
+ default: // all other types of names are ignored
+ break;
+ }
+ current = CERT_GetNextGeneralName(current);
+ } while (current != sanNameList); // double linked
+ }
+ if (san_arena)
+ PORT_FreeArena(san_arena, PR_FALSE);
+
+ if (!useSAN) {
+ char *certName = nsnull;
+ // certName = CERT_FindNSStringExtension(nssCert, SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME);
+ if (!certName) {
+ certName = CERT_GetCommonName(&nssCert->subject);
+ }
+ allNames.AssignASCII(certName);
+ PORT_Free(certName);
+ }
+
+ if (multipleNames) {
+ nsString message;
+ rv = component->GetPIPNSSBundleString("certErrorMismatchMultiple",
+ message);
+ if (NS_SUCCEEDED(rv)) {
+ returnedMessage.Append(message);
+ returnedMessage.Append(NS_LITERAL_STRING("\n "));
+ returnedMessage.Append(allNames);
+ returnedMessage.Append(NS_LITERAL_STRING(" \n"));
+ }
+ }
+ else { // !multipleNames
+ params[0] = allNames.get();
+
+ nsString formattedString;
+ rv = component->PIPBundleFormatStringFromName("certErrorMismatchSingle",
+ params, 1,
+ formattedString);
+ if (NS_SUCCEEDED(rv)) {
+ returnedMessage.Append(formattedString);
+ returnedMessage.Append(NS_LITERAL_STRING("\n"));
+ }
}
}
@@ -745,9 +917,22 @@ getInvalidCertErrorMessage(PRUint32 multipleCollectedErrors,
ToLowerCase(error_id);
NS_ConvertASCIItoUTF16 idU(error_id);
- returnedMessage.Append(NS_LITERAL_STRING(" ("));
- returnedMessage.Append(idU);
- returnedMessage.Append(NS_LITERAL_STRING(")"));
+ params[0] = idU.get();
+
+ nsString formattedString;
+ rv = component->PIPBundleFormatStringFromName("certErrorCodePrefix",
+ params, 1,
+ formattedString);
+ if (NS_SUCCEEDED(rv)) {
+ returnedMessage.Append(NS_LITERAL_STRING("\n"));
+ returnedMessage.Append(formattedString);
+ returnedMessage.Append(NS_LITERAL_STRING("\n"));
+ }
+ else {
+ returnedMessage.Append(NS_LITERAL_STRING(" ("));
+ returnedMessage.Append(idU);
+ returnedMessage.Append(NS_LITERAL_STRING(")"));
+ }
}
return NS_OK;
@@ -803,12 +988,15 @@ nsHandleSSLError(nsNSSSocketInfo *socketInfo, PRInt32 err)
socketInfo->GetHostName(getter_Copies(hostName));
NS_ConvertASCIItoUTF16 hostNameU(hostName);
- nsString formattedString;
- rv = getErrorMessage(err, hostNameU, nssComponent, formattedString);
+ PRInt32 port;
+ socketInfo->GetPort(&port);
PRBool external = PR_FALSE;
socketInfo->GetExternalErrorReporting(&external);
+ nsString formattedString;
+ rv = getErrorMessage(err, hostNameU, port, external, nssComponent, formattedString);
+
if (external)
{
socketInfo->SetErrorMessage(formattedString.get());
@@ -830,8 +1018,12 @@ static nsresult
nsHandleInvalidCertError(nsNSSSocketInfo *socketInfo,
PRUint32 multipleCollectedErrors,
const nsACString &host,
- const nsACString &hostWithPort,
- PRInt32 err,
+ const nsACString &hostWithPort,
+ PRInt32 port,
+ PRErrorCode errorCodeToReport,
+ PRErrorCode errTrust,
+ PRErrorCode errMismatch,
+ PRErrorCode errExpired,
nsIX509Cert* ix509)
{
nsresult rv;
@@ -843,10 +1035,6 @@ nsHandleInvalidCertError(nsNSSSocketInfo *socketInfo,
NS_ConvertASCIItoUTF16 hostU(host);
NS_ConvertASCIItoUTF16 hostWithPortU(hostWithPort);
- nsString formattedString;
- rv = getInvalidCertErrorMessage(multipleCollectedErrors, err, hostU, hostWithPortU,
- ix509, nssComponent, formattedString);
-
// What mechanism is used to inform the user?
// The highest priority has the "external error reporting" feature,
// if set, we'll provide the strings to be used by the nsINSSErrorsService
@@ -854,6 +1042,12 @@ nsHandleInvalidCertError(nsNSSSocketInfo *socketInfo,
PRBool external = PR_FALSE;
socketInfo->GetExternalErrorReporting(&external);
+ nsString formattedString;
+ rv = getInvalidCertErrorMessage(multipleCollectedErrors, errorCodeToReport,
++ errTrust, errMismatch, errExpired,
+ hostU, hostWithPortU, port,
+ ix509, external, nssComponent, formattedString);
+
if (external)
{
socketInfo->SetErrorMessage(formattedString.get());
@@ -2327,11 +2521,9 @@ nsNSSBadCertHandler(void *arg, PRFileDesc *sslSocket)
PRUint32 collected_errors = 0;
PRUint32 remaining_display_errors = 0;
- // There may be multiple problems with a cert, but we can only report
- // a single error code to the caller. We'll use the first code we see.
- // However, in our error string we'll use a string that mentions
- // all of expired/not-yet-valid/domain-mismatch/untrusted.
- PRErrorCode errorCodeToReport = SECSuccess;
+ PRErrorCode errorCodeTrust = SECSuccess;
+ PRErrorCode errorCodeMismatch = SECSuccess;
+ PRErrorCode errorCodeExpired = SECSuccess;
char *hostname = SSL_RevealURL(sslSocket);
charCleaner hostnameCleaner(hostname);
@@ -2350,7 +2542,7 @@ nsNSSBadCertHandler(void *arg, PRFileDesc *sslSocket)
if (hostname && hostname[0] &&
CERT_VerifyCertName(peerCert, hostname) != SECSuccess) {
collected_errors |= nsICertOverrideService::ERROR_MISMATCH;
- errorCodeToReport = SSL_ERROR_BAD_CERT_DOMAIN;
+ errorCodeMismatch = SSL_ERROR_BAD_CERT_DOMAIN;
}
{
@@ -2382,10 +2574,6 @@ nsNSSBadCertHandler(void *arg, PRFileDesc *sslSocket)
CERTVerifyLogNode *i_node;
for (i_node = verify_log->head; i_node; i_node = i_node->next)
{
- if (errorCodeToReport == SECSuccess) {
- errorCodeToReport = i_node->error;
- }
-
switch (i_node->error)
{
case SEC_ERROR_UNKNOWN_ISSUER:
@@ -2395,12 +2583,21 @@ nsNSSBadCertHandler(void *arg, PRFileDesc *sslSocket)
case SEC_ERROR_UNTRUSTED_CERT:
// We group all these errors as "cert not trusted"
collected_errors |= nsICertOverrideService::ERROR_UNTRUSTED;
+ if (errorCodeTrust == SECSuccess) {
+ errorCodeTrust = i_node->error;
+ }
break;
case SSL_ERROR_BAD_CERT_DOMAIN:
collected_errors |= nsICertOverrideService::ERROR_MISMATCH;
+ if (errorCodeMismatch == SECSuccess) {
+ errorCodeMismatch = i_node->error;
+ }
break;
case SEC_ERROR_EXPIRED_CERTIFICATE:
collected_errors |= nsICertOverrideService::ERROR_TIME;
+ if (errorCodeExpired == SECSuccess) {
+ errorCodeExpired = i_node->error;
+ }
break;
default:
// we are not willing to continue on any other error
@@ -2496,13 +2693,26 @@ nsNSSBadCertHandler(void *arg, PRFileDesc *sslSocket)
recentBadCertsService->AddBadCert(hostWithPortStringUTF16, status);
}
+ // pick the error code to report by priority
+ PRErrorCode errorCodeToReport = SECSuccess;
+ if (remaining_display_errors & nsICertOverrideService::ERROR_UNTRUSTED)
+ errorCodeToReport = errorCodeTrust;
+ else if (remaining_display_errors & nsICertOverrideService::ERROR_MISMATCH)
+ errorCodeToReport = errorCodeMismatch;
+ else if (remaining_display_errors & nsICertOverrideService::ERROR_TIME)
+ errorCodeToReport = errorCodeExpired;
+
PR_SetError(errorCodeToReport, 0);
if (!suppressMessage) {
nsHandleInvalidCertError(infoObject,
remaining_display_errors,
hostString,
- hostWithPortString,
- errorCodeToReport,
+ hostWithPortString,
+ port,
+ errorCodeToReport,
+ errorCodeTrust,
+ errorCodeMismatch,
+ errorCodeExpired,
ix509);
}
diff --git a/mozilla/toolkit/themes/pinstripe/global/netError.css b/mozilla/toolkit/themes/pinstripe/global/netError.css
index 7c0e8ffc84e..7fe69b171ee 100644
--- a/mozilla/toolkit/themes/pinstripe/global/netError.css
+++ b/mozilla/toolkit/themes/pinstripe/global/netError.css
@@ -68,6 +68,7 @@ body[dir="rtl"] #errorPageContainer {
border-bottom: 1px solid ThreeDLightShadow;
padding-bottom: 1em;
font-size: 130%;
+ white-space: -moz-pre-wrap;
}
#errorLongDesc {
diff --git a/mozilla/toolkit/themes/winstripe/global/netError.css b/mozilla/toolkit/themes/winstripe/global/netError.css
index b5347e93e25..6122233c1df 100644
--- a/mozilla/toolkit/themes/winstripe/global/netError.css
+++ b/mozilla/toolkit/themes/winstripe/global/netError.css
@@ -68,6 +68,7 @@ body[dir="rtl"] #errorPageContainer {
border-bottom: 1px solid ThreeDLightShadow;
padding-bottom: 1em;
font-size: 130%;
+ white-space: -moz-pre-wrap;
}
#errorLongDesc {