Bug 327181, Improve error reporting for invalid-certificate errors (error page for https, or combined dialog) Code in mozilla/security/manager: r=rrelyea Code elsewhere: r=mconnor, sr=dveditz blocking1.9=mconnor

This commit is contained in:
kaie@kuix.de 2007-10-03 04:47:26 -07:00
Родитель 137ae6249a
Коммит 7104607e1d
26 изменённых файлов: 806 добавлений и 971 удалений

Просмотреть файл

@ -1767,8 +1767,7 @@ MicrosummaryResource.prototype = {
// and abort loads for bad SSL certs and HTTP authorization requests. // and abort loads for bad SSL certs and HTTP authorization requests.
// Interfaces this component implements. // Interfaces this component implements.
interfaces: [Ci.nsIBadCertListener, interfaces: [Ci.nsIAuthPromptProvider,
Ci.nsIAuthPromptProvider,
Ci.nsIAuthPrompt, Ci.nsIAuthPrompt,
Ci.nsIPrompt, Ci.nsIPrompt,
Ci.nsIProgressEventSink, Ci.nsIProgressEventSink,
@ -1800,25 +1799,6 @@ MicrosummaryResource.prototype = {
return this.QueryInterface(iid); return this.QueryInterface(iid);
}, },
// nsIBadCertListener
// Suppress UI and abort secure loads from servers with bad SSL certificates.
confirmUnknownIssuer: function MSR_confirmUnknownIssuer(socketInfo, cert, certAddType) {
return false;
},
confirmMismatchDomain: function MSR_confirmMismatchDomain(socketInfo, targetURL, cert) {
return false;
},
confirmCertExpired: function MSR_confirmCertExpired(socketInfo, cert) {
return false;
},
notifyCrlNextupdate: function MSR_notifyCrlNextupdate(socketInfo, targetURL, cert) {
},
// Suppress UI and abort loads for files secured by authentication. // Suppress UI and abort loads for files secured by authentication.
// Auth requests appear to succeed when we cancel them (since the server // Auth requests appear to succeed when we cancel them (since the server

Просмотреть файл

@ -293,7 +293,6 @@ loadListener.prototype = {
aIID.equals(Ci.nsIStreamListener) || aIID.equals(Ci.nsIStreamListener) ||
aIID.equals(Ci.nsIChannelEventSink) || aIID.equals(Ci.nsIChannelEventSink) ||
aIID.equals(Ci.nsIInterfaceRequestor) || aIID.equals(Ci.nsIInterfaceRequestor) ||
aIID.equals(Ci.nsIBadCertListener) ||
// See FIXME comment below // See FIXME comment below
aIID.equals(Ci.nsIHttpEventSink) || aIID.equals(Ci.nsIHttpEventSink) ||
aIID.equals(Ci.nsIProgressEventSink) || aIID.equals(Ci.nsIProgressEventSink) ||
@ -349,24 +348,6 @@ loadListener.prototype = {
return this.QueryInterface(aIID); return this.QueryInterface(aIID);
}, },
// nsIBadCertListener
confirmUnknownIssuer: function SRCH_load_CUI(aSocketInfo, aCert,
aCertAddType) {
return false;
},
confirmMismatchDomain: function SRCH_load_CMD(aSocketInfo, aTargetURL,
aCert) {
return false;
},
confirmCertExpired: function SRCH_load_CCE(aSocketInfo, aCert) {
return false;
},
notifyCrlNextupdate: function SRCH_load_NCN(aSocketInfo, aTargetURL, aCert) {
},
// FIXME: bug 253127 // FIXME: bug 253127
// nsIHttpEventSink // nsIHttpEventSink
onRedirect: function (aChannel, aNewChannel) {}, onRedirect: function (aChannel, aNewChannel) {},

Просмотреть файл

@ -87,10 +87,6 @@ NS_IMPL_THREADSAFE_ADDREF(EmbedCertificates)
NS_IMPL_THREADSAFE_RELEASE(EmbedCertificates) NS_IMPL_THREADSAFE_RELEASE(EmbedCertificates)
NS_INTERFACE_MAP_BEGIN(EmbedCertificates) NS_INTERFACE_MAP_BEGIN(EmbedCertificates)
NS_INTERFACE_MAP_ENTRY(nsITokenPasswordDialogs) NS_INTERFACE_MAP_ENTRY(nsITokenPasswordDialogs)
NS_INTERFACE_MAP_ENTRY(nsIBadCertListener)
#ifdef BAD_CERT_LISTENER2
NS_INTERFACE_MAP_ENTRY(nsIBadCertListener2)
#endif
NS_INTERFACE_MAP_ENTRY(nsICertificateDialogs) NS_INTERFACE_MAP_ENTRY(nsICertificateDialogs)
NS_INTERFACE_MAP_ENTRY(nsIClientAuthDialogs) NS_INTERFACE_MAP_ENTRY(nsIClientAuthDialogs)
NS_INTERFACE_MAP_ENTRY(nsICertPickDialogs) NS_INTERFACE_MAP_ENTRY(nsICertPickDialogs)
@ -129,40 +125,6 @@ EmbedCertificates::GetPassword(nsIInterfaceRequestor *ctx,
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
EmbedCertificates::ConfirmUnknownIssuer(nsIInterfaceRequestor *socketInfo,
nsIX509Cert *cert, PRInt16 *outAddType,
PRBool *_retval)
{
*outAddType = ADD_TRUSTED_FOR_SESSION;
*_retval = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
EmbedCertificates::ConfirmMismatchDomain(nsIInterfaceRequestor *socketInfo,
const nsACString &targetURL,
nsIX509Cert *cert, PRBool *_retval)
{
*_retval = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
EmbedCertificates::ConfirmCertExpired(nsIInterfaceRequestor *socketInfo,
nsIX509Cert *cert, PRBool *_retval)
{
*_retval = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
EmbedCertificates::NotifyCrlNextupdate(nsIInterfaceRequestor *socketInfo,
const nsACString &targetURL, nsIX509Cert *cert)
{
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
EmbedCertificates::CrlImportStatusDialog(nsIInterfaceRequestor *ctx, nsICRLInfo *crl) EmbedCertificates::CrlImportStatusDialog(nsIInterfaceRequestor *ctx, nsICRLInfo *crl)
{ {
@ -278,86 +240,3 @@ EmbedCertificates::ConfirmKeyEscrow(nsIX509Cert *escrowAuthority, PRBool *_retva
return NS_OK; return NS_OK;
} }
#ifdef BAD_CERT_LISTENER2
NS_IMETHODIMP
EmbedCertificates::ConfirmBadCertificate(
nsIInterfaceRequestor *ctx,
nsIX509Cert *cert,
PRBool aSecSuccess,
PRUint32 aError,
PRBool *_retval)
{
nsresult rv;
gpointer pCert = NULL;
guint messint = 0;
nsCOMPtr<nsIDOMWindow> parent(do_GetInterface(ctx));
GtkMozEmbedCommon * common = nsnull;
GtkMozEmbed *parentWidget = GTK_MOZ_EMBED(GetGtkWidgetForDOMWindow(parent));
if (!parentWidget) {
EmbedCommon * embedcommon = EmbedCommon::GetInstance();
if (embedcommon)
common = GTK_MOZ_EMBED_COMMON(embedcommon->mCommon);
}
if (!(aError & nsIX509Cert::VERIFIED_OK)) {
pCert = (gpointer)cert;
messint = GTK_MOZ_EMBED_CERT_VERIFIED_OK;
if (aError & nsIX509Cert::NOT_VERIFIED_UNKNOWN) {
messint |= GTK_MOZ_EMBED_CERT_NOT_VERIFIED_UNKNOWN;
}
if (aError & nsIX509Cert::CERT_EXPIRED || aError & nsIX509Cert::CERT_REVOKED) {
nsCOMPtr<nsIX509CertValidity> validity;
rv = cert->GetValidity(getter_AddRefs(validity));
if (NS_SUCCEEDED(rv)) {
PRTime notBefore, notAfter, timeToUse;
PRTime now = PR_Now();
rv = validity->GetNotBefore(&notBefore);
if (NS_FAILED(rv))
return rv;
rv = validity->GetNotAfter(&notAfter);
if (NS_FAILED(rv))
return rv;
if (LL_CMP(now, >, notAfter)) {
messint |= GTK_MOZ_EMBED_CERT_EXPIRED;
timeToUse = notAfter;
} else {
messint |= GTK_MOZ_EMBED_CERT_REVOKED;
timeToUse = notBefore;
}
}
}
if (aError & nsIX509Cert::CERT_NOT_TRUSTED) {
messint |= GTK_MOZ_EMBED_CERT_UNTRUSTED;
}
if (aError & nsIX509Cert::ISSUER_UNKNOWN) {
messint |= GTK_MOZ_EMBED_CERT_ISSUER_UNKNOWN;
}
if (aError & nsIX509Cert::ISSUER_NOT_TRUSTED) {
messint |= GTK_MOZ_EMBED_CERT_ISSUER_UNTRUSTED;
}
if (aError & nsIX509Cert::INVALID_CA) {
messint |= GTK_MOZ_EMBED_CERT_INVALID_CA;
}
if (aError & nsIX509Cert::USAGE_NOT_ALLOWED) {
}
PRBool retVal = PR_FALSE;
if (common) {
g_signal_emit_by_name(common, "certificate-error", pCert, messint, &retVal);
}
if (retVal == PR_TRUE) {
*_retval = PR_FALSE;
rv = NS_ERROR_FAILURE;
} else {
rv = NS_OK;
*_retval = PR_TRUE;
}
pCert = NULL;
} else {
rv = NS_OK;
*_retval = PR_TRUE;
}
return rv;
}
#endif

Просмотреть файл

@ -44,10 +44,6 @@
#ifndef __EmbedCertificates_h #ifndef __EmbedCertificates_h
#define __EmbedCertificates_h #define __EmbedCertificates_h
#include "nsITokenPasswordDialogs.h" #include "nsITokenPasswordDialogs.h"
#include "nsIBadCertListener.h"
#ifdef BAD_CERT_LISTENER2
#include "nsIBadCertListener2.h"
#endif
#include "nsICertificateDialogs.h" #include "nsICertificateDialogs.h"
#include "nsIClientAuthDialogs.h" #include "nsIClientAuthDialogs.h"
#include "nsICertPickDialogs.h" #include "nsICertPickDialogs.h"
@ -63,10 +59,6 @@
class EmbedPrivate; class EmbedPrivate;
class EmbedCertificates class EmbedCertificates
: public nsITokenPasswordDialogs, : public nsITokenPasswordDialogs,
public nsIBadCertListener,
#ifdef BAD_CERT_LISTENER2
public nsIBadCertListener2,
#endif
public nsICertificateDialogs, public nsICertificateDialogs,
public nsIClientAuthDialogs, public nsIClientAuthDialogs,
public nsICertPickDialogs, public nsICertPickDialogs,
@ -77,10 +69,6 @@ class EmbedCertificates
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSITOKENPASSWORDDIALOGS NS_DECL_NSITOKENPASSWORDDIALOGS
NS_DECL_NSIBADCERTLISTENER
#ifdef BAD_CERT_LISTENER2
NS_DECL_NSIBADCERTLISTENER2
#endif
NS_DECL_NSICERTIFICATEDIALOGS NS_DECL_NSICERTIFICATEDIALOGS
NS_DECL_NSICLIENTAUTHDIALOGS NS_DECL_NSICLIENTAUTHDIALOGS
NS_DECL_NSICERTPICKDIALOGS NS_DECL_NSICERTPICKDIALOGS

Просмотреть файл

@ -81,7 +81,6 @@
#include "nsIDocShellTreeItem.h" #include "nsIDocShellTreeItem.h"
#include "nsDocShellCID.h" #include "nsDocShellCID.h"
#include "nsMemory.h" #include "nsMemory.h"
#include "nsIBadCertListener.h"
#include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
#include "nsIX509Cert.h" #include "nsIX509Cert.h"
@ -195,95 +194,6 @@ CompressBZ2(nsIInputStream *src, PRFileDesc *outFd)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
class nsMetricsService::BadCertListener : public nsIBadCertListener,
public nsIInterfaceRequestor
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIBADCERTLISTENER
NS_DECL_NSIINTERFACEREQUESTOR
BadCertListener() { }
private:
~BadCertListener() { }
};
// This object has to implement threadsafe addref and release, but this is
// only because the GetInterface call happens on the socket transport thread.
// The actual notifications are proxied to the main thread.
NS_IMPL_THREADSAFE_ISUPPORTS2(nsMetricsService::BadCertListener,
nsIBadCertListener, nsIInterfaceRequestor)
NS_IMETHODIMP
nsMetricsService::BadCertListener::ConfirmUnknownIssuer(
nsIInterfaceRequestor *socketInfo, nsIX509Cert *cert,
PRInt16 *certAddType, PRBool *result)
{
*result = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsMetricsService::BadCertListener::ConfirmMismatchDomain(
nsIInterfaceRequestor *socketInfo, const nsACString &targetURL,
nsIX509Cert *cert, PRBool *result)
{
*result = PR_FALSE;
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
NS_ENSURE_STATE(prefs);
nsCString certHostOverride;
prefs->GetCharPref("metrics.upload.cert-host-override",
getter_Copies(certHostOverride));
if (!certHostOverride.IsEmpty()) {
// Accept the given alternate hostname (CN) for the certificate
nsString certHost;
cert->GetCommonName(certHost);
if (certHostOverride.Equals(NS_ConvertUTF16toUTF8(certHost))) {
*result = PR_TRUE;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsMetricsService::BadCertListener::ConfirmCertExpired(
nsIInterfaceRequestor *socketInfo, nsIX509Cert *cert, PRBool *result)
{
*result = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsMetricsService::BadCertListener::NotifyCrlNextupdate(
nsIInterfaceRequestor *socketInfo,
const nsACString &targetURL, nsIX509Cert *cert)
{
return NS_OK;
}
NS_IMETHODIMP
nsMetricsService::BadCertListener::GetInterface(const nsIID &uuid,
void **result)
{
NS_ENSURE_ARG_POINTER(result);
if (uuid.Equals(NS_GET_IID(nsIBadCertListener))) {
*result = static_cast<nsIBadCertListener *>(this);
NS_ADDREF_THIS();
return NS_OK;
}
*result = nsnull;
return NS_ERROR_NO_INTERFACE;
}
//-----------------------------------------------------------------------------
nsMetricsService::nsMetricsService() nsMetricsService::nsMetricsService()
: mMD5Context(nsnull), : mMD5Context(nsnull),
mEventCount(0), mEventCount(0),
@ -1327,11 +1237,6 @@ nsMetricsService::UploadData()
NS_ENSURE_STATE(props); NS_ENSURE_STATE(props);
props->SetPropertyAsBool(NS_LITERAL_STRING("moz-metrics-request"), PR_TRUE); props->SetPropertyAsBool(NS_LITERAL_STRING("moz-metrics-request"), PR_TRUE);
nsCOMPtr<nsIInterfaceRequestor> certListener = new BadCertListener();
NS_ENSURE_TRUE(certListener, NS_ERROR_OUT_OF_MEMORY);
channel->SetNotificationCallbacks(certListener);
nsCOMPtr<nsIUploadChannel> uploadChannel = do_QueryInterface(channel); nsCOMPtr<nsIUploadChannel> uploadChannel = do_QueryInterface(channel);
NS_ENSURE_STATE(uploadChannel); NS_ENSURE_STATE(uploadChannel);

Просмотреть файл

@ -82,16 +82,8 @@
<!-- Certificate Exists in database --> <!-- Certificate Exists in database -->
<!ENTITY caCertExists.title "Certificate Exists"> <!ENTITY caCertExists.title "Certificate Exists">
<!ENTITY caCertExists.message "The Certificate already exists."> <!ENTITY caCertExists.message "The Certificate already exists.">
<!-- Strings for the MismatchDomain dialog -->
<!ENTITY domainMismatch.title "Security Error: Domain Name Mismatch">
<!ENTITY examineCert.label "View Certificate">
<!ENTITY examineCert.accesskey "V"> <!ENTITY examineCert.accesskey "V">
<!-- Strings for the Server cert expired dialog -->
<!ENTITY serverCertExpired.continue "Would you like to continue anyway?">
<!ENTITY serverCertExpired.accept.label "Continue">
<!-- Strings for the SSL client auth ask dialog --> <!-- Strings for the SSL client auth ask dialog -->
<!ENTITY clientAuthAsk.title "User Identification Request"> <!ENTITY clientAuthAsk.title "User Identification Request">
<!ENTITY clientAuthAsk.message1 "This site has requested that you identify yourself with a certificate:"> <!ENTITY clientAuthAsk.message1 "This site has requested that you identify yourself with a certificate:">

Просмотреть файл

@ -54,9 +54,9 @@ issuerNotKnown=Because you do not know the certificate authority that issued thi
issuerCertNotFound=Certificate for this certificate authority was not found issuerCertNotFound=Certificate for this certificate authority was not found
#For Deleting Certificates #For Deleting Certificates
deleteSslCertConfirm=Are you sure you want to delete these web site certificates? deleteSslCertConfirm2=Are you sure you want to delete these web site exceptions?
deleteSslCertImpact=If you delete a web site certificate, you will be asked to accept it again the next time you visit the web site. deleteSslCertImpact2=If you delete a web site exception, you restore the usual security checks for that site and require it uses a valid certificate.
deleteSslCertTitle=Delete Web Site Certificates deleteSslCertTitle2=Delete Web Site Certificate Exceptions
deleteUserCertConfirm=Are you sure you want to delete these certificates? deleteUserCertConfirm=Are you sure you want to delete these certificates?
deleteUserCertImpact=If you delete one of your own certificates, you can no longer use it to identify yourself. deleteUserCertImpact=If you delete one of your own certificates, you can no longer use it to identify yourself.
@ -79,16 +79,6 @@ chooseP12RestoreFileDialog=File Name to Restore
chooseP12BackupFileDialog=File Name to Backup chooseP12BackupFileDialog=File Name to Backup
file_browse_PKCS12_spec=PKCS12 Files file_browse_PKCS12_spec=PKCS12 Files
#Mismatch Domain Dialg
mismatchDomainMsg1=You have attempted to establish a connection with "%S". However, the security certificate presented belongs to "%S". It is possible, though unlikely, that someone may be trying to intercept your communication with this web site.
mismatchDomainMsg2=If you suspect the certificate shown does not belong to "%S", please cancel the connection and notify the site administrator.
#Server Cert expired
serverCertExpiredMsg1="%S" is a site that uses a security certificate to encrypt data during transmission, but its certificate expired on %S.
serverCertExpiredTitle=Server Certificate Expired
serverCertNotYetValedMsg1="%S" is a site that uses a security certificate to encrypt data during transmission, but its certificate will not be valid until %S.
serverCertNotYetValidTitle=Server Certificate Not Yet Valid
serverCertExpiredMsg2=You should check to make sure that your computer's time (currently set to %S) is correct.
#Preferences #Preferences
resetPreferences=Use this button to reset %S's security preferences to their factory settings. resetPreferences=Use this button to reset %S's security preferences to their factory settings.

Просмотреть файл

@ -21,6 +21,7 @@
* Contributor(s): * Contributor(s):
* Bob Lord <lord@netscape.com> * Bob Lord <lord@netscape.com>
* Ian McGreer <mcgreer@netscape.com> * Ian McGreer <mcgreer@netscape.com>
* Kai Engert <kengert@redhat.com>
* *
* Alternatively, the contents of this file may be used under the terms of * Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or * either the GNU General Public License Version 2 or later (the "GPL"), or
@ -53,7 +54,8 @@ const nsNSSCertCache = "@mozilla.org/security/nsscertcache;1";
var key; var key;
var selected_certs = []; var selected_certs = [];
var selected_cert_index = []; var selected_tree_items = [];
var selected_index = [];
var certdb; var certdb;
var caTreeView; var caTreeView;
@ -157,7 +159,61 @@ function getSelectedCerts()
if (cert) { if (cert) {
var sc = selected_certs.length; var sc = selected_certs.length;
selected_certs[sc] = cert; selected_certs[sc] = cert;
selected_cert_index[sc] = j; selected_index[sc] = j;
}
}
}
}
}
function getSelectedTreeItems()
{
var ca_tab = document.getElementById("ca_tab");
var mine_tab = document.getElementById("mine_tab");
var others_tab = document.getElementById("others_tab");
var websites_tab = document.getElementById("websites_tab");
var orphan_tab = document.getElementById("orphan_tab");
var items = null;
if (ca_tab.selected) {
items = caTreeView.selection;
} else if (mine_tab.selected) {
items = userTreeView.selection;
} else if (others_tab.selected) {
items = emailTreeView.selection;
} else if (websites_tab.selected) {
items = serverTreeView.selection;
} else if (orphan_tab.selected) {
items = orphanTreeView.selection;
}
selected_certs = [];
selected_tree_items = [];
selected_index = [];
var tree_item = null;
var nr = 0;
if (items != null) nr = items.getRangeCount();
if (nr > 0) {
for (var i=0; i<nr; i++) {
var o1 = {};
var o2 = {};
items.getRangeAt(i, o1, o2);
var min = o1.value;
var max = o2.value;
for (var j=min; j<=max; j++) {
if (ca_tab.selected) {
tree_item = caTreeView.getTreeItem(j);
} else if (mine_tab.selected) {
tree_item = userTreeView.getTreeItem(j);
} else if (others_tab.selected) {
tree_item = emailTreeView.getTreeItem(j);
} else if (websites_tab.selected) {
tree_item = serverTreeView.getTreeItem(j);
} else if (orphan_tab.selected) {
tree_item = orphanTreeView.getTreeItem(j);
}
if (tree_item) {
var sc = selected_tree_items.length;
selected_tree_items[sc] = tree_item;
selected_index[sc] = j;
} }
} }
} }
@ -222,18 +278,49 @@ function mine_enableButtons()
function websites_enableButtons() function websites_enableButtons()
{ {
var items = serverTreeView.selection; var items = serverTreeView.selection;
var toggle="false"; var count_ranges = items.getRangeCount();
if (items.getRangeCount() == 0) {
toggle="true"; var enable_delete = false;
var enable_view = false;
var enable_edit = false;
if (count_ranges > 0) {
enable_delete = true;
} }
if (count_ranges == 1) {
var o1 = {};
var o2 = {};
items.getRangeAt(0, o1, o2); // the first range
if (o1.value == o2.value) {
// only a single item is selected
try {
var ti = serverTreeView.getTreeItem(o1.value);
if (ti) {
if (ti.cert) {
enable_view = true;
}
// Trust editing is not possible for override
// entries that are bound to host:port,
// where the cert is stored for convenince only.
if (!ti.hostPort.length) {
enable_edit = true;
}
}
}
catch (e) {
}
}
}
var enableViewButton=document.getElementById('websites_viewButton'); var enableViewButton=document.getElementById('websites_viewButton');
enableViewButton.setAttribute("disabled",toggle); enableViewButton.setAttribute("disabled", !enable_view);
var enableEditButton=document.getElementById('websites_editButton'); var enableEditButton=document.getElementById('websites_editButton');
enableEditButton.setAttribute("disabled",toggle); enableEditButton.setAttribute("disabled", !enable_edit);
var enableExportButton=document.getElementById('websites_exportButton'); var enableExportButton=document.getElementById('websites_exportButton');
enableExportButton.setAttribute("disabled",toggle); enableExportButton.setAttribute("disabled", !enable_edit);
var enableDeleteButton=document.getElementById('websites_deleteButton'); var enableDeleteButton=document.getElementById('websites_deleteButton');
enableDeleteButton.setAttribute("disabled",toggle); enableDeleteButton.setAttribute("disabled", !enable_delete);
} }
function email_enableButtons() function email_enableButtons()
@ -305,15 +392,17 @@ function editCerts()
for (var t=0; t<numcerts; t++) { for (var t=0; t<numcerts; t++) {
var cert = selected_certs[t]; var cert = selected_certs[t];
var certkey = cert.dbKey; var certkey = cert.dbKey;
var ca_tab = document.getElementById("ca_tab"); if (document.getElementById("ca_tab").selected) {
var others_tab = document.getElementById("others_tab");
if (ca_tab.selected) {
window.openDialog('chrome://pippki/content/editcacert.xul', certkey, window.openDialog('chrome://pippki/content/editcacert.xul', certkey,
'chrome,centerscreen,modal'); 'chrome,centerscreen,modal');
} else if (others_tab.selected) { } else if (document.getElementById("others_tab").selected) {
window.openDialog('chrome://pippki/content/editemailcert.xul', certkey, window.openDialog('chrome://pippki/content/editemailcert.xul', certkey,
'chrome,centerscreen,modal'); 'chrome,centerscreen,modal');
} else { } else if (!document.getElementById("websites_tab").selected
|| !serverTreeView.isHostPortOverride(selected_index[t])) {
// If the web sites tab is select, trust editing is only allowed
// if the entry refers to a real cert, but not if it's
// a host:port override, where the cert is stored for convenince only.
window.openDialog('chrome://pippki/content/editsslcert.xul', certkey, window.openDialog('chrome://pippki/content/editsslcert.xul', certkey,
'chrome,centerscreen,modal'); 'chrome,centerscreen,modal');
} }
@ -356,8 +445,8 @@ function exportCerts()
function deleteCerts() function deleteCerts()
{ {
getSelectedCerts(); getSelectedTreeItems();
var numcerts = selected_certs.length; var numcerts = selected_tree_items.length;
if (!numcerts) if (!numcerts)
return; return;
@ -398,15 +487,17 @@ function deleteCerts()
params.SetInt(0,numcerts); params.SetInt(0,numcerts);
for (t=0; t<numcerts; t++) for (t=0; t<numcerts; t++)
{ {
var cert = selected_certs[t]; var tree_item = selected_tree_items[t];
params.SetString(t+1, cert.dbKey); var c = tree_item.cert;
if (!c) {
params.SetString(t+1, tree_item.hostPort);
}
else {
params.SetString(t+1, c.commonName);
}
} }
// The dialog will modify the params.
// Every param item where the corresponding cert could get deleted,
// will still contain the db key.
// Certs which could not get deleted, will have their corrensponding
// param string erased.
window.openDialog('chrome://pippki/content/deletecert.xul', "", window.openDialog('chrome://pippki/content/deletecert.xul', "",
'chrome,centerscreen,modal', params); 'chrome,centerscreen,modal', params);
@ -419,30 +510,23 @@ function deleteCerts()
selTabID = selTab.getAttribute('id'); selTabID = selTab.getAttribute('id');
if (selTabID == 'mine_tab') { if (selTabID == 'mine_tab') {
treeView = userTreeView; treeView = userTreeView;
loadParam = nsIX509Cert.USER_CERT;
} else if (selTabID == "others_tab") { } else if (selTabID == "others_tab") {
treeView = emailTreeView; treeView = emailTreeView;
loadParam = nsIX509Cert.EMAIL_CERT;
} else if (selTabID == "websites_tab") { } else if (selTabID == "websites_tab") {
treeView = serverTreeView; treeView = serverTreeView;
loadParam = nsIX509Cert.SERVER_CERT;
} else if (selTabID == "ca_tab") { } else if (selTabID == "ca_tab") {
treeView = caTreeView; treeView = caTreeView;
loadParam = nsIX509Cert.CA_CERT;
} else if (selTabID == "orphan_tab") { } else if (selTabID == "orphan_tab") {
treeView = orphanTreeView; treeView = orphanTreeView;
loadParam = nsIX509Cert.UNKNOWN_CERT;
} }
for (t=numcerts-1; t>=0; t--) for (t=numcerts-1; t>=0; t--)
{ {
var s = params.GetString(t+1); treeView.deleteEntryObject(selected_index[t]);
if (s.length) {
// This cert was deleted.
treeView.removeCert(selected_cert_index[t]);
}
} }
selected_tree_items = [];
selected_index = [];
treeView.selection.clearSelection(); treeView.selection.clearSelection();
} }
} }

Просмотреть файл

@ -42,24 +42,14 @@ const nsIPKIParamBlock = Components.interfaces.nsIPKIParamBlock;
const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock; const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock;
var certdb; var certdb;
var certs = [];
var gParams; var gParams;
function setWindowName() function setWindowName()
{ {
gParams = window.arguments[0].QueryInterface(nsIDialogParamBlock); gParams = window.arguments[0].QueryInterface(nsIDialogParamBlock);
// Get the cert from the cert database
certdb = Components.classes[nsX509CertDB].getService(nsIX509CertDB);
var typeFlag = gParams.GetString(0); var typeFlag = gParams.GetString(0);
var numberOfCerts = gParams.GetInt(0); var numberOfCerts = gParams.GetInt(0);
var dbkey;
for(var x=0; x<numberOfCerts;x++)
{
dbkey = gParams.GetString(x+1);
certs[x] = certdb.findCertByDBKey(dbkey , null);
}
var bundle = srGetStrBundle("chrome://pippki/locale/pippki.properties"); var bundle = srGetStrBundle("chrome://pippki/locale/pippki.properties");
var title; var title;
@ -74,9 +64,9 @@ function setWindowName()
} }
else if(typeFlag == "websites_tab") else if(typeFlag == "websites_tab")
{ {
title = bundle.GetStringFromName("deleteSslCertTitle"); title = bundle.GetStringFromName("deleteSslCertTitle2");
confirm = bundle.GetStringFromName("deleteSslCertConfirm"); confirm = bundle.GetStringFromName("deleteSslCertConfirm2");
impact = bundle.GetStringFromName("deleteSslCertImpact"); impact = bundle.GetStringFromName("deleteSslCertImpact2");
} }
else if(typeFlag == "ca_tab") else if(typeFlag == "ca_tab")
{ {
@ -108,12 +98,10 @@ function setWindowName()
var box=document.getElementById("certlist"); var box=document.getElementById("certlist");
var text; var text;
for(x=0;x<certs.length;x++) for(var x=0;x<numberOfCerts;x++)
{ {
if (!certs[x])
continue;
text = document.createElement("text"); text = document.createElement("text");
text.setAttribute("value",certs[x].commonName); text.setAttribute("value", gParams.GetString(x+1));
box.appendChild(text); box.appendChild(text);
} }
@ -122,32 +110,12 @@ function setWindowName()
function doOK() function doOK()
{ {
// On returning our param list will contain keys of those certs that were deleted.
// It will contain empty strings for those certs that are still alive.
for(var i=0;i<certs.length;i++)
{
if (certs[i]) {
try {
certdb.deleteCertificate(certs[i]);
}
catch (e) {
gParams.SetString(i+1, "");
}
certs[i] = null;
}
}
gParams.SetInt(1, 1); // means OK gParams.SetInt(1, 1); // means OK
return true; return true;
} }
function doCancel() function doCancel()
{ {
var numberOfCerts = gParams.GetInt(0);
for(var x=0; x<numberOfCerts;x++)
{
gParams.SetString(x+1, "");
}
gParams.SetInt(1, 0); // means CANCEL gParams.SetInt(1, 0); // means CANCEL
return true; return true;
} }

Просмотреть файл

@ -1,91 +0,0 @@
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is mozilla.org Code.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 2001
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
- Javier Delgadillo <javi@netscape.com>
- Bob Lord <lord@netscape.com>
- Håkan Waara <hwaara@chello.se>
-
- Alternatively, the contents of this file may be used under the terms of
- either the GNU General Public License Version 2 or later (the "GPL"), or
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- in which case the provisions of the GPL or the LGPL are applicable instead
- of those above. If you wish to allow use of your version of this file only
- under the terms of either the GPL or the LGPL, and not to allow others to
- use your version of this file under the terms of the MPL, indicate your
- decision by deleting the provisions above and replace them with the notice
- and other provisions required by the GPL or the LGPL. If you do not delete
- the provisions above, a recipient may use your version of this file under
- the terms of any one of the MPL, the GPL or the LGPL.
-
- ***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<!DOCTYPE dialog [
<!ENTITY % newserverDTD SYSTEM "chrome://pippki/locale/newserver.dtd" >
%newserverDTD;
<!ENTITY % pippkiDTD SYSTEM "chrome://pippki/locale/pippki.dtd" >
%pippkiDTD;
]>
<dialog id="newServerDialog" title="&newserver.title;"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
style="width: 47em;"
onload="onLoad();"
buttons="accept,cancel,extra2"
defaultButton="cancel"
buttonlabelextra2="&newserver.examine;"
ondialogaccept="return doOK();"
ondialogcancel="return doCancel();"
ondialogextra2="viewCert();">
<script type="application/x-javascript" src="chrome://global/content/strres.js"/>
<script type="application/x-javascript" src="chrome://pippki/content/pippki.js"/>
<script type="application/x-javascript" src="chrome://pippki/content/newserver.js"/>
<stringbundle id="newserver_bundle" src="chrome://pippki/locale/newserver.properties"/>
<hbox valign="top" align="center">
<image class="alert-icon" style="margin: 5px"/>
<vbox flex="1" valign="middle">
<description id="intro"/>
<separator class="thin"/>
<description>&newserver.reasons;</description>
<description>&newserver.reason1x;</description>
<description>&newserver.reason2;</description>
<description id="reason3"/>
<separator class="thin"/>
<description>&newserver.notify;</description>
<separator/>
<description id="question"/>
<separator class="thin"/>
<radiogroup id="whatnow">
<radio label="&newserver.remember;" id="remember" value="0"/>
<radio label="&newserver.session;" id="session"
value="1" selected="true"/>
</radiogroup>
</vbox>
</hbox>
</dialog>

Просмотреть файл

@ -1,92 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Javier Delgadillo <javi@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock;
const nsIPKIParamBlock = Components.interfaces.nsIPKIParamBlock;
const nsIX509Cert = Components.interfaces.nsIX509Cert;
var dialogParams;
var pkiParams;
var cert=null;
function onLoad()
{
pkiParams = window.arguments[0].QueryInterface(nsIPKIParamBlock);
dialogParams = pkiParams.QueryInterface(nsIDialogParamBlock);
document.title = dialogParams.GetString(2);
var bundle = srGetStrBundle("chrome://pippki/locale/pippki.properties");
var message1 = dialogParams.GetString(1);
const nsIScriptableDateFormat = Components.interfaces.nsIScriptableDateFormat;
var dateService = Components.classes["@mozilla.org/intl/scriptabledateformat;1"].getService(nsIScriptableDateFormat);
var date = new Date();
var dateStr = dateService.FormatDateTime("", dateService.dateFormatShort, dateService.timeFormatNoSeconds,
date.getFullYear(), date.getMonth()+1, date.getDate(),
date.getHours(), date.getMinutes(), date.getSeconds());
var message2 = bundle.formatStringFromName("serverCertExpiredMsg2",
[ dateStr ],
1);
setText("message1", message1);
setText("message2", message2);
document.documentElement.getButton("accept").focus();
}
function doOK()
{
dialogParams.SetInt(1,1);
return true;
}
function doCancel()
{
dialogParams.SetInt(1,0);
return true;
}
function viewCert()
{
if (cert == null) {
var isupport = pkiParams.getISupportAtIndex(1);
cert = isupport.QueryInterface(nsIX509Cert);
}
viewCertHelper(window, cert);
}

Просмотреть файл

@ -41,7 +41,6 @@
#define __NS_NSSDIALOGS_H__ #define __NS_NSSDIALOGS_H__
#include "nsITokenPasswordDialogs.h" #include "nsITokenPasswordDialogs.h"
#include "nsIBadCertListener.h"
#include "nsICertificateDialogs.h" #include "nsICertificateDialogs.h"
#include "nsIClientAuthDialogs.h" #include "nsIClientAuthDialogs.h"
#include "nsICertPickDialogs.h" #include "nsICertPickDialogs.h"
@ -58,7 +57,6 @@
class nsNSSDialogs class nsNSSDialogs
: public nsITokenPasswordDialogs, : public nsITokenPasswordDialogs,
public nsIBadCertListener,
public nsICertificateDialogs, public nsICertificateDialogs,
public nsIClientAuthDialogs, public nsIClientAuthDialogs,
public nsICertPickDialogs, public nsICertPickDialogs,
@ -69,7 +67,6 @@ class nsNSSDialogs
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSITOKENPASSWORDDIALOGS NS_DECL_NSITOKENPASSWORDDIALOGS
NS_DECL_NSIBADCERTLISTENER
NS_DECL_NSICERTIFICATEDIALOGS NS_DECL_NSICERTIFICATEDIALOGS
NS_DECL_NSICLIENTAUTHDIALOGS NS_DECL_NSICLIENTAUTHDIALOGS
NS_DECL_NSICERTPICKDIALOGS NS_DECL_NSICERTPICKDIALOGS

Просмотреть файл

@ -61,13 +61,6 @@ static const nsModuleComponentInfo components[] =
nsNSSDialogsConstructor nsNSSDialogsConstructor
}, },
{
NSS_DIALOGS_DESCRIPTION,
NS_NSSDIALOGS_CID,
NS_BADCERTLISTENER_CONTRACTID,
nsNSSDialogsConstructor
},
{ {
NSS_DIALOGS_DESCRIPTION, NSS_DIALOGS_DESCRIPTION,
NS_NSSDIALOGS_CID, NS_NSSDIALOGS_CID,

Просмотреть файл

@ -51,7 +51,7 @@ GRE_MODULE = 1
SDK_XPIDLSRCS = \ SDK_XPIDLSRCS = \
nsIASN1Object.idl \ nsIASN1Object.idl \
nsIASN1Sequence.idl \ nsIASN1Sequence.idl \
nsIBadCertListener.idl \ nsIBadCertListener2.idl \
nsICertificateDialogs.idl \ nsICertificateDialogs.idl \
nsICRLInfo.idl \ nsICRLInfo.idl \
nsIX509Cert.idl \ nsIX509Cert.idl \
@ -61,6 +61,7 @@ SDK_XPIDLSRCS = \
$(NULL) $(NULL)
XPIDLSRCS = \ XPIDLSRCS = \
nsICertOverrideService.idl \
nsIFormSigningDialog.idl \ nsIFormSigningDialog.idl \
nsIX509Cert2.idl \ nsIX509Cert2.idl \
nsIX509Cert3.idl \ nsIX509Cert3.idl \

Просмотреть файл

@ -1,155 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Javier Delgadillo <javi@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface nsIX509Cert;
interface nsIInterfaceRequestor;
/**
* Functions that display warnings for problems with web site trust.
*
* @status FROZEN
*/
[scriptable, uuid(86960956-edb0-11d4-998b-00b0d02354a0)]
interface nsIBadCertListener : nsISupports {
/**
* No decision was made by the user, whether to trust a cert.
*/
const short UNINIT_ADD_FLAG = -1;
/**
* The user decided to add trust to a certificate temporarily
* for the current application session only.
*/
const short ADD_TRUSTED_FOR_SESSION = 1;
/**
* The user decided to add trust to a certificate permanently.
*/
const short ADD_TRUSTED_PERMANENTLY = 2;
/**
* Inform the user there are problems with the trust of a certificate,
* and request a decision from the user.
* The UI should offer the user a way to look at the certificate in detail.
* The following is a sample UI message to be shown to the user:
*
* Unable to verify the identity of %S as a trusted site.
* Possible reasons for this error:
* - Your browser does not recognize the Certificate Authority
* that issued the site's certificate.
* - The site's certificate is incomplete due to a
* server misconfiguration.
* - You are connected to a site pretending to be %S,
* possibly to obtain your confidential information.
* Please notify the site's webmaster about this problem.
* Before accepting this certificate, you should examine this site's
* certificate carefully. Are you willing to accept this certificate
* for the purpose of identifying the Web site %S?
* o Accept this certificate permanently
* x Accept this certificate temporarily for this session
* o Do not accept this certificate and do not connect to this Web site
*
* @param socketInfo A network communication context that can be used to obtain more information
* about the active connection.
* @param cert The certificate that is not trusted and that is having the problem.
* @param certAddType The user's trust decision. See constants defined above.
*
* @return true if the user decided to connect anyway, false if the user decided to not connect
*/
boolean confirmUnknownIssuer(in nsIInterfaceRequestor socketInfo,
in nsIX509Cert cert,
out short certAddType);
/**
* Inform the user there are problems with the trust of a certificate,
* and request a decision from the user.
* The hostname mentioned in the server's certificate is not the hostname
* that was used as a destination address for the current connection.
*
* @param socketInfo A network communication context that can be used to obtain more information
* about the active connection.
* @param targetURL The URL that was used to open the current connection.
* @param cert The certificate that was presented by the server.
*
* @return true if the user decided to connect anyway, false if the user decided to not connect
*/
boolean confirmMismatchDomain(in nsIInterfaceRequestor socketInfo,
in AUTF8String targetURL,
in nsIX509Cert cert);
/**
* Inform the user there are problems with the trust of a certificate,
* and request a decision from the user.
* The certificate presented by the server is no longer valid because
* the validity period has expired.
*
* @param socketInfo A network communication context that can be used to obtain more information
* about the active connection.
* @param cert The certificate that was presented by the server.
*
* @return true if the user decided to connect anyway, false if the user decided to not connect
*/
boolean confirmCertExpired(in nsIInterfaceRequestor socketInfo,
in nsIX509Cert cert);
/**
* Inform the user there are problems with the trust of a certificate,
* and request a decision from the user.
* The Certificate Authority (CA) that issued the server's certificate has issued a
* Certificate Revocation List (CRL).
* However, the application does not have a current version of the CA's CRL.
* Due to the application configuration, the application disallows the connection
* to the remote site.
*
* @param socketInfo A network communication context that can be used to obtain more information
* about the active connection.
* @param targetURL The URL that was used to open the current connection.
* @param cert The certificate that was presented by the server.
*/
void notifyCrlNextupdate(in nsIInterfaceRequestor socketInfo,
in AUTF8String targetURL, in nsIX509Cert cert);
};
%{C++
#define NS_BADCERTLISTENER_CONTRACTID "@mozilla.org/nsBadCertListener;1"
%}

Просмотреть файл

@ -22,6 +22,7 @@
* *
* Contributor(s): * Contributor(s):
* Ian McGreer <mcgreer@netscape.com> * Ian McGreer <mcgreer@netscape.com>
* Kai Engert <kengert@redhat.com>
* *
* Alternatively, the contents of this file may be used under the terms of * Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or * either the GNU General Public License Version 2 or later (the "GPL"), or
@ -43,15 +44,23 @@
interface nsINSSCertCache; interface nsINSSCertCache;
interface nsIX509Cert; interface nsIX509Cert;
[scriptable, uuid(4ea60761-31d6-491d-9e34-4b53a26c416c)] [scriptable, uuid(d0180863-606e-49e6-8324-cf45ed4dd891)]
interface nsICertTreeItem : nsISupports {
readonly attribute nsIX509Cert cert;
readonly attribute AString hostPort;
};
[scriptable, uuid(a8cd1c89-a901-4735-831b-7198b7b8b6b1)]
interface nsICertTree : nsITreeView { interface nsICertTree : nsITreeView {
void loadCerts(in unsigned long type); void loadCerts(in unsigned long type);
void loadCertsFromCache(in nsINSSCertCache cache, in unsigned long type); void loadCertsFromCache(in nsINSSCertCache cache, in unsigned long type);
nsIX509Cert getCert(in unsigned long index); nsIX509Cert getCert(in unsigned long index);
nsICertTreeItem getTreeItem(in unsigned long index);
boolean isHostPortOverride(in unsigned long index);
void removeCert(in unsigned long index); void deleteEntryObject(in unsigned long index);
}; };
%{C++ %{C++

Просмотреть файл

@ -41,10 +41,25 @@
interface nsIX509Cert; interface nsIX509Cert;
[scriptable, uuid(7b2ca1ca-1dd2-11b2-87ec-d217dbe22b85)] [scriptable, uuid(cfede939-def1-49be-81ed-d401b3a07d1c)]
interface nsISSLStatus : nsISupports { interface nsISSLStatus : nsISupports {
readonly attribute nsIX509Cert serverCert; readonly attribute nsIX509Cert serverCert;
readonly attribute string cipherName; readonly attribute string cipherName;
readonly attribute unsigned long keyLength; readonly attribute unsigned long keyLength;
readonly attribute unsigned long secretKeyLength; readonly attribute unsigned long secretKeyLength;
readonly attribute boolean isDomainMismatch;
readonly attribute boolean isNotValidAtThisTime;
/* Note: To distinguish between
* "unstrusted because missing or untrusted issuer"
* and
* "untrusted because self signed"
* compare for equality of
* nsIX509Cert::subjectName
* and
* nsIX509Cert::issuerName
*/
readonly attribute boolean isUntrusted;
}; };

Просмотреть файл

@ -57,6 +57,8 @@ LIBXUL_LIBRARY = 1
PACKAGE_FILE = pipnss.pkg PACKAGE_FILE = pipnss.pkg
CPPSRCS = \ CPPSRCS = \
nsNSSCleaner.cpp \
nsCertOverrideService.cpp \
nsPSMBackgroundThread.cpp \ nsPSMBackgroundThread.cpp \
nsSSLThread.cpp \ nsSSLThread.cpp \
nsCertVerificationThread.cpp \ nsCertVerificationThread.cpp \
@ -65,6 +67,7 @@ CPPSRCS = \
nsNSSComponent.cpp \ nsNSSComponent.cpp \
nsNSSErrors.cpp \ nsNSSErrors.cpp \
nsNSSIOLayer.cpp \ nsNSSIOLayer.cpp \
nsSSLStatus.cpp \
nsNSSModule.cpp \ nsNSSModule.cpp \
nsSSLSocketProvider.cpp \ nsSSLSocketProvider.cpp \
nsTLSSocketProvider.cpp \ nsTLSSocketProvider.cpp \

Просмотреть файл

@ -20,6 +20,7 @@
* *
* Contributor(s): * Contributor(s):
* Ian McGreer <mcgreer@netscape.com> * Ian McGreer <mcgreer@netscape.com>
* Kai Engert <kengert@redhat.com>
* *
* Alternatively, the contents of this file may be used under the terms of * Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or * either the GNU General Public License Version 2 or later (the "GPL"), or
@ -51,12 +52,18 @@
#include "nsArrayUtils.h" #include "nsArrayUtils.h"
#include "nsISupportsPrimitives.h" #include "nsISupportsPrimitives.h"
#include "nsXPCOMCID.h" #include "nsXPCOMCID.h"
#include "nsTHashtable.h"
#include "nsHashKeys.h"
#include "prlog.h" #include "prlog.h"
#ifdef PR_LOGGING #ifdef PR_LOGGING
extern PRLogModuleInfo* gPIPNSSLog; extern PRLogModuleInfo* gPIPNSSLog;
#endif #endif
#include "nsNSSCleaner.h"
NSSCleanupAutoPtrClass(CERTCertificate, CERT_DestroyCertificate)
static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID); static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
// treeArrayElStr // treeArrayElStr
@ -130,7 +137,48 @@ static PLDHashTableOps gMapOps = {
CompareCacheInitEntry CompareCacheInitEntry
}; };
NS_IMPL_ISUPPORTS0(nsCertAddonInfo)
NS_IMPL_ISUPPORTS1(nsCertTreeDispInfo, nsICertTreeItem)
nsCertTreeDispInfo::nsCertTreeDispInfo()
:mAddonInfo(nsnull)
,mTypeOfEntry(direct_db)
,mOverrideBits(nsCertOverride::ob_None)
{
}
nsCertTreeDispInfo::nsCertTreeDispInfo(nsCertTreeDispInfo &other)
{
mAddonInfo = other.mAddonInfo;
mTypeOfEntry = other.mTypeOfEntry;
mHostWithPort = other.mHostWithPort;
mOverrideBits = other.mOverrideBits;
}
nsCertTreeDispInfo::~nsCertTreeDispInfo()
{
}
NS_IMETHODIMP
nsCertTreeDispInfo::GetCert(nsIX509Cert **_cert)
{
NS_ENSURE_ARG(_cert);
if (mAddonInfo) {
*_cert = mAddonInfo->mCert.get();
NS_IF_ADDREF(*_cert);
}
else {
*_cert = nsnull;
}
return NS_OK;
}
NS_IMETHODIMP
nsCertTreeDispInfo::GetHostPort(nsAString &aHostPort)
{
aHostPort = mHostWithPort;
return NS_OK;
}
NS_IMPL_ISUPPORTS2(nsCertTree, nsICertTree, nsITreeView) NS_IMPL_ISUPPORTS2(nsCertTree, nsICertTree, nsITreeView)
@ -138,6 +186,7 @@ nsCertTree::nsCertTree() : mTreeArray(NULL)
{ {
mCompareCache.ops = nsnull; mCompareCache.ops = nsnull;
mNSSComponent = do_GetService(kNSSComponentCID); mNSSComponent = do_GetService(kNSSComponentCID);
mOverrideService = do_GetService("@mozilla.org/security/certoverride;1");
mCellText = nsnull; mCellText = nsnull;
} }
@ -169,20 +218,7 @@ nsCertTree::~nsCertTree()
void void
nsCertTree::FreeCertArray() nsCertTree::FreeCertArray()
{ {
if (mCertArray) { mDispInfo.Clear();
PRUint32 count;
nsresult rv = mCertArray->Count(&count);
if (NS_FAILED(rv))
{
NS_ASSERTION(0, "Count failed");
return;
}
PRInt32 i;
for (i = count - 1; i >= 0; i--)
{
mCertArray->RemoveElementAt(i);
}
}
} }
CompareCacheHashEntry * CompareCacheHashEntry *
@ -208,16 +244,19 @@ PRInt32
nsCertTree::CountOrganizations() nsCertTree::CountOrganizations()
{ {
PRUint32 i, certCount; PRUint32 i, certCount;
nsresult rv = mCertArray->Count(&certCount); certCount = mDispInfo.Length();
if (NS_FAILED(rv)) return -1;
if (certCount == 0) return 0; if (certCount == 0) return 0;
nsCOMPtr<nsISupports> isupport = dont_AddRef(mCertArray->ElementAt(0)); nsCOMPtr<nsIX509Cert> orgCert = nsnull;
nsCOMPtr<nsIX509Cert> orgCert = do_QueryInterface(isupport); if (mDispInfo.ElementAt(0)->mAddonInfo) {
orgCert = mDispInfo.ElementAt(0)->mAddonInfo->mCert;
}
nsCOMPtr<nsIX509Cert> nextCert = nsnull; nsCOMPtr<nsIX509Cert> nextCert = nsnull;
PRInt32 orgCount = 1; PRInt32 orgCount = 1;
for (i=1; i<certCount; i++) { for (i=1; i<certCount; i++) {
isupport = dont_AddRef(mCertArray->ElementAt(i)); nextCert = nsnull;
nextCert = do_QueryInterface(isupport); if (mDispInfo.ElementAt(i)->mAddonInfo) {
nextCert = mDispInfo.ElementAt(i)->mAddonInfo->mCert;
}
// XXX we assume issuer org is always criterion 1 // XXX we assume issuer org is always criterion 1
if (CmpBy(&mCompareCache, orgCert, nextCert, sort_IssuerOrg, sort_None, sort_None) != 0) { if (CmpBy(&mCompareCache, orgCert, nextCert, sort_IssuerOrg, sort_None, sort_None) != 0) {
orgCert = nextCert; orgCert = nextCert;
@ -255,8 +294,25 @@ nsCertTree::GetThreadDescAtIndex(PRInt32 index)
nsIX509Cert * nsIX509Cert *
nsCertTree::GetCertAtIndex(PRInt32 index, PRInt32 *outAbsoluteCertOffset) nsCertTree::GetCertAtIndex(PRInt32 index, PRInt32 *outAbsoluteCertOffset)
{ {
int i, idx = 0, cIndex = 0, nc; nsRefPtr<nsCertTreeDispInfo> certdi =
getter_AddRefs(GetDispInfoAtIndex(index, outAbsoluteCertOffset));
if (!certdi)
return nsnull;
nsIX509Cert *rawPtr = nsnull; nsIX509Cert *rawPtr = nsnull;
if (certdi->mAddonInfo) {
rawPtr = certdi->mAddonInfo->mCert;
NS_IF_ADDREF(rawPtr);
}
return rawPtr;
}
// If the row at index is a cert, return that cert. Otherwise, return null.
nsCertTreeDispInfo *
nsCertTree::GetDispInfoAtIndex(PRInt32 index,
PRInt32 *outAbsoluteCertOffset)
{
int i, idx = 0, cIndex = 0, nc;
if (index < 0) return nsnull; if (index < 0) return nsnull;
// Loop over the threads // Loop over the threads
for (i=0; i<mNumOrgs; i++) { for (i=0; i<mNumOrgs; i++) {
@ -267,11 +323,12 @@ nsCertTree::GetCertAtIndex(PRInt32 index, PRInt32 *outAbsoluteCertOffset)
PRInt32 certIndex = cIndex + index - idx; PRInt32 certIndex = cIndex + index - idx;
if (outAbsoluteCertOffset) if (outAbsoluteCertOffset)
*outAbsoluteCertOffset = certIndex; *outAbsoluteCertOffset = certIndex;
nsCOMPtr<nsISupports> isupport = nsRefPtr<nsCertTreeDispInfo> certdi = mDispInfo.ElementAt(certIndex);
dont_AddRef(mCertArray->ElementAt(certIndex)); if (certdi) {
nsCOMPtr<nsIX509Cert> cert = do_QueryInterface(isupport); nsCertTreeDispInfo *raw = certdi.get();
rawPtr = cert; NS_IF_ADDREF(raw);
NS_IF_ADDREF(rawPtr); return raw;
}
break; break;
} }
if (mTreeArray[i].open) if (mTreeArray[i].open)
@ -279,7 +336,7 @@ nsCertTree::GetCertAtIndex(PRInt32 index, PRInt32 *outAbsoluteCertOffset)
cIndex += mTreeArray[i].numChildren; cIndex += mTreeArray[i].numChildren;
if (idx > index) break; if (idx > index) break;
} }
return rawPtr; return nsnull;
} }
nsCertTree::nsCertCompareFunc nsCertTree::nsCertCompareFunc
@ -299,72 +356,313 @@ nsCertTree::GetCompareFuncFromCertType(PRUint32 aType)
} }
} }
PRBool struct nsCertAndArrayAndPositionAndCounterAndTracker
{
nsRefPtr<nsCertAddonInfo> certai;
nsTArray< nsRefPtr<nsCertTreeDispInfo> > *array;
int position;
int counter;
nsTHashtable<nsCStringHashKey> *tracker;
};
// Used to enumerate host:port overrides that match a stored
// certificate, creates and adds a display-info-object to the
// provided array. Increments insert position and entry counter.
// We remove the given key from the tracker, which is used to
// track entries that have not yet been handled.
// The created display-info references the cert, so make a note
// of that by incrementing the cert usage counter.
PR_STATIC_CALLBACK(void)
MatchingCertOverridesCallback(const nsCertOverride &aSettings,
void *aUserData)
{
nsCertAndArrayAndPositionAndCounterAndTracker *cap =
(nsCertAndArrayAndPositionAndCounterAndTracker*)aUserData;
if (!cap)
return;
nsCertTreeDispInfo *certdi = new nsCertTreeDispInfo;
if (certdi) {
if (cap->certai)
cap->certai->mUsageCount++;
certdi->mAddonInfo = cap->certai;
certdi->mTypeOfEntry = nsCertTreeDispInfo::host_port_override;
certdi->mHostWithPort = NS_ConvertUTF8toUTF16(aSettings.mHostWithPortUTF8);
certdi->mOverrideBits = aSettings.mOverrideBits;
NS_IF_ADDREF(certdi);
cap->array->InsertElementAt(cap->position, certdi);
cap->position++;
cap->counter++;
}
// this entry is now associated to a displayed cert, remove
// it from the list of remaining entries
cap->tracker->RemoveEntry(aSettings.mHostWithPortUTF8);
}
// Used to collect a list of the (unique) host:port keys
// for all stored overrides.
PR_STATIC_CALLBACK(void)
CollectAllHostPortOverridesCallback(const nsCertOverride &aSettings,
void *aUserData)
{
nsTHashtable<nsCStringHashKey> *collectorTable =
(nsTHashtable<nsCStringHashKey> *)aUserData;
if (!collectorTable)
return;
collectorTable->PutEntry(aSettings.mHostWithPortUTF8);
}
struct nsArrayAndPositionAndCounterAndTracker
{
nsTArray< nsRefPtr<nsCertTreeDispInfo> > *array;
int position;
int counter;
nsTHashtable<nsCStringHashKey> *tracker;
};
// Used when enumerating the stored host:port overrides where
// no associated certificate was found in the NSS database.
PR_STATIC_CALLBACK(void)
AddRemaningHostPortOverridesCallback(const nsCertOverride &aSettings,
void *aUserData)
{
nsArrayAndPositionAndCounterAndTracker *cap =
(nsArrayAndPositionAndCounterAndTracker*)aUserData;
if (!cap)
return;
if (!cap->tracker->GetEntry(aSettings.mHostWithPortUTF8))
return;
// This entry is not associated to any stored cert,
// so we still need to display it.
nsCertTreeDispInfo *certdi = new nsCertTreeDispInfo;
if (certdi) {
certdi->mAddonInfo = nsnull;
certdi->mTypeOfEntry = nsCertTreeDispInfo::host_port_override;
certdi->mHostWithPort = NS_ConvertUTF8toUTF16(aSettings.mHostWithPortUTF8);
certdi->mOverrideBits = aSettings.mOverrideBits;
NS_IF_ADDREF(certdi);
cap->array->InsertElementAt(cap->position, certdi);
cap->position++;
cap->counter++;
}
}
nsresult
nsCertTree::GetCertsByTypeFromCertList(CERTCertList *aCertList, nsCertTree::GetCertsByTypeFromCertList(CERTCertList *aCertList,
PRUint32 aType, PRUint32 aWantedType,
nsCertCompareFunc aCertCmpFn, nsCertCompareFunc aCertCmpFn,
void *aCertCmpFnArg, void *aCertCmpFnArg)
nsISupportsArray **_certs)
{ {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("GetCertsByTypeFromCertList")); PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("GetCertsByTypeFromCertList"));
if (!aCertList) if (!aCertList)
return PR_FALSE; return NS_ERROR_FAILURE;
nsCOMPtr<nsISupportsArray> certarray;
nsresult rv = NS_NewISupportsArray(getter_AddRefs(certarray)); nsCertOverrideService *cos =
if (NS_FAILED(rv)) return PR_FALSE; reinterpret_cast<nsCertOverrideService*>(mOverrideService.get());
if (!cos)
return NS_ERROR_FAILURE;
nsTHashtable<nsCStringHashKey> allHostPortOverrideKeys;
if (!allHostPortOverrideKeys.Init())
return NS_ERROR_OUT_OF_MEMORY;
if (aWantedType == nsIX509Cert::SERVER_CERT) {
cos->EnumerateCertOverrides(nsnull,
CollectAllHostPortOverridesCallback,
&allHostPortOverrideKeys);
}
CERTCertListNode *node; CERTCertListNode *node;
int count = 0; int count = 0;
for (node = CERT_LIST_HEAD(aCertList); for (node = CERT_LIST_HEAD(aCertList);
!CERT_LIST_END(node, aCertList); !CERT_LIST_END(node, aCertList);
node = CERT_LIST_NEXT(node)) { node = CERT_LIST_NEXT(node)) {
if (aType == nsIX509Cert2::ANY_CERT || getCertType(node->cert) == aType) {
nsCOMPtr<nsIX509Cert> pipCert = new nsNSSCertificate(node->cert); PRBool wantThisCert = (aWantedType == nsIX509Cert2::ANY_CERT);
if (pipCert) { PRBool wantThisCertIfNoOverrides = PR_FALSE;
int i; PRBool wantThisCertIfHaveOverrides = PR_FALSE;
for (i = 0; i < count; ++i) { PRBool addOverrides = PR_FALSE;
nsCOMPtr<nsIX509Cert> cert = do_QueryElementAt(certarray, i);
if ((*aCertCmpFn)(aCertCmpFnArg, pipCert, cert) < 0) { if (!wantThisCert) {
break; PRUint32 thisCertType = getCertType(node->cert);
}
// The output from getCertType is a "guess", which can be wrong.
// The guess is based on stored trust flags, but for the host:port
// overrides, we are storing certs without any trust flags associated.
// So we must check whether the cert really belongs to the
// server, email or unknown tab. We will lookup the cert in the override
// list to come to the decision. Unfortunately, the lookup in the
// override list is quite expensive. Therefore we are using this
// lengthy if/else statement to minimize
// the number of override-list-lookups.
if (aWantedType == nsIX509Cert::SERVER_CERT
&& thisCertType == nsIX509Cert::UNKNOWN_CERT) {
// This unknown cert was stored without trust
// Are there host:port based overrides stored?
// If yes, display them.
addOverrides = PR_TRUE;
}
else
if (aWantedType == nsIX509Cert::UNKNOWN_CERT
&& thisCertType == nsIX509Cert::UNKNOWN_CERT) {
// This unknown cert was stored without trust.
// If there are associated overrides, do not show as unknown.
// If there are no associated overrides, display as unknown.
wantThisCertIfNoOverrides = PR_TRUE;
}
else
if (aWantedType == nsIX509Cert::SERVER_CERT
&& thisCertType == nsIX509Cert::SERVER_CERT) {
// This server cert is explicitly marked as a web site peer,
// with or without trust, but editable, so show it
wantThisCert = PR_TRUE;
// Are there host:port based overrides stored?
// If yes, display them.
addOverrides = PR_TRUE;
}
else
if (aWantedType == nsIX509Cert::SERVER_CERT
&& thisCertType == nsIX509Cert::EMAIL_CERT) {
// This cert might have been categorized as an email cert
// because it carries an email address. But is it really one?
// Our cert categorization is uncertain when it comes to
// distinguish between email certs and web site certs.
// So, let's see if we have an override for that cert
// and if there is, conclude it's really a web site cert.
addOverrides = PR_TRUE;
}
else
if (aWantedType == nsIX509Cert::EMAIL_CERT
&& thisCertType == nsIX509Cert::EMAIL_CERT) {
// This cert might have been categorized as an email cert
// because it carries an email address. But is it really one?
// Our cert categorization is uncertain when it comes to
// distinguish between email certs and web site certs.
// So, let's see if we have an override for that cert
// and if there is, conclude it's really a web site cert.
wantThisCertIfNoOverrides = PR_TRUE;
}
else
if (thisCertType == aWantedType) {
wantThisCert = PR_TRUE;
}
}
nsCOMPtr<nsIX509Cert> pipCert = new nsNSSCertificate(node->cert);
if (!pipCert)
return NS_ERROR_OUT_OF_MEMORY;
if (wantThisCertIfNoOverrides || wantThisCertIfHaveOverrides) {
PRUint32 ocount = 0;
nsresult rv = mOverrideService->IsCertUsedForOverrides(pipCert, &ocount);
if (wantThisCertIfNoOverrides) {
if (NS_FAILED(rv) || ocount == 0) {
// no overrides for this cert
wantThisCert = PR_TRUE;
} }
certarray->InsertElementAt(pipCert, i); }
if (wantThisCertIfHaveOverrides) {
if (NS_SUCCEEDED(rv) && ocount > 0) {
// there are overrides for this cert
wantThisCert = PR_TRUE;
}
}
}
nsRefPtr<nsCertAddonInfo> certai = new nsCertAddonInfo;
if (!certai)
return NS_ERROR_OUT_OF_MEMORY;
certai->mCert = pipCert;
certai->mUsageCount = 0;
if (wantThisCert || addOverrides) {
int InsertPosition = 0;
for (; InsertPosition < count; ++InsertPosition) {
nsCOMPtr<nsIX509Cert> cert = nsnull;
nsRefPtr<nsCertTreeDispInfo> elem = mDispInfo.ElementAt(InsertPosition);
if (elem->mAddonInfo) {
cert = mDispInfo.ElementAt(InsertPosition)->mAddonInfo->mCert;
}
if ((*aCertCmpFn)(aCertCmpFnArg, pipCert, cert) < 0) {
break;
}
}
if (wantThisCert) {
nsCertTreeDispInfo *certdi = new nsCertTreeDispInfo;
if (!certdi)
return NS_ERROR_OUT_OF_MEMORY;
certdi->mAddonInfo = certai;
certai->mUsageCount++;
certdi->mTypeOfEntry = nsCertTreeDispInfo::direct_db;
// not necessary: certdi->mHostWithPort.Clear();
certdi->mOverrideBits = nsCertOverride::ob_None;
NS_IF_ADDREF(certdi);
mDispInfo.InsertElementAt(InsertPosition, certdi);
++count; ++count;
++InsertPosition;
}
if (addOverrides && cos) {
nsCertAndArrayAndPositionAndCounterAndTracker cap;
cap.certai = certai;
cap.array = &mDispInfo;
cap.position = InsertPosition;
cap.counter = 0;
cap.tracker = &allHostPortOverrideKeys;
cos->EnumerateCertOverrides(pipCert, MatchingCertOverridesCallback, &cap);
count += cap.counter;
} }
} }
} }
*_certs = certarray;
NS_ADDREF(*_certs); if (aWantedType == nsIX509Cert::SERVER_CERT) {
return PR_TRUE; nsArrayAndPositionAndCounterAndTracker cap;
cap.array = &mDispInfo;
cap.position = 0;
cap.counter = 0;
cap.tracker = &allHostPortOverrideKeys;
cos->EnumerateCertOverrides(nsnull, AddRemaningHostPortOverridesCallback, &cap);
}
return NS_OK;
} }
PRBool nsresult
nsCertTree::GetCertsByType(PRUint32 aType, nsCertTree::GetCertsByType(PRUint32 aType,
nsCertCompareFunc aCertCmpFn, nsCertCompareFunc aCertCmpFn,
void *aCertCmpFnArg, void *aCertCmpFnArg)
nsISupportsArray **_certs)
{ {
nsNSSShutDownPreventionLock locker; nsNSSShutDownPreventionLock locker;
CERTCertList *certList = NULL; CERTCertList *certList = NULL;
nsCOMPtr<nsIInterfaceRequestor> cxt = new PipUIContext(); nsCOMPtr<nsIInterfaceRequestor> cxt = new PipUIContext();
certList = PK11_ListCerts(PK11CertListUnique, cxt); certList = PK11_ListCerts(PK11CertListUnique, cxt);
PRBool rv = GetCertsByTypeFromCertList(certList, aType, aCertCmpFn, aCertCmpFnArg, _certs); nsresult rv = GetCertsByTypeFromCertList(certList, aType, aCertCmpFn, aCertCmpFnArg);
if (certList) if (certList)
CERT_DestroyCertList(certList); CERT_DestroyCertList(certList);
return rv; return rv;
} }
PRBool nsresult
nsCertTree::GetCertsByTypeFromCache(nsINSSCertCache *aCache, nsCertTree::GetCertsByTypeFromCache(nsINSSCertCache *aCache,
PRUint32 aType, PRUint32 aType,
nsCertCompareFunc aCertCmpFn, nsCertCompareFunc aCertCmpFn,
void *aCertCmpFnArg, void *aCertCmpFnArg)
nsISupportsArray **_certs)
{ {
NS_ENSURE_ARG_POINTER(aCache); NS_ENSURE_ARG_POINTER(aCache);
CERTCertList *certList = reinterpret_cast<CERTCertList*>(aCache->GetCachedCerts()); CERTCertList *certList = reinterpret_cast<CERTCertList*>(aCache->GetCachedCerts());
if (!certList) if (!certList)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
return GetCertsByTypeFromCertList(certList, aType, aCertCmpFn, aCertCmpFnArg, _certs); return GetCertsByTypeFromCertList(certList, aType, aCertCmpFn, aCertCmpFnArg);
} }
// LoadCerts // LoadCerts
@ -384,8 +682,7 @@ nsCertTree::LoadCertsFromCache(nsINSSCertCache *aCache, PRUint32 aType)
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
rv = GetCertsByTypeFromCache(aCache, aType, rv = GetCertsByTypeFromCache(aCache, aType,
GetCompareFuncFromCertType(aType), &mCompareCache, GetCompareFuncFromCertType(aType), &mCompareCache);
getter_AddRefs(mCertArray));
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
return UpdateUIContents(); return UpdateUIContents();
} }
@ -403,8 +700,7 @@ nsCertTree::LoadCerts(PRUint32 aType)
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
rv = GetCertsByType(aType, rv = GetCertsByType(aType,
GetCompareFuncFromCertType(aType), &mCompareCache, GetCompareFuncFromCertType(aType), &mCompareCache);
getter_AddRefs(mCertArray));
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
return UpdateUIContents(); return UpdateUIContents();
} }
@ -412,9 +708,7 @@ nsCertTree::LoadCerts(PRUint32 aType)
nsresult nsresult
nsCertTree::UpdateUIContents() nsCertTree::UpdateUIContents()
{ {
PRUint32 count; PRUint32 count = mDispInfo.Length();
nsresult rv = mCertArray->Count(&count);
if (NS_FAILED(rv)) return rv;
mNumOrgs = CountOrganizations(); mNumOrgs = CountOrganizations();
mTreeArray = new treeArrayEl[mNumOrgs]; mTreeArray = new treeArrayEl[mNumOrgs];
if (!mTreeArray) if (!mTreeArray)
@ -422,28 +716,41 @@ nsCertTree::UpdateUIContents()
mCellText = do_CreateInstance(NS_ARRAY_CONTRACTID); mCellText = do_CreateInstance(NS_ARRAY_CONTRACTID);
if (count) {
PRUint32 j = 0; PRUint32 j = 0;
nsCOMPtr<nsISupports> isupport = dont_AddRef(mCertArray->ElementAt(j)); nsCOMPtr<nsIX509Cert> orgCert = nsnull;
nsCOMPtr<nsIX509Cert> orgCert = do_QueryInterface(isupport); if (mDispInfo.ElementAt(j)->mAddonInfo) {
orgCert = mDispInfo.ElementAt(j)->mAddonInfo->mCert;
}
for (PRInt32 i=0; i<mNumOrgs; i++) { for (PRInt32 i=0; i<mNumOrgs; i++) {
nsString &orgNameRef = mTreeArray[i].orgName; nsString &orgNameRef = mTreeArray[i].orgName;
orgCert->GetIssuerOrganization(orgNameRef); if (!orgCert) {
if (orgNameRef.IsEmpty()) mNSSComponent->GetPIPNSSBundleString("CertOrgUnknown", orgNameRef);
orgCert->GetCommonName(orgNameRef); }
else {
orgCert->GetIssuerOrganization(orgNameRef);
if (orgNameRef.IsEmpty())
orgCert->GetCommonName(orgNameRef);
}
mTreeArray[i].open = PR_TRUE; mTreeArray[i].open = PR_TRUE;
mTreeArray[i].certIndex = j; mTreeArray[i].certIndex = j;
mTreeArray[i].numChildren = 1; mTreeArray[i].numChildren = 1;
if (++j >= count) break; if (++j >= count) break;
isupport = dont_AddRef(mCertArray->ElementAt(j)); nsCOMPtr<nsIX509Cert> nextCert = nsnull;
nsCOMPtr<nsIX509Cert> nextCert = do_QueryInterface(isupport); if (mDispInfo.ElementAt(j)->mAddonInfo) {
nextCert = mDispInfo.ElementAt(j)->mAddonInfo->mCert;
}
while (0 == CmpBy(&mCompareCache, orgCert, nextCert, sort_IssuerOrg, sort_None, sort_None)) { while (0 == CmpBy(&mCompareCache, orgCert, nextCert, sort_IssuerOrg, sort_None, sort_None)) {
mTreeArray[i].numChildren++; mTreeArray[i].numChildren++;
if (++j >= count) break; if (++j >= count) break;
isupport = dont_AddRef(mCertArray->ElementAt(j)); nextCert = nsnull;
nextCert = do_QueryInterface(isupport); if (mDispInfo.ElementAt(j)->mAddonInfo) {
nextCert = mDispInfo.ElementAt(j)->mAddonInfo->mCert;
}
} }
orgCert = nextCert; orgCert = nextCert;
} }
}
if (mTree) { if (mTree) {
mTree->BeginUpdateBatch(); mTree->BeginUpdateBatch();
mTree->RowCountChanged(0, -mNumRows); mTree->RowCountChanged(0, -mNumRows);
@ -455,9 +762,15 @@ nsCertTree::UpdateUIContents()
} }
NS_IMETHODIMP NS_IMETHODIMP
nsCertTree::RemoveCert(PRUint32 index) nsCertTree::DeleteEntryObject(PRUint32 index)
{ {
if (!mCertArray || !mTreeArray || index < 0) { if (!mTreeArray || index < 0) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIX509CertDB> certdb =
do_GetService("@mozilla.org/security/x509certdb;1");
if (!certdb) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@ -471,9 +784,66 @@ nsCertTree::RemoveCert(PRUint32 index)
nc = (mTreeArray[i].open) ? mTreeArray[i].numChildren : 0; nc = (mTreeArray[i].open) ? mTreeArray[i].numChildren : 0;
if (index < idx + nc) { // cert is within range of this thread if (index < idx + nc) { // cert is within range of this thread
PRInt32 certIndex = cIndex + index - idx; PRInt32 certIndex = cIndex + index - idx;
nsCOMPtr<nsISupports> isupport = dont_AddRef(mCertArray->ElementAt(certIndex));
RemoveCacheEntry(isupport); nsRefPtr<nsCertTreeDispInfo> certdi = mDispInfo.ElementAt(certIndex);
mCertArray->RemoveElementAt(certIndex); nsCOMPtr<nsIX509Cert> cert = nsnull;
if (certdi->mAddonInfo) {
cert = certdi->mAddonInfo->mCert;
}
PRBool canRemoveEntry = PR_FALSE;
if (certdi->mTypeOfEntry == nsCertTreeDispInfo::host_port_override) {
mOverrideService->ClearValidityOverride(certdi->mHostWithPort);
if (certdi->mAddonInfo) {
certdi->mAddonInfo->mUsageCount--;
if (certdi->mAddonInfo->mUsageCount == 0) {
// The certificate stored in the database is no longer
// referenced by any other object displayed.
// That means we no longer need to keep it around
// and really can remove it.
canRemoveEntry = PR_TRUE;
}
}
}
else {
if (certdi->mAddonInfo->mUsageCount > 1) {
// user is trying to delete a perm trusted cert,
// although there are still overrides stored,
// so, we keep the cert, but remove the trust
CERTCertificate *nsscert = nsnull;
CERTCertificateCleaner nsscertCleaner(nsscert);
nsCOMPtr<nsIX509Cert2> cert2 = do_QueryInterface(cert);
if (cert2) {
nsscert = cert2->GetCert();
}
if (nsscert) {
CERTCertTrust trust;
memset((void*)&trust, 0, sizeof(trust));
SECStatus srv = CERT_DecodeTrustString(&trust, ""); // no override
if (srv == SECSuccess) {
CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), nsscert, &trust);
}
}
}
else {
canRemoveEntry = PR_TRUE;
}
}
nsCertTreeDispInfo *certdi2 = mDispInfo.ElementAt(certIndex);
mDispInfo.RemoveElementAt(certIndex);
NS_IF_RELEASE(certdi2);
certdi2 = 0;
if (canRemoveEntry) {
RemoveCacheEntry(cert);
certdb->DeleteCertificate(cert);
}
delete [] mTreeArray; delete [] mTreeArray;
mTreeArray = nsnull; mTreeArray = nsnull;
return UpdateUIContents(); return UpdateUIContents();
@ -499,11 +869,35 @@ nsCertTree::GetCert(PRUint32 aIndex, nsIX509Cert **_cert)
{ {
NS_ENSURE_ARG(_cert); NS_ENSURE_ARG(_cert);
*_cert = GetCertAtIndex(aIndex); *_cert = GetCertAtIndex(aIndex);
//nsCOMPtr<nsIX509Cert> cert = GetCertAtIndex(aIndex); return NS_OK;
//if (cert) { }
//*_cert = cert;
//NS_ADDREF(*_cert); NS_IMETHODIMP
//} nsCertTree::GetTreeItem(PRUint32 aIndex, nsICertTreeItem **_treeitem)
{
NS_ENSURE_ARG(_treeitem);
nsRefPtr<nsCertTreeDispInfo> certdi =
getter_AddRefs(GetDispInfoAtIndex(aIndex));
if (!certdi)
return NS_ERROR_FAILURE;
*_treeitem = certdi;
NS_IF_ADDREF(*_treeitem);
return NS_OK;
}
NS_IMETHODIMP
nsCertTree::IsHostPortOverride(PRUint32 aIndex, PRBool *_retval)
{
NS_ENSURE_ARG(_retval);
nsRefPtr<nsCertTreeDispInfo> certdi =
getter_AddRefs(GetDispInfoAtIndex(aIndex));
if (!certdi)
return NS_ERROR_FAILURE;
*_retval = (certdi->mTypeOfEntry == nsCertTreeDispInfo::host_port_override);
return NS_OK; return NS_OK;
} }
@ -719,7 +1113,15 @@ nsCertTree::GetCellText(PRInt32 row, nsITreeColumn* col,
} }
PRInt32 absoluteCertOffset; PRInt32 absoluteCertOffset;
nsCOMPtr<nsIX509Cert> cert = dont_AddRef(GetCertAtIndex(row, &absoluteCertOffset)); nsRefPtr<nsCertTreeDispInfo> certdi =
getter_AddRefs(GetDispInfoAtIndex(row, &absoluteCertOffset));
if (!certdi)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIX509Cert> cert = nsnull;
if (certdi->mAddonInfo) {
cert = certdi->mAddonInfo->mCert;
}
PRInt32 colIndex; PRInt32 colIndex;
col->GetIndex(&colIndex); col->GetIndex(&colIndex);
@ -736,34 +1138,38 @@ nsCertTree::GetCellText(PRInt32 row, nsITreeColumn* col,
} }
} }
if (cert == nsnull) return NS_ERROR_FAILURE;
if (NS_LITERAL_STRING("certcol").Equals(colID)) { if (NS_LITERAL_STRING("certcol").Equals(colID)) {
rv = cert->GetCommonName(_retval); if (!cert) {
if (NS_FAILED(rv) || _retval.IsEmpty()) { mNSSComponent->GetPIPNSSBundleString("CertNotStored", _retval);
// kaie: I didn't invent the idea to cut off anything before }
// the first colon. :-) else {
nsAutoString nick; rv = cert->GetCommonName(_retval);
rv = cert->GetNickname(nick); if (NS_FAILED(rv) || _retval.IsEmpty()) {
// kaie: I didn't invent the idea to cut off anything before
nsAString::const_iterator start, end, end2; // the first colon. :-)
nick.BeginReading(start); nsAutoString nick;
nick.EndReading(end); rv = cert->GetNickname(nick);
end2 = end;
nsAString::const_iterator start, end, end2;
if (FindInReadable(NS_LITERAL_STRING(":"), start, end)) { nick.BeginReading(start);
// found. end points to the first char after the colon, nick.EndReading(end);
// that's what we want. end2 = end;
_retval = Substring(end, end2);
} if (FindInReadable(NS_LITERAL_STRING(":"), start, end)) {
else { // found. end points to the first char after the colon,
_retval = nick; // that's what we want.
_retval = Substring(end, end2);
}
else {
_retval = nick;
}
} }
} }
} else if (NS_LITERAL_STRING("tokencol").Equals(colID)) { } else if (NS_LITERAL_STRING("tokencol").Equals(colID) && cert) {
rv = cert->GetTokenName(_retval); rv = cert->GetTokenName(_retval);
} else if (NS_LITERAL_STRING("emailcol").Equals(colID)) { } else if (NS_LITERAL_STRING("emailcol").Equals(colID) && cert) {
rv = cert->GetEmailAddress(_retval); rv = cert->GetEmailAddress(_retval);
} else if (NS_LITERAL_STRING("purposecol").Equals(colID) && mNSSComponent) { } else if (NS_LITERAL_STRING("purposecol").Equals(colID) && mNSSComponent && cert) {
PRUint32 verified; PRUint32 verified;
nsAutoString theUsages; nsAutoString theUsages;
@ -801,23 +1207,41 @@ nsCertTree::GetCellText(PRInt32 row, nsITreeColumn* col,
rv = mNSSComponent->GetPIPNSSBundleString("VerifyUnknown", _retval); rv = mNSSComponent->GetPIPNSSBundleString("VerifyUnknown", _retval);
break; break;
} }
} else if (NS_LITERAL_STRING("issuedcol").Equals(colID)) { } else if (NS_LITERAL_STRING("issuedcol").Equals(colID) && cert) {
nsCOMPtr<nsIX509CertValidity> validity; nsCOMPtr<nsIX509CertValidity> validity;
rv = cert->GetValidity(getter_AddRefs(validity)); rv = cert->GetValidity(getter_AddRefs(validity));
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
validity->GetNotBeforeLocalDay(_retval); validity->GetNotBeforeLocalDay(_retval);
} }
} else if (NS_LITERAL_STRING("expiredcol").Equals(colID)) { } else if (NS_LITERAL_STRING("expiredcol").Equals(colID) && cert) {
nsCOMPtr<nsIX509CertValidity> validity; nsCOMPtr<nsIX509CertValidity> validity;
rv = cert->GetValidity(getter_AddRefs(validity)); rv = cert->GetValidity(getter_AddRefs(validity));
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
validity->GetNotAfterLocalDay(_retval); validity->GetNotAfterLocalDay(_retval);
} }
} else if (NS_LITERAL_STRING("serialnumcol").Equals(colID)) { } else if (NS_LITERAL_STRING("serialnumcol").Equals(colID) && cert) {
rv = cert->GetSerialNumber(_retval); rv = cert->GetSerialNumber(_retval);
} else if (NS_LITERAL_STRING("typecol").Equals(colID)) {
} else if (NS_LITERAL_STRING("overridetypecol").Equals(colID)) {
// default to classic permanent-trust
nsCertOverride::OverrideBits ob = nsCertOverride::ob_Untrusted;
if (certdi->mTypeOfEntry == nsCertTreeDispInfo::host_port_override) {
ob = certdi->mOverrideBits;
}
nsCAutoString temp;
nsCertOverride::convertBitsToString(ob, temp);
_retval = NS_ConvertUTF8toUTF16(temp);
} else if (NS_LITERAL_STRING("sitecol").Equals(colID)) {
if (certdi->mTypeOfEntry == nsCertTreeDispInfo::host_port_override) {
_retval = certdi->mHostWithPort;
}
else {
_retval = NS_LITERAL_STRING("*");
}
} else if (NS_LITERAL_STRING("typecol").Equals(colID) && cert) {
nsCOMPtr<nsIX509Cert2> pipCert = do_QueryInterface(cert); nsCOMPtr<nsIX509Cert2> pipCert = do_QueryInterface(cert);
PRUint32 type = nsIX509Cert::UNKNOWN_CERT; PRUint32 type = nsIX509Cert::UNKNOWN_CERT;
@ -972,7 +1396,7 @@ nsCertTree::dumpMap()
nsAutoString td(el->orgName); nsAutoString td(el->orgName);
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("thread desc[%d]: %s", i, NS_LossyConvertUTF16toASCII(td).get())); PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("thread desc[%d]: %s", i, NS_LossyConvertUTF16toASCII(td).get()));
} }
nsCOMPtr<nsIX509Cert> ct = dont_AddRef(GetCertAtIndex(i)); nsCOMPtr<nsIX509Cert> ct = getter_AddRefs(GetCertAtIndex(i));
if (ct != nsnull) { if (ct != nsnull) {
PRUnichar *goo; PRUnichar *goo;
ct->GetCommonName(&goo); ct->GetCommonName(&goo);
@ -1105,11 +1529,24 @@ PRInt32
nsCertTree::CmpBy(void *cache, nsIX509Cert *a, nsIX509Cert *b, nsCertTree::CmpBy(void *cache, nsIX509Cert *a, nsIX509Cert *b,
sortCriterion c0, sortCriterion c1, sortCriterion c2) sortCriterion c0, sortCriterion c1, sortCriterion c2)
{ {
NS_ENSURE_TRUE( (cache!=0 && a!=0 && b!=0), 0 ); // This will be called when comparing items for display sorting.
// Some items might have no cert associated, so either a or b is null.
// We want all those orphans show at the top of the list,
// so we treat a null cert as "smaller" by returning -1.
// We don't try to sort within the group of no-cert entries,
// so we treat them as equal wrt sort order.
if (a == b) if (!a && !b)
return 0; return 0;
if (!a)
return -1;
if (!b)
return 1;
NS_ENSURE_TRUE( (cache!=0 && a!=0 && b!=0), 0 );
CompareCacheHashEntry *ace = getCacheEntry(cache, a); CompareCacheHashEntry *ace = getCacheEntry(cache, a);
CompareCacheHashEntry *bce = getCacheEntry(cache, b); CompareCacheHashEntry *bce = getCacheEntry(cache, b);

Просмотреть файл

@ -20,6 +20,7 @@
* *
* Contributor(s): * Contributor(s):
* Ian McGreer <mcgreer@netscape.com> * Ian McGreer <mcgreer@netscape.com>
* Kai Engert <kengert@redhat.com>
* *
* Alternatively, the contents of this file may be used under the terms of * Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or * either the GNU General Public License Version 2 or later (the "GPL"), or
@ -39,6 +40,7 @@
#define _NS_CERTTREE_H_ #define _NS_CERTTREE_H_
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "nsICertTree.h" #include "nsICertTree.h"
#include "nsITreeView.h" #include "nsITreeView.h"
@ -46,8 +48,11 @@
#include "nsITreeSelection.h" #include "nsITreeSelection.h"
#include "nsISupportsArray.h" #include "nsISupportsArray.h"
#include "nsIMutableArray.h" #include "nsIMutableArray.h"
#include "nsTArray.h"
#include "pldhash.h" #include "pldhash.h"
#include "nsIX509CertDB.h" #include "nsIX509CertDB.h"
#include "nsCertOverrideService.h"
typedef struct treeArrayElStr treeArrayEl; typedef struct treeArrayElStr treeArrayEl;
@ -66,6 +71,36 @@ struct CompareCacheHashEntryPtr : PLDHashEntryHdr {
CompareCacheHashEntry *entry; CompareCacheHashEntry *entry;
}; };
class nsCertAddonInfo : public nsISupports
{
public:
NS_DECL_ISUPPORTS
nsCertAddonInfo() : mUsageCount(0) {}
nsRefPtr<nsIX509Cert> mCert;
// how many display entries reference this?
// (and therefore depend on the underlying cert)
PRInt32 mUsageCount;
};
class nsCertTreeDispInfo : public nsICertTreeItem
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICERTTREEITEM
nsCertTreeDispInfo();
nsCertTreeDispInfo(nsCertTreeDispInfo &other);
virtual ~nsCertTreeDispInfo();
nsRefPtr<nsCertAddonInfo> mAddonInfo;
enum {
direct_db, host_port_override
} mTypeOfEntry;
nsString mHostWithPort;
nsCertOverride::OverrideBits mOverrideBits;
};
class nsCertTree : public nsICertTree class nsCertTree : public nsICertTree
{ {
@ -102,14 +137,13 @@ protected:
nsCertCompareFunc GetCompareFuncFromCertType(PRUint32 aType); nsCertCompareFunc GetCompareFuncFromCertType(PRUint32 aType);
PRInt32 CountOrganizations(); PRInt32 CountOrganizations();
PRBool GetCertsByType(PRUint32 aType, nsCertCompareFunc aCertCmpFn, nsresult GetCertsByType(PRUint32 aType, nsCertCompareFunc aCertCmpFn,
void *aCertCmpFnArg, nsISupportsArray **_certs); void *aCertCmpFnArg);
PRBool GetCertsByTypeFromCache(nsINSSCertCache *aCache, PRUint32 aType, nsresult GetCertsByTypeFromCache(nsINSSCertCache *aCache, PRUint32 aType,
nsCertCompareFunc aCertCmpFn, void *aCertCmpFnArg, nsCertCompareFunc aCertCmpFn, void *aCertCmpFnArg);
nsISupportsArray **_certs);
private: private:
nsCOMPtr<nsISupportsArray> mCertArray; nsTArray< nsRefPtr<nsCertTreeDispInfo> > mDispInfo;
nsCOMPtr<nsITreeBoxObject> mTree; nsCOMPtr<nsITreeBoxObject> mTree;
nsCOMPtr<nsITreeSelection> mSelection; nsCOMPtr<nsITreeSelection> mSelection;
treeArrayEl *mTreeArray; treeArrayEl *mTreeArray;
@ -117,18 +151,19 @@ private:
PRInt32 mNumRows; PRInt32 mNumRows;
PLDHashTable mCompareCache; PLDHashTable mCompareCache;
nsCOMPtr<nsINSSComponent> mNSSComponent; nsCOMPtr<nsINSSComponent> mNSSComponent;
nsCOMPtr<nsICertOverrideService> mOverrideService;
treeArrayEl *GetThreadDescAtIndex(PRInt32 _index); treeArrayEl *GetThreadDescAtIndex(PRInt32 _index);
nsIX509Cert *GetCertAtIndex(PRInt32 _index, PRInt32 *outAbsoluteCertOffset = nsnull); nsIX509Cert *GetCertAtIndex(PRInt32 _index, PRInt32 *outAbsoluteCertOffset = nsnull);
nsCertTreeDispInfo *GetDispInfoAtIndex(PRInt32 index,
PRInt32 *outAbsoluteCertOffset = nsnull);
void FreeCertArray(); void FreeCertArray();
nsresult UpdateUIContents(); nsresult UpdateUIContents();
PRBool GetCertsByTypeFromCertList(CERTCertList *aCertList, nsresult GetCertsByTypeFromCertList(CERTCertList *aCertList,
PRUint32 aType, PRUint32 aType,
nsCertCompareFunc aCertCmpFn, nsCertCompareFunc aCertCmpFn,
void *aCertCmpFnArg, void *aCertCmpFnArg);
nsISupportsArray **_certs);
nsCOMPtr<nsIMutableArray> mCellText; nsCOMPtr<nsIMutableArray> mCellText;

Просмотреть файл

@ -41,7 +41,8 @@
#include "nsNSSComponent.h" // for PIPNSS string bundle calls. #include "nsNSSComponent.h" // for PIPNSS string bundle calls.
#include "nsNSSCallbacks.h" #include "nsNSSCallbacks.h"
#include "nsNSSCertificate.h" #include "nsNSSCertificate.h"
#include "nsISSLStatus.h" #include "nsNSSCleaner.h"
#include "nsSSLStatus.h"
#include "nsNSSIOLayer.h" // for nsNSSSocketInfo #include "nsNSSIOLayer.h" // for nsNSSSocketInfo
#include "nsIWebProgressListener.h" #include "nsIWebProgressListener.h"
#include "nsIStringBundle.h" #include "nsIStringBundle.h"
@ -69,6 +70,7 @@
#include "ocsp.h" #include "ocsp.h"
static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID); static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
NSSCleanupAutoPtrClass(CERTCertificate, CERT_DestroyCertificate)
#ifdef PR_LOGGING #ifdef PR_LOGGING
extern PRLogModuleInfo* gPIPNSSLog; extern PRLogModuleInfo* gPIPNSSLog;
@ -621,77 +623,6 @@ void nsHTTPListener::send_done_signal()
} }
} }
/* Implementation of nsISSLStatus */
class nsSSLStatus
: public nsISSLStatus
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISSLSTATUS
nsSSLStatus();
virtual ~nsSSLStatus();
/* public for initilization in this file */
nsCOMPtr<nsIX509Cert> mServerCert;
PRUint32 mKeyLength;
PRUint32 mSecretKeyLength;
nsXPIDLCString mCipherName;
};
NS_IMETHODIMP
nsSSLStatus::GetServerCert(nsIX509Cert** _result)
{
NS_ASSERTION(_result, "non-NULL destination required");
*_result = mServerCert;
NS_IF_ADDREF(*_result);
return NS_OK;
}
NS_IMETHODIMP
nsSSLStatus::GetKeyLength(PRUint32* _result)
{
NS_ASSERTION(_result, "non-NULL destination required");
*_result = mKeyLength;
return NS_OK;
}
NS_IMETHODIMP
nsSSLStatus::GetSecretKeyLength(PRUint32* _result)
{
NS_ASSERTION(_result, "non-NULL destination required");
*_result = mSecretKeyLength;
return NS_OK;
}
NS_IMETHODIMP
nsSSLStatus::GetCipherName(char** _result)
{
NS_ASSERTION(_result, "non-NULL destination required");
*_result = PL_strdup(mCipherName.get());
return NS_OK;
}
nsSSLStatus::nsSSLStatus()
: mKeyLength(0), mSecretKeyLength(0)
{
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsSSLStatus, nsISSLStatus)
nsSSLStatus::~nsSSLStatus()
{
}
char* PR_CALLBACK char* PR_CALLBACK
PK11PasswordPrompt(PK11SlotInfo* slot, PRBool retry, void* arg) { PK11PasswordPrompt(PK11SlotInfo* slot, PRBool retry, void* arg) {
nsNSSShutDownPreventionLock locker; nsNSSShutDownPreventionLock locker;
@ -839,7 +770,12 @@ void PR_CALLBACK HandshakeCallback(PRFileDesc* fd, void* client_data) {
infoObject->SetShortSecurityDescription(shortDesc.get()); infoObject->SetShortSecurityDescription(shortDesc.get());
/* Set the SSL Status information */ /* Set the SSL Status information */
nsCOMPtr<nsSSLStatus> status = new nsSSLStatus(); nsCOMPtr<nsSSLStatus> status;
infoObject->GetSSLStatus(getter_AddRefs(status));
if (!status) {
status = new nsSSLStatus();
infoObject->SetSSLStatus(status);
}
CERTCertificate *serverCert = SSL_PeerCertificate(fd); CERTCertificate *serverCert = SSL_PeerCertificate(fd);
if (serverCert) { if (serverCert) {
@ -852,11 +788,10 @@ void PR_CALLBACK HandshakeCallback(PRFileDesc* fd, void* client_data) {
} }
} }
status->mHaveKeyLengthAndCipher = PR_TRUE;
status->mKeyLength = keyLength; status->mKeyLength = keyLength;
status->mSecretKeyLength = encryptBits; status->mSecretKeyLength = encryptBits;
status->mCipherName.Adopt(cipherName); status->mCipherName.Adopt(cipherName);
infoObject->SetSSLStatus(status);
} }
PR_FREEIF(certOrgName); PR_FREEIF(certOrgName);
@ -874,9 +809,11 @@ SECStatus PR_CALLBACK AuthCertificateCallback(void* client_data, PRFileDesc* fd,
// complete chain at any time it might need it. // complete chain at any time it might need it.
// But we keep only those CA certs in the temp db, that we didn't already know. // But we keep only those CA certs in the temp db, that we didn't already know.
if (SECSuccess == rv) { CERTCertificate *serverCert = SSL_PeerCertificate(fd);
CERTCertificate *serverCert = SSL_PeerCertificate(fd); CERTCertificateCleaner serverCertCleaner(serverCert);
if (serverCert) {
if (serverCert) {
if (SECSuccess == rv) {
CERTCertList *certList = CERT_GetCertChainFromCert(serverCert, PR_Now(), certUsageSSLCA); CERTCertList *certList = CERT_GetCertChainFromCert(serverCert, PR_Now(), certUsageSSLCA);
nsCOMPtr<nsINSSComponent> nssComponent; nsCOMPtr<nsINSSComponent> nssComponent;
@ -915,7 +852,21 @@ SECStatus PR_CALLBACK AuthCertificateCallback(void* client_data, PRFileDesc* fd,
} }
CERT_DestroyCertList(certList); CERT_DestroyCertList(certList);
CERT_DestroyCertificate(serverCert); }
else {
// The connection will be terminated, let's provide a minimal SSLStatus
// to the caller that contains at least the cert and its status.
nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*) fd->higher->secret;
nsCOMPtr<nsSSLStatus> status;
infoObject->GetSSLStatus(getter_AddRefs(status));
if (!status) {
status = new nsSSLStatus();
infoObject->SetSSLStatus(status);
}
if (status) {
status->mServerCert = new nsNSSCertificate(serverCert);
}
} }
} }

Просмотреть файл

@ -175,13 +175,6 @@ public:
void SetAllowTLSIntoleranceTimeout(PRBool aAllow); void SetAllowTLSIntoleranceTimeout(PRBool aAllow);
enum BadCertUIStatusType {
bcuis_not_shown, bcuis_active, bcuis_was_shown
};
void SetBadCertUIStatus(BadCertUIStatusType aNewStatus);
BadCertUIStatusType GetBadCertUIStatus() { return mBadCertUIStatus; }
nsresult GetExternalErrorReporting(PRBool* state); nsresult GetExternalErrorReporting(PRBool* state);
nsresult SetExternalErrorReporting(PRBool aState); nsresult SetExternalErrorReporting(PRBool aState);
@ -209,7 +202,6 @@ protected:
PRPackedBool mHasCleartextPhase; PRPackedBool mHasCleartextPhase;
PRPackedBool mHandshakeInProgress; PRPackedBool mHandshakeInProgress;
PRPackedBool mAllowTLSIntoleranceTimeout; PRPackedBool mAllowTLSIntoleranceTimeout;
BadCertUIStatusType mBadCertUIStatus;
PRIntervalTime mHandshakeStartTime; PRIntervalTime mHandshakeStartTime;
PRInt32 mPort; PRInt32 mPort;
nsXPIDLCString mHostName; nsXPIDLCString mHostName;

Просмотреть файл

@ -72,6 +72,7 @@
#include "nsStreamCipher.h" #include "nsStreamCipher.h"
#include "nsKeyModule.h" #include "nsKeyModule.h"
#include "nsDataSignatureVerifier.h" #include "nsDataSignatureVerifier.h"
#include "nsCertOverrideService.h"
// We must ensure that the nsNSSComponent has been loaded before // We must ensure that the nsNSSComponent has been loaded before
// creating any other components. // creating any other components.
@ -192,6 +193,7 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsStreamCipher)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsKeyObject) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsKeyObject)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsKeyObjectFactory) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsKeyObjectFactory)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsDataSignatureVerifier) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsDataSignatureVerifier)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(PR_FALSE, nsCertOverrideService, Init)
static NS_METHOD RegisterPSMContentListeners( static NS_METHOD RegisterPSMContentListeners(
nsIComponentManager *aCompMgr, nsIComponentManager *aCompMgr,
@ -454,6 +456,13 @@ static const nsModuleComponentInfo components[] =
NS_DATASIGNATUREVERIFIER_CID, NS_DATASIGNATUREVERIFIER_CID,
NS_DATASIGNATUREVERIFIER_CONTRACTID, NS_DATASIGNATUREVERIFIER_CONTRACTID,
nsDataSignatureVerifierConstructor nsDataSignatureVerifierConstructor
},
{
"PSM Cert Override Settings Service",
NS_CERTOVERRIDE_CID,
NS_CERTOVERRIDE_CONTRACTID,
nsCertOverrideServiceConstructor
} }
}; };

Просмотреть файл

@ -69,25 +69,6 @@ function BadCertHandler() {
} }
BadCertHandler.prototype = { BadCertHandler.prototype = {
// nsIBadCertListener
confirmUnknownIssuer: function(socketInfo, cert, certAddType) {
LOG("EM BadCertHandler: Unknown issuer");
return false;
},
confirmMismatchDomain: function(socketInfo, targetURL, cert) {
LOG("EM BadCertHandler: Mismatched domain");
return false;
},
confirmCertExpired: function(socketInfo, cert) {
LOG("EM BadCertHandler: Expired certificate");
return false;
},
notifyCrlNextupdate: function(socketInfo, targetURL, cert) {
},
// nsIChannelEventSink // nsIChannelEventSink
onChannelRedirect: function(oldChannel, newChannel, flags) { onChannelRedirect: function(oldChannel, newChannel, flags) {
// make sure the certificate of the old channel checks out before we follow // make sure the certificate of the old channel checks out before we follow

Просмотреть файл

@ -140,7 +140,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS11(nsXPInstallManager,
nsIProgressEventSink, nsIProgressEventSink,
nsIInterfaceRequestor, nsIInterfaceRequestor,
nsPICertNotification, nsPICertNotification,
nsIBadCertListener, nsIBadCertListener2,
nsIChannelEventSink, nsIChannelEventSink,
nsISupportsWeakReference) nsISupportsWeakReference)
@ -1253,7 +1253,7 @@ nsXPInstallManager::GetInterface(const nsIID & eventSinkIID, void* *_retval)
*_retval = p; *_retval = p;
return NS_OK; return NS_OK;
} }
else if (eventSinkIID.Equals(NS_GET_IID(nsIBadCertListener))) { else if (eventSinkIID.Equals(NS_GET_IID(nsIBadCertListener2))) {
// If we aren't chrome triggered fall back to the default dialogs // If we aren't chrome triggered fall back to the default dialogs
if (!mFromChrome) if (!mFromChrome)
return NS_ERROR_NO_INTERFACE; return NS_ERROR_NO_INTERFACE;
@ -1271,31 +1271,14 @@ nsXPInstallManager::OnChannelRedirect(nsIChannel *oldChannel, nsIChannel *newCha
return NS_OK; return NS_OK;
} }
// nsIBadCertListener methods // nsIBadCertListener2 methods
NS_IMETHODIMP NS_IMETHODIMP
nsXPInstallManager::ConfirmUnknownIssuer(nsIInterfaceRequestor *socketInfo, nsIX509Cert *cert, PRInt16 *certAddType, PRBool *_retval) nsXPInstallManager::NotifyCertProblem(nsIInterfaceRequestor *socketInfo,
{ nsISSLStatus *status,
*_retval = PR_FALSE; const nsACString &targetSite,
return NS_OK; PRBool *_retval)
}
NS_IMETHODIMP
nsXPInstallManager::ConfirmMismatchDomain(nsIInterfaceRequestor *socketInfo, const nsACString & targetURL, nsIX509Cert *cert, PRBool *_retval)
{
*_retval = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsXPInstallManager::ConfirmCertExpired(nsIInterfaceRequestor *socketInfo, nsIX509Cert *cert, PRBool *_retval)
{
*_retval = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsXPInstallManager::NotifyCrlNextupdate(nsIInterfaceRequestor *socketInfo, const nsACString & targetURL, nsIX509Cert *cert)
{ {
*_retval = PR_TRUE;
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -56,7 +56,7 @@
#include "nsIChromeRegistry.h" #include "nsIChromeRegistry.h"
#include "nsIDOMWindowInternal.h" #include "nsIDOMWindowInternal.h"
#include "nsIObserver.h" #include "nsIObserver.h"
#include "nsIBadCertListener.h" #include "nsIBadCertListener2.h"
#include "nsIChannelEventSink.h" #include "nsIChannelEventSink.h"
#include "nsIXPIInstallInfo.h" #include "nsIXPIInstallInfo.h"
@ -86,7 +86,7 @@ class nsXPInstallManager : public nsIXPIListener,
public nsIProgressEventSink, public nsIProgressEventSink,
public nsIInterfaceRequestor, public nsIInterfaceRequestor,
public nsPICertNotification, public nsPICertNotification,
public nsIBadCertListener, public nsIBadCertListener2,
public nsIChannelEventSink, public nsIChannelEventSink,
public nsSupportsWeakReference public nsSupportsWeakReference
{ {
@ -104,7 +104,7 @@ class nsXPInstallManager : public nsIXPIListener,
NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSIINTERFACEREQUESTOR NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSPICERTNOTIFICATION NS_DECL_NSPICERTNOTIFICATION
NS_DECL_NSIBADCERTLISTENER NS_DECL_NSIBADCERTLISTENER2
NS_DECL_NSICHANNELEVENTSINK NS_DECL_NSICHANNELEVENTSINK
NS_IMETHOD InitManager(nsIDOMWindowInternal* aParentWindow, nsXPITriggerInfo* aTrigger, PRUint32 aChromeType ); NS_IMETHOD InitManager(nsIDOMWindowInternal* aParentWindow, nsXPITriggerInfo* aTrigger, PRUint32 aChromeType );