Bug 886752 - Add TLS version to SSLStatus and additional cleanup. r=keeler
authorTom Schuster <evilpies@gmail.com>
Fri, 24 Oct 2014 13:53:34 +0200
changeset 212227 eaaa68a7c2d8085969f5f15304b790bbf992ff63
parent 212226 0114b29a07303f24ea384bdac60548ec9d1a3a9a
child 212228 128fd9cbc29bcec8e325ad247dfebe569bdc8a65
push id27702
push userkwierso@gmail.com
push dateFri, 24 Oct 2014 22:05:50 +0000
treeherdermozilla-central@c70f62375f7d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskeeler
bugs886752
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 886752 - Add TLS version to SSLStatus and additional cleanup. r=keeler
security/manager/ssl/public/nsISSLStatus.idl
security/manager/ssl/src/TransportSecurityInfo.cpp
security/manager/ssl/src/nsNSSCallbacks.cpp
security/manager/ssl/src/nsSSLStatus.cpp
security/manager/ssl/src/nsSSLStatus.h
--- a/security/manager/ssl/public/nsISSLStatus.idl
+++ b/security/manager/ssl/public/nsISSLStatus.idl
@@ -3,30 +3,36 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface nsIX509Cert;
 
-[scriptable, uuid(3f1fcd83-c5a9-4cd1-a250-7676ca7c7e34)]
+[scriptable, uuid(fa9ba95b-ca3b-498a-b889-7c79cf28fee8)]
 interface nsISSLStatus : nsISupports {
   readonly attribute nsIX509Cert serverCert;
 
-  readonly attribute string cipherName;
+  readonly attribute ACString cipherName;
   readonly attribute unsigned long keyLength;
   readonly attribute unsigned long secretKeyLength;
 
+  const short SSL_VERSION_3   = 0;
+  const short TLS_VERSION_1   = 1;
+  const short TLS_VERSION_1_1 = 2;
+  const short TLS_VERSION_1_2 = 3;
+  readonly attribute unsigned short protocolVersion;
+
   readonly attribute boolean isDomainMismatch;
   readonly attribute boolean isNotValidAtThisTime;
 
-  /* Note: To distinguish between 
+  /* Note: To distinguish between
    *         "unstrusted because missing or untrusted issuer"
-   *       and 
+   *       and
    *         "untrusted because self signed"
    *       query nsIX509Cert::isSelfSigned
    */
   readonly attribute boolean isUntrusted;
 
   /**
    * True only if (and after) serverCert was successfully validated as
    * Extended Validation (EV).
--- a/security/manager/ssl/src/TransportSecurityInfo.cpp
+++ b/security/manager/ssl/src/TransportSecurityInfo.cpp
@@ -284,18 +284,18 @@ TransportSecurityInfo::GetInterface(cons
   }
   return rv;
 }
 
 // This is a new magic value. However, it re-uses the first 4 bytes
 // of the previous value. This is so when older versions attempt to
 // read a newer serialized TransportSecurityInfo, they will actually
 // fail and return NS_ERROR_FAILURE instead of silently failing.
-#define TRANSPORTSECURITYINFOMAGIC { 0xa9863a23, 0xda1f, 0x4008, \
-  { 0xac, 0x3c, 0x52, 0x86, 0x21, 0x54, 0x10, 0x70 } }
+#define TRANSPORTSECURITYINFOMAGIC { 0xa9863a23, 0x2429, 0x4866, \
+  { 0x92, 0x89, 0x45, 0x51, 0xc2, 0x01, 0xca, 0xf2 } }
 static NS_DEFINE_CID(kTransportSecurityInfoMagic, TRANSPORTSECURITYINFOMAGIC);
 
 NS_IMETHODIMP
 TransportSecurityInfo::Write(nsIObjectOutputStream* stream)
 {
   nsresult rv = stream->WriteID(kTransportSecurityInfoMagic);
   if (NS_FAILED(rv)) {
     return rv;
--- a/security/manager/ssl/src/nsNSSCallbacks.cpp
+++ b/security/manager/ssl/src/nsNSSCallbacks.cpp
@@ -887,20 +887,19 @@ PreliminaryHandshakeDone(PRFileDesc* fd)
                                sizeof cipherInfo) == SECSuccess) {
       /* Set the SSL Status information */
       RefPtr<nsSSLStatus> status(infoObject->SSLStatus());
       if (!status) {
         status = new nsSSLStatus();
         infoObject->SetSSLStatus(status);
       }
 
-      status->mHaveKeyLengthAndCipher = true;
-      status->mKeyLength = cipherInfo.symKeyBits;
-      status->mSecretKeyLength = cipherInfo.effectiveKeyBits;
-      status->mCipherName.Assign(cipherInfo.cipherSuiteName);
+      status->mHaveCipherSuiteAndProtocol = true;
+      status->mCipherSuite = channelInfo.cipherSuite;
+      status->mProtocolVersion = channelInfo.protocolVersion & 0xFF;
       infoObject->SetKEAUsed(cipherInfo.keaType);
       infoObject->SetKEAKeyBits(channelInfo.keaKeyBits);
       infoObject->SetMACAlgorithmUsed(cipherInfo.macAlgorithm);
     }
   }
 
   // Get the NPN value.
   SSLNextProtoState state;
--- a/security/manager/ssl/src/nsSSLStatus.cpp
+++ b/security/manager/ssl/src/nsSSLStatus.cpp
@@ -6,259 +6,281 @@
 
 #include "nsSSLStatus.h"
 #include "plstr.h"
 #include "nsIClassInfoImpl.h"
 #include "nsIIdentityInfo.h"
 #include "nsIProgrammingLanguage.h"
 #include "nsIObjectOutputStream.h"
 #include "nsIObjectInputStream.h"
+#include "ssl.h"
 
 NS_IMETHODIMP
-nsSSLStatus::GetServerCert(nsIX509Cert** _result)
+nsSSLStatus::GetServerCert(nsIX509Cert** aServerCert)
 {
-  NS_ASSERTION(_result, "non-NULL destination required");
+  NS_ENSURE_ARG_POINTER(aServerCert);
 
-  *_result = mServerCert;
-  NS_IF_ADDREF(*_result);
-
+  nsCOMPtr<nsIX509Cert> cert = mServerCert;
+  cert.forget(aServerCert);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSSLStatus::GetKeyLength(uint32_t* _result)
+nsSSLStatus::GetKeyLength(uint32_t* aKeyLength)
 {
-  NS_ASSERTION(_result, "non-NULL destination required");
-  if (!mHaveKeyLengthAndCipher)
+  NS_ENSURE_ARG_POINTER(aKeyLength);
+  if (!mHaveCipherSuiteAndProtocol) {
     return NS_ERROR_NOT_AVAILABLE;
+  }
 
-  *_result = mKeyLength;
+  SSLCipherSuiteInfo cipherInfo;
+  if (SSL_GetCipherSuiteInfo(mCipherSuite, &cipherInfo,
+                             sizeof(cipherInfo)) != SECSuccess) {
+    return NS_ERROR_FAILURE;
+  }
 
+  *aKeyLength = cipherInfo.symKeyBits;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSSLStatus::GetSecretKeyLength(uint32_t* _result)
+nsSSLStatus::GetSecretKeyLength(uint32_t* aSecretKeyLength)
 {
-  NS_ASSERTION(_result, "non-NULL destination required");
-  if (!mHaveKeyLengthAndCipher)
+  NS_ENSURE_ARG_POINTER(aSecretKeyLength);
+  if (!mHaveCipherSuiteAndProtocol) {
     return NS_ERROR_NOT_AVAILABLE;
+  }
 
-  *_result = mSecretKeyLength;
+  SSLCipherSuiteInfo cipherInfo;
+  if (SSL_GetCipherSuiteInfo(mCipherSuite, &cipherInfo,
+                             sizeof(cipherInfo)) != SECSuccess) {
+    return NS_ERROR_FAILURE;
+  }
 
+  *aSecretKeyLength = cipherInfo.effectiveKeyBits;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSSLStatus::GetCipherName(char** _result)
+nsSSLStatus::GetCipherName(nsACString& aCipherName)
 {
-  NS_ASSERTION(_result, "non-NULL destination required");
-  if (!mHaveKeyLengthAndCipher)
+  if (!mHaveCipherSuiteAndProtocol) {
     return NS_ERROR_NOT_AVAILABLE;
+  }
 
-  *_result = ToNewCString(mCipherName);
+  SSLCipherSuiteInfo cipherInfo;
+  if (SSL_GetCipherSuiteInfo(mCipherSuite, &cipherInfo,
+                             sizeof(cipherInfo)) != SECSuccess) {
+    return NS_ERROR_FAILURE;
+  }
 
+  aCipherName.Assign(cipherInfo.cipherSuiteName);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSSLStatus::GetIsDomainMismatch(bool* _result)
+nsSSLStatus::GetProtocolVersion(uint16_t* aProtocolVersion)
 {
-  NS_ASSERTION(_result, "non-NULL destination required");
+  NS_ENSURE_ARG_POINTER(aProtocolVersion);
+  if (!mHaveCipherSuiteAndProtocol) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
 
-  *_result = mHaveCertErrorBits && mIsDomainMismatch;
-
+  *aProtocolVersion = mProtocolVersion;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSSLStatus::GetIsNotValidAtThisTime(bool* _result)
+nsSSLStatus::GetIsDomainMismatch(bool* aIsDomainMismatch)
 {
-  NS_ASSERTION(_result, "non-NULL destination required");
+  NS_ENSURE_ARG_POINTER(aIsDomainMismatch);
 
-  *_result = mHaveCertErrorBits && mIsNotValidAtThisTime;
-
+  *aIsDomainMismatch = mHaveCertErrorBits && mIsDomainMismatch;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSSLStatus::GetIsUntrusted(bool* _result)
+nsSSLStatus::GetIsNotValidAtThisTime(bool* aIsNotValidAtThisTime)
 {
-  NS_ASSERTION(_result, "non-NULL destination required");
+  NS_ENSURE_ARG_POINTER(aIsNotValidAtThisTime);
+
+  *aIsNotValidAtThisTime = mHaveCertErrorBits && mIsNotValidAtThisTime;
+  return NS_OK;
+}
 
-  *_result = mHaveCertErrorBits && mIsUntrusted;
+NS_IMETHODIMP
+nsSSLStatus::GetIsUntrusted(bool* aIsUntrusted)
+{
+  NS_ENSURE_ARG_POINTER(aIsUntrusted);
 
+  *aIsUntrusted = mHaveCertErrorBits && mIsUntrusted;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSSLStatus::GetIsExtendedValidation(bool* aIsEV)
 {
   NS_ENSURE_ARG_POINTER(aIsEV);
   *aIsEV = false;
 
 #ifdef MOZ_NO_EV_CERTS
   return NS_OK;
 #else
   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.
+  nsCOMPtr<nsIIdentityInfo> idinfo = do_QueryInterface(cert);
   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 (mHaveCertErrorBits) {
     return NS_OK;
   }
 
   return idinfo->GetIsExtendedValidation(aIsEV);
 #endif
 }
 
 NS_IMETHODIMP
-nsSSLStatus::Read(nsIObjectInputStream* stream)
+nsSSLStatus::Read(nsIObjectInputStream* aStream)
 {
   nsCOMPtr<nsISupports> cert;
-  nsresult rv = stream->ReadObject(true, getter_AddRefs(cert));
+  nsresult rv = aStream->ReadObject(true, getter_AddRefs(cert));
   NS_ENSURE_SUCCESS(rv, rv);
 
   mServerCert = do_QueryInterface(cert);
-  if (!mServerCert)
+  if (!mServerCert) {
     return NS_NOINTERFACE;
+  }
 
-  rv = stream->Read32(&mKeyLength);
+  rv = aStream->Read16(&mCipherSuite);
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = stream->Read32(&mSecretKeyLength);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = stream->ReadCString(mCipherName);
+  rv = aStream->Read16(&mProtocolVersion);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = stream->ReadBoolean(&mIsDomainMismatch);
+  rv = aStream->ReadBoolean(&mIsDomainMismatch);
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = stream->ReadBoolean(&mIsNotValidAtThisTime);
+  rv = aStream->ReadBoolean(&mIsNotValidAtThisTime);
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = stream->ReadBoolean(&mIsUntrusted);
+  rv = aStream->ReadBoolean(&mIsUntrusted);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = stream->ReadBoolean(&mHaveKeyLengthAndCipher);
+  rv = aStream->ReadBoolean(&mHaveCipherSuiteAndProtocol);
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = stream->ReadBoolean(&mHaveCertErrorBits);
+  rv = aStream->ReadBoolean(&mHaveCertErrorBits);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSSLStatus::Write(nsIObjectOutputStream* stream)
+nsSSLStatus::Write(nsIObjectOutputStream* aStream)
 {
-  nsresult rv = stream->WriteCompoundObject(mServerCert,
-                                            NS_GET_IID(nsIX509Cert),
-                                            true);
+  nsresult rv = aStream->WriteCompoundObject(mServerCert,
+                                             NS_GET_IID(nsIX509Cert),
+                                             true);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = stream->Write32(mKeyLength);
+  rv = aStream->Write16(mCipherSuite);
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = stream->Write32(mSecretKeyLength);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = stream->WriteStringZ(mCipherName.get());
+  rv = aStream->Write16(mProtocolVersion);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = stream->WriteBoolean(mIsDomainMismatch);
+  rv = aStream->WriteBoolean(mIsDomainMismatch);
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = stream->WriteBoolean(mIsNotValidAtThisTime);
+  rv = aStream->WriteBoolean(mIsNotValidAtThisTime);
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = stream->WriteBoolean(mIsUntrusted);
+  rv = aStream->WriteBoolean(mIsUntrusted);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = stream->WriteBoolean(mHaveKeyLengthAndCipher);
+  rv = aStream->WriteBoolean(mHaveCipherSuiteAndProtocol);
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = stream->WriteBoolean(mHaveCertErrorBits);
+  rv = aStream->WriteBoolean(mHaveCertErrorBits);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSSLStatus::GetInterfaces(uint32_t *count, nsIID * **array)
+nsSSLStatus::GetInterfaces(uint32_t* aCount, nsIID*** aArray)
 {
-  *count = 0;
-  *array = nullptr;
+  *aCount = 0;
+  *aArray = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSSLStatus::GetHelperForLanguage(uint32_t language, nsISupports **_retval)
+nsSSLStatus::GetHelperForLanguage(uint32_t aLanguage, nsISupports** aHelper)
 {
-  *_retval = nullptr;
+  *aHelper = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSSLStatus::GetContractID(char * *aContractID)
+nsSSLStatus::GetContractID(char** aContractID)
 {
   *aContractID = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSSLStatus::GetClassDescription(char * *aClassDescription)
+nsSSLStatus::GetClassDescription(char** aClassDescription)
 {
   *aClassDescription = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSSLStatus::GetClassID(nsCID * *aClassID)
+nsSSLStatus::GetClassID(nsCID** aClassID)
 {
   *aClassID = (nsCID*) nsMemory::Alloc(sizeof(nsCID));
-  if (!*aClassID)
+  if (!*aClassID) {
     return NS_ERROR_OUT_OF_MEMORY;
+  }
   return GetClassIDNoAlloc(*aClassID);
 }
 
 NS_IMETHODIMP
-nsSSLStatus::GetImplementationLanguage(uint32_t *aImplementationLanguage)
+nsSSLStatus::GetImplementationLanguage(uint32_t* aImplementationLanguage)
 {
   *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSSLStatus::GetFlags(uint32_t *aFlags)
+nsSSLStatus::GetFlags(uint32_t* aFlags)
 {
   *aFlags = 0;
   return NS_OK;
 }
 
 static NS_DEFINE_CID(kSSLStatusCID, NS_SSLSTATUS_CID);
 
 NS_IMETHODIMP
-nsSSLStatus::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
+nsSSLStatus::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
 {
   *aClassIDNoAlloc = kSSLStatusCID;
   return NS_OK;
 }
 
 nsSSLStatus::nsSSLStatus()
-: mKeyLength(0), mSecretKeyLength(0)
+: mCipherSuite(0)
+, mProtocolVersion(0)
 , mIsDomainMismatch(false)
 , mIsNotValidAtThisTime(false)
 , mIsUntrusted(false)
-, mHaveKeyLengthAndCipher(false)
+, mHaveCipherSuiteAndProtocol(false)
 , mHaveCertErrorBits(false)
 {
-  mCipherName = "";
 }
 
 NS_IMPL_ISUPPORTS(nsSSLStatus, nsISSLStatus, nsISerializable, nsIClassInfo)
 
 nsSSLStatus::~nsSSLStatus()
 {
 }
--- a/security/manager/ssl/src/nsSSLStatus.h
+++ b/security/manager/ssl/src/nsSSLStatus.h
@@ -27,29 +27,27 @@ public:
   NS_DECL_NSISERIALIZABLE
   NS_DECL_NSICLASSINFO
 
   nsSSLStatus();
 
   /* public for initilization in this file */
   nsCOMPtr<nsIX509Cert> mServerCert;
 
-  uint32_t mKeyLength;
-  uint32_t mSecretKeyLength;
-  nsXPIDLCString mCipherName;
+  uint16_t mCipherSuite;
+  uint16_t mProtocolVersion;
 
   bool mIsDomainMismatch;
   bool mIsNotValidAtThisTime;
   bool mIsUntrusted;
 
-  bool mHaveKeyLengthAndCipher;
+  bool mHaveCipherSuiteAndProtocol;
 
   /* mHaveCertErrrorBits is relied on to determine whether or not a SPDY
      connection is eligible for joining in nsNSSSocketInfo::JoinConnection() */
   bool mHaveCertErrorBits;
 };
 
-// 2c3837af-8b85-4a68-b0d8-0aed88985b32
 #define NS_SSLSTATUS_CID \
-{ 0x2c3837af, 0x8b85, 0x4a68, \
-  { 0xb0, 0xd8, 0x0a, 0xed, 0x88, 0x98, 0x5b, 0x32 } }
+{ 0x61f69c85, 0x0fed, 0x44fb, \
+  { 0x89, 0x8f, 0xa4, 0xb1, 0x3c, 0x33, 0x3c, 0x8d } }
 
 #endif