Bug 1282279 - Make user certificates Origin Attribute aware. r=keeler
authorJonathan Hao <jhao@mozilla.com>
Fri, 25 Nov 2016 17:28:22 +0800
changeset 325715 533ad81299f74d62e679afbf42bb52bea56ce7ac
parent 325714 ea7338a0b3deb91d7e10008e3560ca8e8e3605b0
child 325716 73a3bdf14ac18787819d83ba571b984a217b3209
push id31072
push userphilringnalda@gmail.com
push dateWed, 14 Dec 2016 03:19:56 +0000
treeherdermozilla-central@0c7a106074f7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskeeler
bugs1282279
milestone53.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 1282279 - Make user certificates Origin Attribute aware. r=keeler
security/manager/ssl/nsClientAuthRemember.cpp
security/manager/ssl/nsClientAuthRemember.h
security/manager/ssl/nsNSSIOLayer.cpp
--- a/security/manager/ssl/nsClientAuthRemember.cpp
+++ b/security/manager/ssl/nsClientAuthRemember.cpp
@@ -3,16 +3,17 @@
  * 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 "nsClientAuthRemember.h"
 
 #include "nsIX509Cert.h"
 #include "mozilla/RefPtr.h"
+#include "mozilla/BasePrincipal.h"
 #include "nsCRT.h"
 #include "nsNSSCertHelper.h"
 #include "nsIObserverService.h"
 #include "nsNetUtil.h"
 #include "nsISupportsPrimitives.h"
 #include "nsPromiseFlatString.h"
 #include "nsThreadUtils.h"
 #include "nsStringBuffer.h"
@@ -92,18 +93,19 @@ void nsClientAuthRememberService::ClearA
 
 void
 nsClientAuthRememberService::RemoveAllFromMemory()
 {
   mSettingsTable.Clear();
 }
 
 nsresult
-nsClientAuthRememberService::RememberDecision(const nsACString & aHostName, 
-                                              CERTCertificate *aServerCert, CERTCertificate *aClientCert)
+nsClientAuthRememberService::RememberDecision(
+  const nsACString& aHostName, const NeckoOriginAttributes& aOriginAttributes,
+  CERTCertificate* aServerCert, CERTCertificate* aClientCert)
 {
   // aClientCert == nullptr means: remember that user does not want to use a cert
   NS_ENSURE_ARG_POINTER(aServerCert);
   if (aHostName.IsEmpty()) {
     return NS_ERROR_INVALID_ARG;
   }
 
   nsAutoCString fpStr;
@@ -114,95 +116,98 @@ nsClientAuthRememberService::RememberDec
 
   {
     ReentrantMonitorAutoEnter lock(monitor);
     if (aClientCert) {
       RefPtr<nsNSSCertificate> pipCert(new nsNSSCertificate(aClientCert));
       nsAutoCString dbkey;
       rv = pipCert->GetDbKey(dbkey);
       if (NS_SUCCEEDED(rv)) {
-        AddEntryToList(aHostName, fpStr, dbkey);
+        AddEntryToList(aHostName, aOriginAttributes, fpStr, dbkey);
       }
     } else {
       nsCString empty;
-      AddEntryToList(aHostName, fpStr, empty);
+      AddEntryToList(aHostName, aOriginAttributes, fpStr, empty);
     }
   }
 
   return NS_OK;
 }
 
 nsresult
-nsClientAuthRememberService::HasRememberedDecision(const nsACString & aHostName, 
-                                                   CERTCertificate *aCert, 
-                                                   nsACString & aCertDBKey,
-                                                   bool *_retval)
+nsClientAuthRememberService::HasRememberedDecision(
+  const nsACString& aHostName, const NeckoOriginAttributes& aOriginAttributes,
+  CERTCertificate* aCert, nsACString& aCertDBKey, bool* aRetVal)
 {
   if (aHostName.IsEmpty())
     return NS_ERROR_INVALID_ARG;
 
   NS_ENSURE_ARG_POINTER(aCert);
-  NS_ENSURE_ARG_POINTER(_retval);
-  *_retval = false;
+  NS_ENSURE_ARG_POINTER(aRetVal);
+  *aRetVal = false;
 
   nsresult rv;
   nsAutoCString fpStr;
   rv = GetCertFingerprintByOidTag(aCert, SEC_OID_SHA256, fpStr);
   if (NS_FAILED(rv))
     return rv;
 
-  nsAutoCString hostCert;
-  GetHostWithCert(aHostName, fpStr, hostCert);
+  nsAutoCString entryKey;
+  GetEntryKey(aHostName, aOriginAttributes, fpStr, entryKey);
   nsClientAuthRemember settings;
 
   {
     ReentrantMonitorAutoEnter lock(monitor);
-    nsClientAuthRememberEntry *entry = mSettingsTable.GetEntry(hostCert.get());
+    nsClientAuthRememberEntry* entry = mSettingsTable.GetEntry(entryKey.get());
     if (!entry)
       return NS_OK;
     settings = entry->mSettings; // copy
   }
 
   aCertDBKey = settings.mDBKey;
-  *_retval = true;
+  *aRetVal = true;
   return NS_OK;
 }
 
 nsresult
-nsClientAuthRememberService::AddEntryToList(const nsACString &aHostName, 
-                                      const nsACString &fingerprint,
-                                      const nsACString &db_key)
-
+nsClientAuthRememberService::AddEntryToList(
+  const nsACString& aHostName, const NeckoOriginAttributes& aOriginAttributes,
+  const nsACString& aFingerprint, const nsACString& aDBKey)
 {
-  nsAutoCString hostCert;
-  GetHostWithCert(aHostName, fingerprint, hostCert);
+  nsAutoCString entryKey;
+  GetEntryKey(aHostName, aOriginAttributes, aFingerprint, entryKey);
 
   {
     ReentrantMonitorAutoEnter lock(monitor);
-    nsClientAuthRememberEntry *entry = mSettingsTable.PutEntry(hostCert.get());
+    nsClientAuthRememberEntry* entry = mSettingsTable.PutEntry(entryKey.get());
 
     if (!entry) {
       NS_ERROR("can't insert a null entry!");
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
-    entry->mHostWithCert = hostCert;
+    entry->mHostWithCert = entryKey;
 
-    nsClientAuthRemember &settings = entry->mSettings;
+    nsClientAuthRemember& settings = entry->mSettings;
     settings.mAsciiHost = aHostName;
-    settings.mFingerprint = fingerprint;
-    settings.mDBKey = db_key;
+    settings.mFingerprint = aFingerprint;
+    settings.mDBKey = aDBKey;
   }
 
   return NS_OK;
 }
 
 void
-nsClientAuthRememberService::GetHostWithCert(const nsACString & aHostName, 
-                                             const nsACString & fingerprint, 
-                                             nsACString& _retval)
+nsClientAuthRememberService::GetEntryKey(
+  const nsACString& aHostName,
+  const NeckoOriginAttributes& aOriginAttributes,
+  const nsACString& aFingerprint,
+  nsACString& aEntryKey)
 {
   nsAutoCString hostCert(aHostName);
+  nsAutoCString suffix;
+  aOriginAttributes.CreateSuffix(suffix);
+  hostCert.Append(suffix);
   hostCert.Append(':');
-  hostCert.Append(fingerprint);
-  
-  _retval.Assign(hostCert);
+  hostCert.Append(aFingerprint);
+
+  aEntryKey.Assign(hostCert);
 }
--- a/security/manager/ssl/nsClientAuthRemember.h
+++ b/security/manager/ssl/nsClientAuthRemember.h
@@ -11,16 +11,22 @@
 #include "nsTHashtable.h"
 #include "nsIObserver.h"
 #include "nsIX509Cert.h"
 #include "nsNSSCertificate.h"
 #include "nsString.h"
 #include "nsWeakReference.h"
 #include "mozilla/Attributes.h"
 
+namespace mozilla {
+  class NeckoOriginAttributes;
+}
+
+using mozilla::NeckoOriginAttributes;
+
 class nsClientAuthRemember
 {
 public:
 
   nsClientAuthRemember()
   {
   }
   
@@ -110,33 +116,40 @@ class nsClientAuthRememberService final 
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
   nsClientAuthRememberService();
 
   nsresult Init();
 
-  static void GetHostWithCert(const nsACString & aHostName, 
-                              const nsACString & nickname, nsACString& _retval);
+  static void GetEntryKey(const nsACString& aHostName,
+                          const NeckoOriginAttributes& aOriginAttributes,
+                          const nsACString& aFingerprint,
+                          /* out */ nsACString& aEntryKey);
 
-  nsresult RememberDecision(const nsACString & aHostName, 
-                            CERTCertificate *aServerCert, CERTCertificate *aClientCert);
-  nsresult HasRememberedDecision(const nsACString & aHostName, 
-                                 CERTCertificate *aServerCert, 
-                                 nsACString & aCertDBKey, bool *_retval);
+  nsresult RememberDecision(const nsACString& aHostName,
+                            const NeckoOriginAttributes& aOriginAttributes,
+                            CERTCertificate* aServerCert,
+                            CERTCertificate* aClientCert);
+
+  nsresult HasRememberedDecision(const nsACString& aHostName,
+                                 const NeckoOriginAttributes& aOriginAttributes,
+                                 CERTCertificate* aServerCert,
+                                 nsACString& aCertDBKey, bool* aRetVal);
 
   void ClearRememberedDecisions();
   static void ClearAllRememberedDecisions();
 
 protected:
     ~nsClientAuthRememberService();
 
     mozilla::ReentrantMonitor monitor;
     nsTHashtable<nsClientAuthRememberEntry> mSettingsTable;
 
     void RemoveAllFromMemory();
-    nsresult AddEntryToList(const nsACString &host, 
-                            const nsACString &server_fingerprint,
-                            const nsACString &db_key);
+    nsresult AddEntryToList(const nsACString& aHost,
+                            const NeckoOriginAttributes& aOriginAttributes,
+                            const nsACString& aServerFingerprint,
+                            const nsACString& aDBKey);
 };
 
 #endif
--- a/security/manager/ssl/nsNSSIOLayer.cpp
+++ b/security/manager/ssl/nsNSSIOLayer.cpp
@@ -2130,18 +2130,19 @@ ClientAuthDataRunnable::RunOnTargetThrea
 
     RefPtr<nsClientAuthRememberService> cars =
       mSocketInfo->SharedState().GetClientAuthRememberService();
 
     bool hasRemembered = false;
     nsCString rememberedDBKey;
     if (cars) {
       bool found;
-      rv = cars->HasRememberedDecision(hostname, mServerCert,
-        rememberedDBKey, &found);
+      rv = cars->HasRememberedDecision(hostname,
+                                       mSocketInfo->GetOriginAttributes(),
+                                       mServerCert, rememberedDBKey, &found);
       if (NS_SUCCEEDED(rv) && found) {
         hasRemembered = true;
       }
     }
 
     if (hasRemembered && !rememberedDBKey.IsEmpty()) {
       nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
       if (certdb) {
@@ -2245,18 +2246,18 @@ ClientAuthDataRunnable::RunOnTargetThrea
                                                                selectedIndex);
         if (!selectedCert) {
           goto loser;
         }
         cert.reset(selectedCert->GetCert());
       }
 
       if (cars && wantRemember) {
-        cars->RememberDecision(hostname, mServerCert,
-                               certChosen ? cert.get() : nullptr);
+        cars->RememberDecision(hostname, mSocketInfo->GetOriginAttributes(),
+                               mServerCert, certChosen ? cert.get() : nullptr);
       }
     }
 
     if (!cert) {
       goto loser;
     }
 
     // go get the private key