michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsSSLStatus.h" michael@0: #include "plstr.h" michael@0: #include "nsIClassInfoImpl.h" michael@0: #include "nsIIdentityInfo.h" michael@0: #include "nsIProgrammingLanguage.h" michael@0: #include "nsIObjectOutputStream.h" michael@0: #include "nsIObjectInputStream.h" michael@0: michael@0: NS_IMETHODIMP michael@0: nsSSLStatus::GetServerCert(nsIX509Cert** _result) michael@0: { michael@0: NS_ASSERTION(_result, "non-NULL destination required"); michael@0: michael@0: *_result = mServerCert; michael@0: NS_IF_ADDREF(*_result); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsSSLStatus::GetKeyLength(uint32_t* _result) michael@0: { michael@0: NS_ASSERTION(_result, "non-NULL destination required"); michael@0: if (!mHaveKeyLengthAndCipher) michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: michael@0: *_result = mKeyLength; michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsSSLStatus::GetSecretKeyLength(uint32_t* _result) michael@0: { michael@0: NS_ASSERTION(_result, "non-NULL destination required"); michael@0: if (!mHaveKeyLengthAndCipher) michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: michael@0: *_result = mSecretKeyLength; michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsSSLStatus::GetCipherName(char** _result) michael@0: { michael@0: NS_ASSERTION(_result, "non-NULL destination required"); michael@0: if (!mHaveKeyLengthAndCipher) michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: michael@0: *_result = ToNewCString(mCipherName); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsSSLStatus::GetIsDomainMismatch(bool* _result) michael@0: { michael@0: NS_ASSERTION(_result, "non-NULL destination required"); michael@0: michael@0: *_result = mHaveCertErrorBits && mIsDomainMismatch; michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsSSLStatus::GetIsNotValidAtThisTime(bool* _result) michael@0: { michael@0: NS_ASSERTION(_result, "non-NULL destination required"); michael@0: michael@0: *_result = mHaveCertErrorBits && mIsNotValidAtThisTime; michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsSSLStatus::GetIsUntrusted(bool* _result) michael@0: { michael@0: NS_ASSERTION(_result, "non-NULL destination required"); michael@0: michael@0: *_result = mHaveCertErrorBits && mIsUntrusted; michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsSSLStatus::GetIsExtendedValidation(bool* aIsEV) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aIsEV); michael@0: *aIsEV = false; michael@0: michael@0: #ifdef MOZ_NO_EV_CERTS michael@0: return NS_OK; michael@0: #else michael@0: nsCOMPtr cert = mServerCert; michael@0: nsresult rv; michael@0: nsCOMPtr idinfo = do_QueryInterface(cert, &rv); michael@0: michael@0: // mServerCert should never be null when this method is called because michael@0: // nsSSLStatus objects always have mServerCert set right after they are michael@0: // constructed and before they are returned. GetIsExtendedValidation should michael@0: // only be called in the chrome process (in e10s), and mServerCert will always michael@0: // implement nsIIdentityInfo in the chrome process. michael@0: if (!idinfo) { michael@0: NS_ERROR("nsSSLStatus has null mServerCert or was called in the content " michael@0: "process"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: // Never allow bad certs for EV, regardless of overrides. michael@0: if (mHaveCertErrorBits) { michael@0: return NS_OK; michael@0: } michael@0: michael@0: return idinfo->GetIsExtendedValidation(aIsEV); michael@0: #endif michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsSSLStatus::Read(nsIObjectInputStream* stream) michael@0: { michael@0: nsCOMPtr cert; michael@0: nsresult rv = stream->ReadObject(true, getter_AddRefs(cert)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: mServerCert = do_QueryInterface(cert); michael@0: if (!mServerCert) michael@0: return NS_NOINTERFACE; michael@0: michael@0: rv = stream->Read32(&mKeyLength); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: rv = stream->Read32(&mSecretKeyLength); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: rv = stream->ReadCString(mCipherName); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: rv = stream->ReadBoolean(&mIsDomainMismatch); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: rv = stream->ReadBoolean(&mIsNotValidAtThisTime); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: rv = stream->ReadBoolean(&mIsUntrusted); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: rv = stream->ReadBoolean(&mHaveKeyLengthAndCipher); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: rv = stream->ReadBoolean(&mHaveCertErrorBits); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsSSLStatus::Write(nsIObjectOutputStream* stream) michael@0: { michael@0: nsresult rv = stream->WriteCompoundObject(mServerCert, michael@0: NS_GET_IID(nsIX509Cert), michael@0: true); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: rv = stream->Write32(mKeyLength); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: rv = stream->Write32(mSecretKeyLength); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: rv = stream->WriteStringZ(mCipherName.get()); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: rv = stream->WriteBoolean(mIsDomainMismatch); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: rv = stream->WriteBoolean(mIsNotValidAtThisTime); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: rv = stream->WriteBoolean(mIsUntrusted); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: rv = stream->WriteBoolean(mHaveKeyLengthAndCipher); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: rv = stream->WriteBoolean(mHaveCertErrorBits); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsSSLStatus::GetInterfaces(uint32_t *count, nsIID * **array) michael@0: { michael@0: *count = 0; michael@0: *array = nullptr; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsSSLStatus::GetHelperForLanguage(uint32_t language, nsISupports **_retval) michael@0: { michael@0: *_retval = nullptr; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsSSLStatus::GetContractID(char * *aContractID) michael@0: { michael@0: *aContractID = nullptr; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsSSLStatus::GetClassDescription(char * *aClassDescription) michael@0: { michael@0: *aClassDescription = nullptr; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsSSLStatus::GetClassID(nsCID * *aClassID) michael@0: { michael@0: *aClassID = (nsCID*) nsMemory::Alloc(sizeof(nsCID)); michael@0: if (!*aClassID) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: return GetClassIDNoAlloc(*aClassID); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsSSLStatus::GetImplementationLanguage(uint32_t *aImplementationLanguage) michael@0: { michael@0: *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsSSLStatus::GetFlags(uint32_t *aFlags) michael@0: { michael@0: *aFlags = 0; michael@0: return NS_OK; michael@0: } michael@0: michael@0: static NS_DEFINE_CID(kSSLStatusCID, NS_SSLSTATUS_CID); michael@0: michael@0: NS_IMETHODIMP michael@0: nsSSLStatus::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) michael@0: { michael@0: *aClassIDNoAlloc = kSSLStatusCID; michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsSSLStatus::nsSSLStatus() michael@0: : mKeyLength(0), mSecretKeyLength(0) michael@0: , mIsDomainMismatch(false) michael@0: , mIsNotValidAtThisTime(false) michael@0: , mIsUntrusted(false) michael@0: , mHaveKeyLengthAndCipher(false) michael@0: , mHaveCertErrorBits(false) michael@0: { michael@0: mCipherName = ""; michael@0: } michael@0: michael@0: NS_IMPL_ISUPPORTS(nsSSLStatus, nsISSLStatus, nsISerializable, nsIClassInfo) michael@0: michael@0: nsSSLStatus::~nsSSLStatus() michael@0: { michael@0: }