Bug 686248: Add isExtendedValidation to nsISSLStatus so it can be used by mobile, r=meyhemer

--HG--
extra : rebase_source : 6d21f2fdc3cb587874662cc23f84503e63b95ed1
This commit is contained in:
Brian Smith 2011-10-30 11:43:06 -07:00
parent f0fba63b8a
commit c70f428cda
13 changed files with 81 additions and 176 deletions

View File

@ -52,7 +52,6 @@
#include "nsIDOMEventTarget.h"
#include "nsIWindowWatcher.h"
#include "nsIDOMWindow.h"
#include "nsIIdentityInfo.h"
#include "nsPIDOMWindow.h"
#include "TabChild.h"
#include "nsIDOMEvent.h"

View File

@ -238,11 +238,9 @@
let SSLStatus = json.SSLStatusAsString ? serhelper.deserializeObject(json.SSLStatusAsString) : null;
if (SSLStatus) {
SSLStatus.QueryInterface(Components.interfaces.nsISSLStatus);
if (SSLStatus) {
// We must check the Extended Validation (EV) state here, on the chrome
// process, because NSS is needed for that determination.
let ii = SSLStatus.serverCert.QueryInterface(Components.interfaces.nsIIdentityInfo);
if (ii && ii.isExtendedValidation)
// We must check the Extended Validation (EV) state here, on the chrome
// process, because NSS is needed for that determination.
if (SSLStatus && SSLStatus.isExtendedValidation) {
json.state |= Components.interfaces.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL;
}
}

View File

@ -38,7 +38,9 @@
#include "nsISupports.idl"
[scriptable, uuid(8de811f0-1dd2-11b2-8bf1-e9aa324984b2)]
interface nsISSLStatus;
[scriptable, uuid(179b1ab1-0950-4427-9556-6f496dc4a27f)]
interface nsISSLStatusProvider : nsISupports {
readonly attribute nsISupports SSLStatus;
readonly attribute nsISSLStatus SSLStatus;
};

View File

@ -71,7 +71,7 @@
#include "nsIWyciwygChannel.h"
#include "nsIFTPChannel.h"
#include "nsITransportSecurityInfo.h"
#include "nsIIdentityInfo.h"
#include "nsISSLStatus.h"
#include "nsIURI.h"
#include "nsISecurityEventSink.h"
#include "nsIPrompt.h"
@ -519,7 +519,7 @@ nsSecureBrowserUIImpl::EvaluateAndUpdateSecurityState(nsIRequest* aRequest, nsIS
bool temp_NewToplevelIsEV = false;
bool updateStatus = false;
nsCOMPtr<nsISupports> temp_SSLStatus;
nsCOMPtr<nsISSLStatus> temp_SSLStatus;
bool updateTooltip = false;
nsXPIDLString temp_InfoTooltip;
@ -534,7 +534,13 @@ nsSecureBrowserUIImpl::EvaluateAndUpdateSecurityState(nsIRequest* aRequest, nsIS
if (sp) {
// Ignore result
updateStatus = true;
sp->GetSSLStatus(getter_AddRefs(temp_SSLStatus));
(void) sp->GetSSLStatus(getter_AddRefs(temp_SSLStatus));
if (temp_SSLStatus) {
bool aTemp;
if (NS_SUCCEEDED(temp_SSLStatus->GetIsExtendedValidation(&aTemp))) {
temp_NewToplevelIsEV = aTemp;
}
}
}
if (info) {
@ -543,14 +549,6 @@ nsSecureBrowserUIImpl::EvaluateAndUpdateSecurityState(nsIRequest* aRequest, nsIS
updateTooltip = true;
secInfo->GetShortSecurityDescription(getter_Copies(temp_InfoTooltip));
}
nsCOMPtr<nsIIdentityInfo> idinfo = do_QueryInterface(info);
if (idinfo) {
bool aTemp;
if (NS_SUCCEEDED(idinfo->GetIsExtendedValidation(&aTemp))) {
temp_NewToplevelIsEV = aTemp;
}
}
}
// assume temp_NewToplevelSecurityState was set in this scope!
@ -1640,7 +1638,7 @@ nsSecureBrowserUIImpl::OnSecurityChange(nsIWebProgress *aWebProgress,
// nsISSLStatusProvider methods
NS_IMETHODIMP
nsSecureBrowserUIImpl::GetSSLStatus(nsISupports** _result)
nsSecureBrowserUIImpl::GetSSLStatus(nsISSLStatus** _result)
{
NS_ENSURE_ARG_POINTER(_result);

View File

@ -63,6 +63,7 @@
#include "pldhash.h"
#include "nsINetUtil.h"
class nsISSLStatus;
class nsITransportSecurityInfo;
class nsISecurityWarningDialogs;
class nsIChannel;
@ -149,7 +150,7 @@ protected:
void ObtainEventSink(nsIChannel *channel,
nsCOMPtr<nsISecurityEventSink> &sink);
nsCOMPtr<nsISupports> mSSLStatus;
nsCOMPtr<nsISSLStatus> mSSLStatus;
nsCOMPtr<nsISupports> mCurrentToplevelSecurityInfo;
void GetBundleString(const PRUnichar* name, nsAString &outString);

View File

@ -364,11 +364,9 @@ nsStrictTransportSecurityService::ShouldIgnoreStsHeader(nsISupports* aSecurityIn
nsCOMPtr<nsISSLStatusProvider> sslprov = do_QueryInterface(aSecurityInfo);
NS_ENSURE_TRUE(sslprov, NS_ERROR_FAILURE);
nsCOMPtr<nsISupports> isupstat;
rv = sslprov->GetSSLStatus(getter_AddRefs(isupstat));
nsCOMPtr<nsISSLStatus> sslstat;
rv = sslprov->GetSSLStatus(getter_AddRefs(sslstat));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISSLStatus> sslstat = do_QueryInterface(isupstat);
NS_ENSURE_TRUE(sslstat, NS_ERROR_FAILURE);
bool trustcheck;

View File

@ -41,7 +41,7 @@
interface nsIX509Cert;
[scriptable, uuid(cfede939-def1-49be-81ed-d401b3a07d1c)]
[scriptable, uuid(3f1fcd83-c5a9-4cd1-a250-7676ca7c7e34)]
interface nsISSLStatus : nsISupports {
readonly attribute nsIX509Cert serverCert;
@ -59,4 +59,10 @@ interface nsISSLStatus : nsISupports {
* query nsIX509Cert3::isSelfSigned
*/
readonly attribute boolean isUntrusted;
/**
* True only if (and after) serverCert was successfully validated as
* Extended Validation (EV).
*/
readonly attribute boolean isExtendedValidation;
};

View File

@ -1086,55 +1086,35 @@ static SECStatus getFirstEVPolicy(CERTCertificate *cert, SECOidTag &outOidTag)
return SECFailure;
}
bool
nsNSSSocketInfo::hasCertErrors()
{
if (!mSSLStatus) {
// if the status is unknown, assume the cert is bad, better safe than sorry
return true;
}
return mSSLStatus->mHaveCertErrorBits;
}
NS_IMETHODIMP
nsNSSSocketInfo::GetIsExtendedValidation(bool* aIsEV)
nsSSLStatus::GetIsExtendedValidation(bool* aIsEV)
{
NS_ENSURE_ARG(aIsEV);
NS_ENSURE_ARG_POINTER(aIsEV);
*aIsEV = false;
if (!mCert)
return NS_OK;
nsCOMPtr<nsIX509Cert> cert = mServerCert;
nsresult rv;
nsCOMPtr<nsIIdentityInfo> idinfo = do_QueryInterface(cert, &rv);
// mServerCert should never be null when this method is called because
// nsSSLStatus objects always have mServerCert set right after they are
// constructed and before they are returned. GetIsExtendedValidation should
// only be called in the chrome process (in e10s), and mServerCert will always
// implement nsIIdentityInfo in the chrome process.
if (!idinfo) {
NS_ERROR("nsSSLStatus has null mServerCert or was called in the content "
"process");
return NS_ERROR_UNEXPECTED;
}
// Never allow bad certs for EV, regardless of overrides.
if (hasCertErrors())
if (!mHaveCertErrorBits)
return NS_OK;
nsresult rv;
nsCOMPtr<nsIIdentityInfo> idinfo = do_QueryInterface(mCert, &rv);
if (NS_FAILED(rv))
return rv;
return idinfo->GetIsExtendedValidation(aIsEV);
}
NS_IMETHODIMP
nsNSSSocketInfo::GetValidEVPolicyOid(nsACString &outDottedOid)
{
if (!mCert)
return NS_OK;
if (hasCertErrors())
return NS_OK;
nsresult rv;
nsCOMPtr<nsIIdentityInfo> idinfo = do_QueryInterface(mCert, &rv);
if (NS_FAILED(rv))
return rv;
return idinfo->GetValidEVPolicyOid(outDottedOid);
}
nsresult
nsNSSCertificate::hasValidEVOidTag(SECOidTag &resultOidTag, bool &validEV)
{

View File

@ -934,19 +934,16 @@ void PR_CALLBACK HandshakeCallback(PRFileDesc* fd, void* client_data) {
if (equals_previous) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
("HandshakeCallback using PREV cert %p\n", prevcert.get()));
infoObject->SetCert(prevcert);
status->mServerCert = prevcert;
}
else {
if (status->mServerCert) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
("HandshakeCallback KEEPING cert %p\n", status->mServerCert.get()));
infoObject->SetCert(status->mServerCert);
}
else {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
("HandshakeCallback using NEW cert %p\n", nssc.get()));
infoObject->SetCert(nssc);
status->mServerCert = nssc;
}
}

View File

@ -37,12 +37,8 @@
#include "nsNSSCertificateFakeTransport.h"
#include "nsCOMPtr.h"
#include "nsIMutableArray.h"
#include "nsNSSCertificate.h"
#include "nsIX509Cert.h"
#include "nsIX509Cert3.h"
#include "nsISMimeCert.h"
#include "nsNSSASN1Object.h"
#include "nsString.h"
#include "nsXPIDLString.h"
#include "nsISupportsPrimitives.h"
@ -56,9 +52,7 @@ extern PRLogModuleInfo* gPIPNSSLog;
/* nsNSSCertificateFakeTransport */
NS_IMPL_THREADSAFE_ISUPPORTS5(nsNSSCertificateFakeTransport, nsIX509Cert,
nsIX509Cert2,
nsIX509Cert3,
NS_IMPL_THREADSAFE_ISUPPORTS3(nsNSSCertificateFakeTransport, nsIX509Cert,
nsISerializable,
nsIClassInfo)
@ -73,27 +67,6 @@ nsNSSCertificateFakeTransport::~nsNSSCertificateFakeTransport()
SECITEM_FreeItem(mCertSerialization, true);
}
NS_IMETHODIMP
nsNSSCertificateFakeTransport::GetCertType(PRUint32 *aCertType)
{
NS_NOTREACHED("Unimplemented on content process");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsNSSCertificateFakeTransport::GetIsSelfSigned(bool *aIsSelfSigned)
{
NS_NOTREACHED("Unimplemented on content process");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsNSSCertificateFakeTransport::MarkForPermDeletion()
{
NS_NOTREACHED("Unimplemented on content process");
return NS_ERROR_NOT_IMPLEMENTED;
}
/* readonly attribute string dbKey; */
NS_IMETHODIMP
nsNSSCertificateFakeTransport::GetDbKey(char * *aDbKey)
@ -198,13 +171,6 @@ nsNSSCertificateFakeTransport::GetChain(nsIArray **_rvChain)
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsNSSCertificateFakeTransport::GetAllTokenNames(PRUint32 *aLength, PRUnichar*** aTokenNames)
{
NS_NOTREACHED("Unimplemented on content process");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsNSSCertificateFakeTransport::GetSubjectName(nsAString &_subjectName)
{
@ -254,21 +220,6 @@ nsNSSCertificateFakeTransport::GetRawDER(PRUint32 *aLength, PRUint8 **aArray)
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsNSSCertificateFakeTransport::ExportAsCMS(PRUint32 chainMode,
PRUint32 *aLength, PRUint8 **aArray)
{
NS_NOTREACHED("Unimplemented on content process");
return NS_ERROR_NOT_IMPLEMENTED;
}
CERTCertificate *
nsNSSCertificateFakeTransport::GetCert()
{
NS_NOTREACHED("Unimplemented on content process");
return nsnull;
}
NS_IMETHODIMP
nsNSSCertificateFakeTransport::GetValidity(nsIX509CertValidity **aValidity)
{
@ -293,13 +244,6 @@ nsNSSCertificateFakeTransport::GetUsagesArray(bool localOnly,
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsNSSCertificateFakeTransport::RequestUsagesArrayAsync(nsICertVerificationListener *aResultListener)
{
NS_NOTREACHED("Unimplemented on content process");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsNSSCertificateFakeTransport::GetUsagesString(bool localOnly,
PRUint32 *_verified,

View File

@ -39,15 +39,7 @@
#define _NS_NSSCERTIFICATECHILD_H_
#include "nsIX509Cert.h"
#include "nsIX509Cert2.h"
#include "nsIX509Cert3.h"
#include "nsIX509CertDB.h"
#include "nsIX509CertList.h"
#include "nsIASN1Object.h"
#include "nsISMimeCert.h"
#include "nsIIdentityInfo.h"
#include "nsNSSShutDown.h"
#include "nsISimpleEnumerator.h"
#include "nsISerializable.h"
#include "nsIClassInfo.h"
@ -57,15 +49,13 @@ class nsINSSComponent;
class nsIASN1Sequence;
/* Certificate */
class nsNSSCertificateFakeTransport : public nsIX509Cert3,
class nsNSSCertificateFakeTransport : public nsIX509Cert,
public nsISerializable,
public nsIClassInfo
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIX509CERT
NS_DECL_NSIX509CERT2
NS_DECL_NSIX509CERT3
NS_DECL_NSISERIALIZABLE
NS_DECL_NSICLASSINFO

View File

@ -249,12 +249,11 @@ void nsNSSSocketInfo::virtualDestroyNSSReference()
{
}
NS_IMPL_THREADSAFE_ISUPPORTS9(nsNSSSocketInfo,
NS_IMPL_THREADSAFE_ISUPPORTS8(nsNSSSocketInfo,
nsITransportSecurityInfo,
nsISSLSocketControl,
nsIInterfaceRequestor,
nsISSLStatusProvider,
nsIIdentityInfo,
nsIAssociatedContentSecurity,
nsISerializable,
nsIClassInfo,
@ -429,13 +428,10 @@ nsNSSSocketInfo::EnsureDocShellDependentStuffKnown()
// and all the data it has cached (like verification results).
nsCOMPtr<nsISSLStatusProvider> statprov = do_QueryInterface(secureUI);
if (statprov) {
nsCOMPtr<nsISupports> isup_stat;
statprov->GetSSLStatus(getter_AddRefs(isup_stat));
if (isup_stat) {
nsCOMPtr<nsISSLStatus> sslstat = do_QueryInterface(isup_stat);
if (sslstat) {
sslstat->GetServerCert(getter_AddRefs(mPreviousCert));
}
nsCOMPtr<nsISSLStatus> sslstat;
statprov->GetSSLStatus(getter_AddRefs(sslstat));
if (sslstat) {
sslstat->GetServerCert(getter_AddRefs(mPreviousCert));
}
}
}
@ -610,13 +606,30 @@ NS_IMETHODIMP
nsNSSSocketInfo::Write(nsIObjectOutputStream* stream) {
stream->WriteID(kNSSSocketInfoMagic);
// Store the flag if there is the certificate present
stream->WriteBoolean(!!mCert);
nsRefPtr<nsSSLStatus> status = mSSLStatus;
nsCOMPtr<nsISerializable> certSerializable;
// Write a redundant copy of the certificate for backward compatibility
// with previous versions, which also unnecessarily wrote it.
//
// As we are reading the object our self, not using ReadObject, we have
// to store it here 'manually' as well, mimicking our object stream
// implementation.
nsCOMPtr<nsISerializable> certSerializable = do_QueryInterface(mCert);
if (status) {
nsCOMPtr<nsIX509Cert> cert = status->mServerCert;
certSerializable = do_QueryInterface(cert);
if (!certSerializable) {
NS_ERROR("certificate is missing or isn't serializable");
return NS_ERROR_UNEXPECTED;
}
} else {
NS_WARNING("Serializing nsNSSSocketInfo without mSSLStatus");
}
// Store the flag if there is the certificate present
stream->WriteBoolean(certSerializable);
if (certSerializable) {
stream->WriteID(kNSSCertificateCID);
stream->WriteID(NS_GET_IID(nsISupports));
@ -635,7 +648,7 @@ nsNSSSocketInfo::Write(nsIObjectOutputStream* stream) {
stream->WriteWStringZ(mShortDesc.get());
stream->WriteWStringZ(mErrorMessage.get());
stream->WriteCompoundObject(NS_ISUPPORTS_CAST(nsISSLStatus*, mSSLStatus),
stream->WriteCompoundObject(NS_ISUPPORTS_CAST(nsISSLStatus*, status),
NS_GET_IID(nsISupports), true);
stream->Write32((PRUint32)mSubRequestsHighSecurity);
@ -701,8 +714,8 @@ nsNSSSocketInfo::Read(nsIObjectInputStream* stream) {
do_CreateInstance(kNSSCertificateCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
// This is the redundant copy of the certificate; just ignore it
serializable->Read(stream);
mCert = do_QueryInterface(serializable);
// We are done with reading the certificate, now read the version
// as we did before.
@ -711,7 +724,6 @@ nsNSSSocketInfo::Read(nsIObjectInputStream* stream) {
else {
// There seems not to be the certificate present in the stream.
version = UUID_0;
mCert = nsnull;
}
// If the version field we have just read is not masked with 0xFFFF0000
@ -730,8 +742,13 @@ nsNSSSocketInfo::Read(nsIObjectInputStream* stream) {
nsCOMPtr<nsISupports> obj;
stream->ReadObject(true, getter_AddRefs(obj));
mSSLStatus = reinterpret_cast<nsSSLStatus*>(obj.get());
if (!mSSLStatus) {
NS_WARNING("deserializing nsNSSSocketInfo without mSSLStatus");
}
if (version >= 2) {
stream->Read32((PRUint32*)&mSubRequestsHighSecurity);
stream->Read32((PRUint32*)&mSubRequestsLowSecurity);
@ -848,28 +865,11 @@ nsresult nsNSSSocketInfo::GetPreviousCert(nsIX509Cert** _result)
return NS_OK;
}
nsresult nsNSSSocketInfo::GetCert(nsIX509Cert** _result)
nsresult nsNSSSocketInfo::GetSSLStatus(nsISSLStatus** _result)
{
NS_ENSURE_ARG_POINTER(_result);
*_result = mCert;
NS_IF_ADDREF(*_result);
return NS_OK;
}
nsresult nsNSSSocketInfo::SetCert(nsIX509Cert *aCert)
{
mCert = aCert;
return NS_OK;
}
nsresult nsNSSSocketInfo::GetSSLStatus(nsISupports** _result)
{
NS_ENSURE_ARG_POINTER(_result);
*_result = NS_ISUPPORTS_CAST(nsISSLStatus*, mSSLStatus);
*_result = mSSLStatus;
NS_IF_ADDREF(*_result);
return NS_OK;

View File

@ -52,7 +52,6 @@
#include "nsISSLSocketControl.h"
#include "nsSSLStatus.h"
#include "nsISSLStatusProvider.h"
#include "nsIIdentityInfo.h"
#include "nsIAssociatedContentSecurity.h"
#include "nsXPIDLString.h"
#include "nsNSSShutDown.h"
@ -131,7 +130,6 @@ class nsNSSSocketInfo : public nsITransportSecurityInfo,
public nsISSLSocketControl,
public nsIInterfaceRequestor,
public nsISSLStatusProvider,
public nsIIdentityInfo,
public nsIAssociatedContentSecurity,
public nsISerializable,
public nsIClassInfo,
@ -148,7 +146,6 @@ public:
NS_DECL_NSISSLSOCKETCONTROL
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSISSLSTATUSPROVIDER
NS_DECL_NSIIDENTITYINFO
NS_DECL_NSIASSOCIATEDCONTENTSECURITY
NS_DECL_NSISERIALIZABLE
NS_DECL_NSICLASSINFO
@ -173,9 +170,6 @@ public:
nsresult GetPort(PRInt32 *aPort);
nsresult SetPort(PRInt32 aPort);
nsresult GetCert(nsIX509Cert** _result);
nsresult SetCert(nsIX509Cert *aCert);
nsresult GetPreviousCert(nsIX509Cert** _result);
void SetCanceled(bool aCanceled);
@ -197,7 +191,6 @@ public:
/* Set SSL Status values */
nsresult SetSSLStatus(nsSSLStatus *aSSLStatus);
nsSSLStatus* SSLStatus() { return mSSLStatus; }
bool hasCertErrors();
PRStatus CloseSocketAndDestroy();
@ -210,7 +203,6 @@ public:
protected:
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
PRFileDesc* mFd;
nsCOMPtr<nsIX509Cert> mCert;
nsCOMPtr<nsIX509Cert> mPreviousCert; // DocShellDependent
enum {
blocking_state_unknown, is_nonblocking_socket, is_blocking_socket