Bug 634697 - Add permanent storage to user's client certificate selection r=keeler,baku,fluent-reviewers,Gijs
authorMoritz Birghan <mbirghan@mozilla.com>
Mon, 03 Aug 2020 13:24:34 +0000
changeset 3102952 7142dd253e6d245748323956797d2c28f1399d7b
parent 3102951 98cee710190613a3f88085691b51319622f6db55
child 3102953 d8bdbda9b88c2e5ebb09a706a34258da5c1bc954
push id578529
push userreviewbot
push dateTue, 04 Aug 2020 02:36:56 +0000
treeherdertry@538c88f9f9fe [default view] [failures only]
reviewerskeeler, baku, fluent-reviewers, Gijs
bugs634697
milestone81.0a1
Bug 634697 - Add permanent storage to user's client certificate selection r=keeler,baku,fluent-reviewers,Gijs Differential Revision: https://phabricator.services.mozilla.com/D58820
build/pgo/certs/cert9.db
build/pgo/certs/key4.db
build/pgo/certs/mochitest.client
build/pgo/server-locations.txt
security/manager/locales/en-US/security/certificates/certManager.ftl
security/manager/pki/resources/content/certManager.js
security/manager/ssl/DataStorageList.h
security/manager/ssl/nsClientAuthRemember.cpp
security/manager/ssl/nsClientAuthRemember.h
security/manager/ssl/nsIClientAuthRememberService.idl
security/manager/ssl/nsNSSComponent.cpp
security/manager/ssl/nsNSSIOLayer.cpp
security/manager/ssl/tests/mochitest/browser/browser_clientAuthRememberService.js
security/manager/ssl/tests/mochitest/browser/browser_clientAuth_connection.js
security/manager/ssl/tests/unit/head_psm.js
security/manager/ssl/tests/unit/test_sss_eviction.js
security/manager/ssl/tests/unit/test_sss_readstate.js
security/manager/ssl/tests/unit/test_sss_readstate_garbage.js
security/manager/ssl/tests/unit/test_sss_readstate_huge.js
security/manager/ssl/tests/unit/test_sss_savestate.js
toolkit/components/cleardata/ClearDataService.jsm
index c4f59cdf389fdb2cdfd68703b535c8cf98868ea6..1e22f8b769aff353e3a582aa86ae88e759e83590
GIT binary patch
literal 229376
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
G_x}Tec^yjt
index cd34021f5de6187e97465feb0f59222bdaec3297..aaac6ba7dfec280c7bca08a03e433ce3ab645492
GIT binary patch
literal 294912
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
z0000000000000000000000000000000002~e~gNhjF{ZTXqI$)MKi*Vgp!nunq0o=
zJPmd)Y4Rtc<nPJr*mnQ`000000000000000000000000000000000000000000000
z00000000000000000000000000000000000000000000000000!2b|rq(sD|zZN8<
zq(sy-$>T(%N%}-d`pF(iiT|gw0RR9100000000000000000000000000000000000
z00000000000000000000000000000000000000000000000000000000Kk89ilpJx
zNEsPvq$CBYEg31DkYBK8V3ZeHG9t>uD<lZz7aSoK>K7dB7wjX2jztB92BM`rLxM0~
zWGN=ZNX%0iS|s(aBPp0kY;FE|gNm6%S6hY+$@1$4B{RKQNK|knb|_vuKXi-?Ka%g)
zb{ghgW+Cx@fq^JqNnU+BUN5vqln-wtIwF!6doUMr_pdwAGPBsAJ)^??BI9`VgMIvh
z(dck&6d6UN{B~YuN$ipPvBzLH@`_+TN_bR6WK2kSq;H%kb{OekR1jJN9WD85SV>Qm
zj094Qf?6!yD1Dutn3|Z4%hMMX9*BxW1#3nA9^_v?NzyPfj2AJ|Uq%Ee^!uan>_-QM
zhJ>TS<9Kz^;gNpcex9gEG_Q74q;JTtj4~WZw%?!Ij(>h`{|F}|fJFTMgmznohj{x1
zqInIY{JhX!ycVI6enEcms7Sw%U=r*Zks$Qc(Il@BktTN#C66U9V&4G(0000000000
z00000000000000000000000000000000000000000000000000000000000000000
z000000000000000000000RIg!lS)uWM4}@7JT3i#gZ+YibWmPQq$0%VXuse{ba)Wj
z%MTTaCZ#52BM$Wm@kEhekJ<TeBhX;qNRw|6CBII7fPDu500000000000000000000
z00000000000000000000000000000000000000000000000000000000000000000
z00000000000Q@(?K`Kvt+@yGvgPyMDWWZDv!{t*88dl^FNq_A~OlZ?gJtg>|ttwg4
zz<179q3((}2|KAgwW803_U_lD-&Zl5#LKx^f=@B@?)2Ev>ULfuN_I$UOkz0bmv|?U
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
index 3142b38d35b424c72f24022e95dc686767f12385..508db409b9853ad84967557f69ac7b3763658b9e
GIT binary patch
literal 2448
zc$`&~cRU-47RQ4mqBSarN=LLxNnH}H8WDT6HL9^|N7V{iQMIm;BGf81J2YmDTeMb#
zqSPjK?<HzeLF`epulMtL@7?$QIG^)5-*e8N-ye#^70b@Xfg*9?z+A}48<D#_Y@BQq
z5|<W`#HIENV^AcH-hWnL3W=lf7ph}t1N>^0|MP@83qJAhftwAC;sru{q|&N!k@GU_
z><~aGi6d&rra;lb4oVN{r;YISs*|bT&TD|C6c1579!(ASk8{#(X9zO4_0-$mDpm!T
z=$6!MmJP~a|A6z<7H$LfwwoL7kjCEP<_(sktigoeZ4Ef}dmr}<0aglRhj{lRFB4(y
z9fOhad~~}Aa!kry=#6XDf?k~QHEOOQ;(dAPT0KNR(W^9#6#R2z+(^fW@Fn_ERN2dE
zy4z44+}DTO^ETu~%@j7$T1s1ra@ZH|E{ff@V7*?OTBKt9`8Bv-hY{n4%RPmQ?DrYS
zOiY32*Tc#O{3@%-^#s{OH3`;?Of8hJ%WO)lY<()YX*2_CWBacE5*(EiH)z89XTFwb
zJTZ!k7#engbpEXRIIj45`DBhx2Ia}-gMr)kdm)U|c?i>od}>o3UmZ6zJJxt^K-YgV
zDn#-_NV1)hIVk~rt%(s&^vwtdDcE!s6<hKHe8Oh0Ere=}GD)8=pqRO7U^JD*=y^SX
z)}A8c@jk4~@>0PIMZHbW;bEiWA;xiAzC+ssc7~-DD2^6a52q#DAOTa;#{=;9A$xgT
znc!ogD$Z`77X|7LGNST4p#gDT`-kTRv6jms1Zmj)yaB~`Q44pcL&l4jn9TP{if1iB
zl$P~9Ep0sFqwcK))#csnEceZ>)fGFHeu~jPnK#tq64K7zGdoyFBhjlMWHxZzD@jdT
ztXySB)Jpp9m9gOpO~xNjSZzPAk&k?Vaht|R5s)G4S97U3%-oII%)RctZFW{B5r`Hn
z9#rNJ0@<5;e}lRjx?%Mf^PUwN>`bs!?U6qMSrheqly36ItGh>i`FP!{rr>9?2>c8F
z<(XKU^ypadl6}1YVS-dU_O~a8bFQR0g??&tq%tvFIYK$pSPzrBE0?k52}0_K9Jn{+
z@s-E_1!i5RR)+SZ&wYU4<KQuw7)0>y!C=UyiBp^`PocoXEnzyGU#1u~QwXcy_h(qg
zI%!j4ZFy54N?9(IFJe0k?*#jiQolTJeVm|^?AM5u4-`_lJc=0sUAa-YHGGa&8kN?p
zNtqxlxnXoz&dXO%Ng|`x8t1*9_A!LJlZ9Y@!+KggU!Fnai0zgmMmn^I6-h`F`0M&H
zPP%t{%N;Y9&*&y?t4x4t8+s{Yhvq!MK_6WZDW;w%f_3e)Ox!or!=6=ZCf~FJ1umad
zSS159RyAv!c6!+X3AwGzLK_VhiUhj%f3}0nfF#hJU)b<h-2|WfkH#n1*eN973W@|=
z{6D)n{<hm={CjWRaq73f?FN#7?X&eAi?ySoPzxe|_8i<l>swXVg0yN#^(3P_@p{5Z
z_i<tWF&VykJAbM)>5eqPwUT(#ji<|h#oG~Q>V<o!$lRQaPB2m&mBS7RRK*KyWJN3G
z_eVGnC@Z;>g@l?_D64z@1EstdyGc#vEl#Yr^TAVo8^*9L#fVfAuY30A#+re3aU4u_
zL8=XD=d$T)Kb$RedU=FRiHxy)fOyz1*5~OjoV06tAm!j6%OOsV3){-1Wo=oc?Ob7r
zmemFR#$D7Y?-LBWtY)R6V#2#Mj+B(KxR)Paz0C~8F1!e?@8lGotaEV>ub%vRPVG15
z*>CJJv%bqGw(w@Fm3Dg8Gq#yE>u=pUPxS;bq_||p^l`E;8+GAbr&Q~YfF-1UJVP&y
zAKI>Ivn-7EirsUm;JIJ>ERS}x-??T6!E5!YHD^f#@!3AuQGmsm5m@UDKb0M?+GyR&
z@xIO;<SQq)Q009&1LfrZIqPZNY?z$7DDfP0{ZAy~hhoeRd2elChaI=}2YZajam-Yx
z@k=!{I&4HO;YgkOI;HAd%;711YYj-rlzcutKky)^irv%H_(?~Wrf{zQTbpLNX|^-|
zBl`e}tmc_Q_a@Xk*MP#552XzCbZJ85vb+D*>7TJquDR%*T&v^H0qPQN6{==Nh(v=k
z^ERHGi-FJc-mh)oob?QpY(26z4^~!Ww!=n+F}V_83+JS61<_KbjV@w>a~weA;12g#
zeQL^64t5>M+D^V|cHjgxYgg8VJk+;PrOWPdyqOr4+?kdZvq~=pxAsj#_6Bw$oIPNL
z>d3hDd-rsP8?@Q9#+r76I+Q}iFqC`*JbO*;y~Dec)>Tx|>dgmZj>p<erL;HaIx~~s
zbUtbM-Ai7g&(+cW=?bO6NOQNqdls!lD^4{0T|6q9f-HkD6pCm)5=T<%hS0y9X|Fy4
z#|ddgRVa(#)SdFO++i2Y@f|}2$x1qj#_SvNyai%A?&fsJR=HQ)pWGg=p<|$)q#d*f
z6zjPkmg*wbulghAYII9NxW3Ib3p@aPAa49-(jeJv|Mr?20n7dIdw_?~`EbsYM<{Oj
zv07@Y*Q1tga?<-r0KV-pAgnU-<sa@Toabv#H@s?gG%{-BW)sh+4W?>Zl9dA-7+HLe
zfNxUM$Zb9nm;kt>2vvXU;+6(;EU~*8(SK`jXxKbz`cWhLr3G!ZSb@Dz_Y3xR9ka@5
z=<MLb`+S!1YDN(Yk3EOFXL$~!l#Dw*hwqfw7o1zQV_N#PClX<?Jh}7TG{JFP46E&?
zkGgdr8q^{=I6M6y0FB>9Uc)*kgMQ9pv^M&AKbpwiT>ZGX?KXw^3PU`1r+rfO2pzxp
zMTgib^C-Bz`5=^UzAQJvprJ3)PU;BhjmPs`I1vQodR+#GVlEJ%3bMX8+GY$k<$B@I
z>7UBT0^3%&7HajO`7w%)SltPWy&m_e@RfKPaU>_{Hty*qMh!Cal%8VObZiE)RJw*Z
ziW`JZ*3bwp<Bv+kx=%(mGQP(w4O6=&KD@oyAf<=6zu%35_Dt<~o;ho$fa($pVG|iC
zA=PR56{Q#K_k}EeCqk7)sjqVg7O|v~ii<E}v?UDAmD5x1XkIJW8S3!o5c&q{!hh3|
zOAsx19t!XTcmtdOt^hZHFTfc<1o)!F{y7ms!+?TwKiiu4OcnH(zb@D!wGU6*SA+?n
z(5MS2E->f{F9$mu1ON&K>6zdCOM-AsL~#TzVLnRhI+_dxLSpF)$_Lk@z5Wi;e*xxX
BgsA`k
--- a/build/pgo/server-locations.txt
+++ b/build/pgo/server-locations.txt
@@ -112,16 +112,17 @@ https://sub1.test2.example.com:443     p
 https://sub2.test1.example.com:443     privileged
 https://sub2.test2.example.com:443     privileged
 https://nocert.example.com:443         privileged,nocert
 https://self-signed.example.com:443    privileged,cert=selfsigned
 https://untrusted.example.com:443      privileged,cert=untrusted
 https://expired.example.com:443        privileged,cert=expired
 https://requestclientcert.example.com:443         privileged,clientauth=request
 https://requireclientcert.example.com:443         privileged,clientauth=require
+https://requireclientcert-2.example.com:443         privileged,clientauth=require
 https://mismatch.expired.example.com:443	privileged,cert=expired
 https://mismatch.untrusted.example.com:443	privileged,cert=untrusted
 https://untrusted-expired.example.com:443	privileged,cert=untrustedandexpired
 https://mismatch.untrusted-expired.example.com:443	privileged,cert=untrustedandexpired
 https://supports-insecure.expired.example.com:443   privileged,cert=expired
 https://no-subject-alt-name.example.com:443   cert=noSubjectAltName
 
 # Used for secure contexts on ip addresses, see bug 1616675. Note that
--- a/security/manager/locales/en-US/security/certificates/certManager.ftl
+++ b/security/manager/locales/en-US/security/certificates/certManager.ftl
@@ -179,16 +179,19 @@ delete-email-cert-impact = If you delete a person’s e-mail certificate, you will no longer be able to send encrypted e-mail to that person.
 
 # Used for semi-uniquely representing a cert.
 #
 # Variables:
 #   $serialNumber : the serial number of the cert in AA:BB:CC hex format.
 cert-with-serial =
     .value = Certificate with serial number: { $serialNumber }
 
+# Used to indicate that the user chose not to send a client authentication certificate to a server that requested one in a TLS handshake.
+send-no-client-certificate = Send no client certificate
+
 ## Add Security Exception dialog
 add-exception-branded-warning = You are about to override how { -brand-short-name } identifies this site.
 add-exception-invalid-header = This site attempts to identify itself with invalid information.
 add-exception-domain-mismatch-short = Wrong Site
 add-exception-domain-mismatch-long = The certificate belongs to a different site, which could mean that someone is trying to impersonate this site.
 add-exception-expired-short = Outdated Information
 add-exception-expired-long = The certificate is not currently valid. It may have been stolen or lost, and could be used by someone to impersonate this site.
 add-exception-unverified-or-bad-signature-short = Unknown Identity
--- a/security/manager/pki/resources/content/certManager.js
+++ b/security/manager/pki/resources/content/certManager.js
@@ -44,30 +44,32 @@ var emailTreeView;
  */
 var userTreeView;
 
 var clientAuthRememberService;
 
 var richlist;
 
 var rememberedDecisionsRichList = {
-  buildRichList() {
+  async buildRichList() {
     let rememberedDecisions = clientAuthRememberService.getDecisions();
 
     let oldItems = richlist.querySelectorAll("richlistitem");
     for (let item of oldItems) {
       item.remove();
     }
 
     let frag = document.createDocumentFragment();
     for (let decision of rememberedDecisions) {
-      let richlistitem = this._richBoxAddItem(decision);
+      let richlistitem = await this._richBoxAddItem(decision);
       frag.appendChild(richlistitem);
     }
     richlist.appendChild(frag);
+
+    richlist.addEventListener("select", () => this.setButtonState());
   },
 
   _createItem(item) {
     let innerHbox = document.createXULElement("hbox");
     innerHbox.setAttribute("align", "center");
     innerHbox.setAttribute("flex", "1");
 
     let row = document.createXULElement("label");
@@ -76,66 +78,91 @@ var rememberedDecisionsRichList = {
     row.setAttribute("style", "margin-inline-start: 15px;");
     row.setAttribute("value", item);
     row.setAttribute("ordinal", "1");
     innerHbox.appendChild(row);
 
     return innerHbox;
   },
 
-  _richBoxAddItem(item) {
+  async _richBoxAddItem(item) {
     let richlistitem = document.createXULElement("richlistitem");
 
     richlistitem.setAttribute("entryKey", item.entryKey);
     richlistitem.setAttribute("dbKey", item.dbKey);
 
     let hbox = document.createXULElement("hbox");
     hbox.setAttribute("flex", "1");
     hbox.setAttribute("equalsize", "always");
 
-    let tmpCert = certdb.findCertByDBKey(item.dbKey);
+    hbox.appendChild(this._createItem(item.asciiHost));
+    if (item.dbKey == "") {
+      let noCertSpecified = await document.l10n.formatValue(
+        "send-no-client-certificate"
+      );
 
-    hbox.appendChild(this._createItem(item.asciiHost));
+      hbox.appendChild(this._createItem(noCertSpecified));
 
-    hbox.appendChild(this._createItem(tmpCert.commonName));
+      hbox.appendChild(this._createItem(""));
+    } else {
+      let tmpCert = certdb.findCertByDBKey(item.dbKey);
 
-    hbox.appendChild(this._createItem(tmpCert.serialNumber));
+      hbox.appendChild(this._createItem(tmpCert.commonName));
+
+      hbox.appendChild(this._createItem(tmpCert.serialNumber));
+    }
 
     richlistitem.appendChild(hbox);
 
     return richlistitem;
   },
 
-  deleteSelectedRichListItem() {
+  async deleteSelectedRichListItem() {
     let selectedItem = richlist.selectedItem;
     let index = richlist.selectedIndex;
     if (index < 0) {
       return;
     }
 
     clientAuthRememberService.forgetRememberedDecision(
       selectedItem.attributes.entryKey.value
     );
 
-    this.buildRichList();
+    await this.buildRichList();
+    this.setButtonState();
   },
 
   viewSelectedRichListItem() {
     let selectedItem = richlist.selectedItem;
     let index = richlist.selectedIndex;
     if (index < 0) {
       return;
     }
 
-    let cert = certdb.findCertByDBKey(selectedItem.attributes.dbKey.value);
-    viewCertHelper(window, cert);
+    if (selectedItem.attributes.dbKey.value != "") {
+      let cert = certdb.findCertByDBKey(selectedItem.attributes.dbKey.value);
+      viewCertHelper(window, cert);
+    }
+  },
+
+  setButtonState() {
+    let rememberedDeleteButton = document.getElementById(
+      "remembered_deleteButton"
+    );
+    let rememberedViewButton = document.getElementById("remembered_viewButton");
+
+    rememberedDeleteButton.disabled = richlist.selectedIndex < 0;
+    rememberedViewButton.disabled =
+      richlist.selectedItem == null
+        ? true
+        : richlist.selectedItem.attributes.dbKey.value == "";
   },
 };
 
-function LoadCerts() {
+async function LoadCerts() {
   certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
     Ci.nsIX509CertDB
   );
   var certcache = certdb.getCerts();
 
   caTreeView = Cc["@mozilla.org/security/nsCertTree;1"].createInstance(
     Ci.nsICertTree
   );
@@ -161,17 +188,19 @@ function LoadCerts() {
   document.getElementById("user-tree").view = userTreeView;
 
   clientAuthRememberService = Cc[
     "@mozilla.org/security/clientAuthRememberService;1"
   ].getService(Ci.nsIClientAuthRememberService);
 
   richlist = document.getElementById("rememberedList");
 
-  rememberedDecisionsRichList.buildRichList();
+  await rememberedDecisionsRichList.buildRichList();
+
+  rememberedDecisionsRichList.setButtonState();
 
   enableBackupAllButton();
 }
 
 function enableBackupAllButton() {
   let backupAllButton = document.getElementById("mine_backupAllButton");
   backupAllButton.disabled = userTreeView.rowCount < 1;
 }
--- a/security/manager/ssl/DataStorageList.h
+++ b/security/manager/ssl/DataStorageList.h
@@ -9,11 +9,12 @@
 // storage in the profile directory.
 //
 // Please note that it is crucial for performance reasons for the number of
 // these classes to remain low.  If you need to add to this list, you may
 // need to update the algorithm in DataStorage::SetCachedStorageEntries()
 // to something faster.
 
 DATA_STORAGE(AlternateServices)
+DATA_STORAGE(ClientAuthRememberList)
 DATA_STORAGE(SecurityPreloadState)
 DATA_STORAGE(SiteSecurityServiceState)
 DATA_STORAGE(TRRBlacklist)
--- a/security/manager/ssl/nsClientAuthRemember.cpp
+++ b/security/manager/ssl/nsClientAuthRemember.cpp
@@ -2,38 +2,43 @@
  *
  * 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 "mozilla/BasePrincipal.h"
+#include "mozilla/DataStorage.h"
 #include "mozilla/RefPtr.h"
 #include "nsCRT.h"
 #include "nsNSSCertHelper.h"
 #include "nsIObserverService.h"
 #include "nsNetUtil.h"
 #include "nsPromiseFlatString.h"
 #include "nsThreadUtils.h"
 #include "nsStringBuffer.h"
 #include "cert.h"
 #include "nspr.h"
 #include "pk11pub.h"
 #include "certdb.h"
 #include "sechash.h"
 #include "SharedSSLState.h"
 
+#include "nsJSUtils.h"
+
 using namespace mozilla;
 using namespace mozilla::psm;
 
-NS_IMPL_ISUPPORTS(nsClientAuthRememberService, nsIClientAuthRememberService,
-                  nsIObserver)
+NS_IMPL_ISUPPORTS(nsClientAuthRememberService, nsIClientAuthRememberService)
 NS_IMPL_ISUPPORTS(nsClientAuthRemember, nsIClientAuthRememberRecord)
 
+const nsCString nsClientAuthRemember::SentinelValue =
+    "no client certificate"_ns;
+
 NS_IMETHODIMP
 nsClientAuthRemember::GetAsciiHost(/*out*/ nsACString& aAsciiHost) {
   aAsciiHost = mAsciiHost;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsClientAuthRemember::GetFingerprint(/*out*/ nsACString& aFingerprint) {
@@ -48,104 +53,95 @@ nsClientAuthRemember::GetDbKey(/*out*/ n
 }
 
 NS_IMETHODIMP
 nsClientAuthRemember::GetEntryKey(/*out*/ nsACString& aEntryKey) {
   aEntryKey = mEntryKey;
   return NS_OK;
 }
 
-nsClientAuthRememberService::nsClientAuthRememberService()
-    : monitor("nsClientAuthRememberService.monitor") {}
-
-nsClientAuthRememberService::~nsClientAuthRememberService() {
-  RemoveAllFromMemory();
-}
-
 nsresult nsClientAuthRememberService::Init() {
   if (!NS_IsMainThread()) {
     NS_ERROR("nsClientAuthRememberService::Init called off the main thread");
     return NS_ERROR_NOT_SAME_THREAD;
   }
 
-  nsCOMPtr<nsIObserverService> observerService =
-      mozilla::services::GetObserverService();
-  if (observerService) {
-    observerService->AddObserver(this, "profile-before-change", false);
-    observerService->AddObserver(this, "last-pb-context-exited", false);
+  mClientAuthRememberList =
+      mozilla::DataStorage::Get(DataStorageClass::ClientAuthRememberList);
+  nsresult rv = mClientAuthRememberList->Init(nullptr);
+
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsClientAuthRememberService::ForgetRememberedDecision(const nsACString& key) {
-  {
-    ReentrantMonitorAutoEnter lock(monitor);
-    mSettingsTable.RemoveEntry(PromiseFlatCString(key).get());
-  }
+  mClientAuthRememberList->Remove(PromiseFlatCString(key),
+                                  mozilla::DataStorage_Persistent);
 
   nsNSSComponent::ClearSSLExternalAndInternalSessionCacheNative();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsClientAuthRememberService::GetDecisions(
     nsTArray<RefPtr<nsIClientAuthRememberRecord>>& results) {
-  ReentrantMonitorAutoEnter lock(monitor);
-  for (auto iter = mSettingsTable.Iter(); !iter.Done(); iter.Next()) {
-    if (!nsClientAuthRememberService::IsPrivateBrowsingKey(
-            iter.Get()->mEntryKey)) {
-      results.AppendElement(iter.Get()->mSettings);
+  nsTArray<mozilla::psm::DataStorageItem> decisions;
+  mClientAuthRememberList->GetAll(&decisions);
+
+  for (const mozilla::psm::DataStorageItem& decision : decisions) {
+    if (decision.type() == DataStorageType::DataStorage_Persistent) {
+      RefPtr<nsIClientAuthRememberRecord> tmp =
+          new nsClientAuthRemember(decision.key(), decision.value());
+
+      results.AppendElement(tmp);
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsClientAuthRememberService::Observe(nsISupports* aSubject, const char* aTopic,
-                                     const char16_t* aData) {
-  // check the topic
-  if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
-    // The profile is about to change,
-    // or is going away because the application is shutting down.
-
-    ReentrantMonitorAutoEnter lock(monitor);
-    RemoveAllFromMemory();
-  } else if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) {
-    ReentrantMonitorAutoEnter lock(monitor);
-    ClearPrivateDecisions();
-  }
-
+nsClientAuthRememberService::ClearRememberedDecisions() {
+  mClientAuthRememberList->Clear();
+  nsNSSComponent::ClearSSLExternalAndInternalSessionCacheNative();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsClientAuthRememberService::ClearRememberedDecisions() {
-  ReentrantMonitorAutoEnter lock(monitor);
-  RemoveAllFromMemory();
-  return NS_OK;
-}
+nsClientAuthRememberService::DeleteDecisionsByHost(
+    const nsACString& aHostName, JS::Handle<JS::Value> aOriginAttributes,
+    JSContext* aCx) {
+  OriginAttributes attrs;
+  if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+  DataStorageType storageType = GetDataStorageType(attrs);
 
-nsresult nsClientAuthRememberService::ClearPrivateDecisions() {
-  ReentrantMonitorAutoEnter lock(monitor);
-  for (auto iter = mSettingsTable.Iter(); !iter.Done(); iter.Next()) {
-    if (nsClientAuthRememberService::IsPrivateBrowsingKey(
-            iter.Get()->mEntryKey)) {
-      iter.Remove();
+  nsTArray<mozilla::psm::DataStorageItem> decisions;
+  mClientAuthRememberList->GetAll(&decisions);
+
+  for (const mozilla::psm::DataStorageItem& decision : decisions) {
+    if (decision.type() == storageType) {
+      RefPtr<nsIClientAuthRememberRecord> tmp =
+          new nsClientAuthRemember(decision.key(), decision.value());
+      nsAutoCString asciiHost;
+      tmp->GetAsciiHost(asciiHost);
+      if (asciiHost.Equals(aHostName)) {
+        mClientAuthRememberList->Remove(decision.key(), decision.type());
+      }
     }
   }
+  nsNSSComponent::ClearSSLExternalAndInternalSessionCacheNative();
   return NS_OK;
 }
 
-void nsClientAuthRememberService::RemoveAllFromMemory() {
-  mSettingsTable.Clear();
-}
-
 NS_IMETHODIMP
 nsClientAuthRememberService::RememberDecision(
     const nsACString& aHostName, const OriginAttributes& 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()) {
@@ -153,101 +149,106 @@ nsClientAuthRememberService::RememberDec
   }
 
   nsAutoCString fpStr;
   nsresult rv = GetCertFingerprintByOidTag(aServerCert, SEC_OID_SHA256, fpStr);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  {
-    ReentrantMonitorAutoEnter lock(monitor);
-    if (aClientCert) {
-      RefPtr<nsNSSCertificate> pipCert(new nsNSSCertificate(aClientCert));
-      nsAutoCString dbkey;
-      rv = pipCert->GetDbKey(dbkey);
-      if (NS_SUCCEEDED(rv)) {
-        AddEntryToList(aHostName, aOriginAttributes, fpStr, dbkey);
-      }
-    } else {
-      nsCString empty;
-      AddEntryToList(aHostName, aOriginAttributes, fpStr, empty);
+  if (aClientCert) {
+    RefPtr<nsNSSCertificate> pipCert(new nsNSSCertificate(aClientCert));
+    nsAutoCString dbkey;
+    rv = pipCert->GetDbKey(dbkey);
+    if (NS_SUCCEEDED(rv)) {
+      AddEntryToList(aHostName, aOriginAttributes, fpStr, dbkey);
     }
+  } else {
+    AddEntryToList(aHostName, aOriginAttributes, fpStr,
+                   nsClientAuthRemember::SentinelValue);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsClientAuthRememberService::HasRememberedDecision(
     const nsACString& aHostName, const OriginAttributes& aOriginAttributes,
     CERTCertificate* aCert, nsACString& aCertDBKey, bool* aRetVal) {
   if (aHostName.IsEmpty()) return NS_ERROR_INVALID_ARG;
 
   NS_ENSURE_ARG_POINTER(aCert);
   NS_ENSURE_ARG_POINTER(aRetVal);
   *aRetVal = false;
+  aCertDBKey.Truncate();
 
   nsresult rv;
   nsAutoCString fpStr;
   rv = GetCertFingerprintByOidTag(aCert, SEC_OID_SHA256, fpStr);
   if (NS_FAILED(rv)) return rv;
 
   nsAutoCString entryKey;
   GetEntryKey(aHostName, aOriginAttributes, fpStr, entryKey);
-  {
-    ReentrantMonitorAutoEnter lock(monitor);
-    nsClientAuthRememberEntry* entry = mSettingsTable.GetEntry(entryKey.get());
-    if (!entry) return NS_OK;
-    entry->mSettings->GetDbKey(aCertDBKey);
-    *aRetVal = true;
+  DataStorageType storageType = GetDataStorageType(aOriginAttributes);
+
+  nsCString listEntry = mClientAuthRememberList->Get(entryKey, storageType);
+  if (listEntry.IsEmpty()) {
+    return NS_OK;
   }
+
+  if (!listEntry.Equals(nsClientAuthRemember::SentinelValue)) {
+    aCertDBKey = listEntry;
+  }
+  *aRetVal = true;
+
   return NS_OK;
 }
 
 nsresult nsClientAuthRememberService::AddEntryToList(
     const nsACString& aHostName, const OriginAttributes& aOriginAttributes,
     const nsACString& aFingerprint, const nsACString& aDBKey) {
   nsAutoCString entryKey;
   GetEntryKey(aHostName, aOriginAttributes, aFingerprint, entryKey);
-
-  {
-    ReentrantMonitorAutoEnter lock(monitor);
-    nsClientAuthRememberEntry* entry = mSettingsTable.PutEntry(entryKey.get());
+  DataStorageType storageType = GetDataStorageType(aOriginAttributes);
 
-    if (!entry) {
-      NS_ERROR("can't insert a null entry!");
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    entry->mEntryKey = entryKey;
-
-    entry->mSettings =
-        new nsClientAuthRemember(aHostName, aFingerprint, aDBKey, entryKey);
+  nsCString tmpDbKey(aDBKey);
+  nsresult rv = mClientAuthRememberList->Put(entryKey, tmpDbKey, storageType);
+  if (NS_FAILED(rv)) {
+    return rv;
   }
 
   return NS_OK;
 }
 
 void nsClientAuthRememberService::GetEntryKey(
     const nsACString& aHostName, const OriginAttributes& aOriginAttributes,
     const nsACString& aFingerprint, nsACString& aEntryKey) {
   nsAutoCString hostCert(aHostName);
+  hostCert.Append(',');
+  hostCert.Append(aFingerprint);
+  hostCert.Append(',');
+
   nsAutoCString suffix;
   aOriginAttributes.CreateSuffix(suffix);
   hostCert.Append(suffix);
-  hostCert.Append(':');
-  hostCert.Append(aFingerprint);
 
   aEntryKey.Assign(hostCert);
 }
 
 bool nsClientAuthRememberService::IsPrivateBrowsingKey(
     const nsCString& entryKey) {
   const int32_t separator = entryKey.Find(":", false, 0, -1);
   nsCString suffix;
   if (separator >= 0) {
     entryKey.Left(suffix, separator);
   } else {
     suffix = entryKey;
   }
   return OriginAttributes::IsPrivateBrowsing(suffix);
 }
+
+DataStorageType nsClientAuthRememberService::GetDataStorageType(
+    const OriginAttributes& aOriginAttributes) {
+  if (aOriginAttributes.mPrivateBrowsingId > 0) {
+    return DataStorage_Private;
+  }
+  return DataStorage_Persistent;
+}
--- a/security/manager/ssl/nsClientAuthRemember.h
+++ b/security/manager/ssl/nsClientAuthRemember.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __NSCLIENTAUTHREMEMBER_H__
 #define __NSCLIENTAUTHREMEMBER_H__
 
 #include <utility>
 
 #include "mozilla/Attributes.h"
+#include "mozilla/DataStorage.h"
 #include "mozilla/HashFunctions.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "nsIClientAuthRememberService.h"
 #include "nsIObserver.h"
 #include "nsNSSCertificate.h"
 #include "nsString.h"
 #include "nsTHashtable.h"
 #include "nsWeakReference.h"
@@ -25,103 +26,66 @@ class OriginAttributes;
 
 using mozilla::OriginAttributes;
 
 class nsClientAuthRemember final : public nsIClientAuthRememberRecord {
  public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSICLIENTAUTHREMEMBERRECORD
 
-  nsClientAuthRemember(const nsACString& aAsciiHost,
-                       const nsACString& aFingerprint, const nsACString& aDBKey,
-                       const nsACString& aEntryKey) {
-    mAsciiHost = aAsciiHost;
-    mFingerprint = aFingerprint;
-    mDBKey = aDBKey;
+  nsClientAuthRemember(const nsCString& aEntryKey, const nsCString& aDBKey) {
     mEntryKey = aEntryKey;
+    if (!aDBKey.Equals(nsClientAuthRemember::SentinelValue)) {
+      mDBKey = aDBKey;
+    }
+
+    nsTArray<nsCString*> fields = {&mAsciiHost, &mFingerprint};
+
+    auto fieldsIter = fields.begin();
+    auto splitter = aEntryKey.Split(',');
+    auto splitterIter = splitter.begin();
+    for (; fieldsIter != fields.end() && splitterIter != splitter.end();
+         ++fieldsIter, ++splitterIter) {
+      (*fieldsIter)->Assign(*splitterIter);
+    }
   }
 
   nsCString mAsciiHost;
   nsCString mFingerprint;
   nsCString mDBKey;
   nsCString mEntryKey;
+  static const nsCString SentinelValue;
 
  protected:
   ~nsClientAuthRemember() = default;
 };
 
-// hash entry class
-class nsClientAuthRememberEntry final : public PLDHashEntryHdr {
- public:
-  // Hash methods
-  typedef const char* KeyType;
-  typedef const char* KeyTypePointer;
-
-  // do nothing with aHost - we require mHead to be set before we're live!
-  explicit nsClientAuthRememberEntry(KeyTypePointer aHostWithCertUTF8) {}
-
-  nsClientAuthRememberEntry(nsClientAuthRememberEntry&& aToMove)
-      : PLDHashEntryHdr(std::move(aToMove)),
-        mSettings(std::move(aToMove.mSettings)),
-        mEntryKey(std::move(aToMove.mEntryKey)) {}
-
-  ~nsClientAuthRememberEntry() = default;
-
-  KeyType GetKey() const { return EntryKeyPtr(); }
-
-  KeyTypePointer GetKeyPointer() const { return EntryKeyPtr(); }
-
-  bool KeyEquals(KeyTypePointer aKey) const {
-    return !strcmp(EntryKeyPtr(), aKey);
-  }
-
-  static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
-
-  static PLDHashNumber HashKey(KeyTypePointer aKey) {
-    return mozilla::HashString(aKey);
-  }
-
-  enum { ALLOW_MEMMOVE = false };
-
-  // get methods
-  inline const nsCString& GetEntryKey() const { return mEntryKey; }
-
-  inline KeyTypePointer EntryKeyPtr() const { return mEntryKey.get(); }
-
-  nsCOMPtr<nsIClientAuthRememberRecord> mSettings;
-  nsCString mEntryKey;
-};
-
-class nsClientAuthRememberService final : public nsIObserver,
-                                          public nsIClientAuthRememberService {
+class nsClientAuthRememberService final : public nsIClientAuthRememberService {
  public:
   NS_DECL_THREADSAFE_ISUPPORTS
-  NS_DECL_NSIOBSERVER
   NS_DECL_NSICLIENTAUTHREMEMBERSERVICE
 
-  nsClientAuthRememberService();
+  nsClientAuthRememberService() = default;
 
   nsresult Init();
 
   static void GetEntryKey(const nsACString& aHostName,
                           const OriginAttributes& aOriginAttributes,
                           const nsACString& aFingerprint,
                           /*out*/ nsACString& aEntryKey);
 
   static bool IsPrivateBrowsingKey(const nsCString& entryKey);
 
  protected:
-  ~nsClientAuthRememberService();
+  ~nsClientAuthRememberService() = default;
 
-  mozilla::ReentrantMonitor monitor;
-  nsTHashtable<nsClientAuthRememberEntry> mSettingsTable;
+  static mozilla::DataStorageType GetDataStorageType(
+      const OriginAttributes& aOriginAttributes);
 
-  void RemoveAllFromMemory();
-
-  nsresult ClearPrivateDecisions();
+  RefPtr<mozilla::DataStorage> mClientAuthRememberList;
 
   nsresult AddEntryToList(const nsACString& aHost,
                           const OriginAttributes& aOriginAttributes,
                           const nsACString& aServerFingerprint,
                           const nsACString& aDBKey);
 };
 
 #endif
--- a/security/manager/ssl/nsIClientAuthRememberService.idl
+++ b/security/manager/ssl/nsIClientAuthRememberService.idl
@@ -49,9 +49,14 @@ interface nsIClientAuthRememberService :
   [must_use, noscript]
   bool hasRememberedDecision(in ACString aHostName,
                              in const_OriginAttributesRef aOriginAttributes,
                              in CERTCertificatePtr aServerCert,
                              out ACString aCertDBKey);
 
   [must_use]
   void clearRememberedDecisions();
+
+  [implicit_jscontext]
+  void deleteDecisionsByHost(in ACString aHostName,
+                             in jsval aOriginAttributes);
+
 };
--- a/security/manager/ssl/nsNSSComponent.cpp
+++ b/security/manager/ssl/nsNSSComponent.cpp
@@ -2483,24 +2483,17 @@ nsresult nsNSSComponent::GetNewPrompter(
 
 nsresult nsNSSComponent::LogoutAuthenticatedPK11() {
   nsCOMPtr<nsICertOverrideService> icos =
       do_GetService("@mozilla.org/security/certoverride;1");
   if (icos) {
     icos->ClearValidityOverride("all:temporary-certificates"_ns, 0);
   }
 
-  nsCOMPtr<nsIClientAuthRememberService> svc =
-      do_GetService(NS_CLIENTAUTHREMEMBERSERVICE_CONTRACTID);
-
-  if (svc) {
-    nsresult rv = svc->ClearRememberedDecisions();
-
-    Unused << NS_WARN_IF(NS_FAILED(rv));
-  }
+  nsNSSComponent::ClearSSLExternalAndInternalSessionCacheNative();
 
   nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
   if (os) {
     os->NotifyObservers(nullptr, "net:cancel-all-connections", nullptr);
   }
 
   return NS_OK;
 }
--- a/security/manager/ssl/nsNSSIOLayer.cpp
+++ b/security/manager/ssl/nsNSSIOLayer.cpp
@@ -2337,17 +2337,22 @@ void ClientAuthDataRunnable::RunOnTarget
     nsCString rememberedDBKey;
     bool found;
     nsresult rv =
         cars->HasRememberedDecision(hostname, mInfo.OriginAttributesRef(),
                                     mServerCert, rememberedDBKey, &found);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return;
     }
-    if (found && !rememberedDBKey.IsEmpty()) {
+    if (found) {
+      // An empty dbKey indicates that the user chose not to use a certificate
+      // and chose to remember this decision
+      if (rememberedDBKey.IsEmpty()) {
+        return;
+      }
       nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
       if (NS_WARN_IF(!certdb)) {
         return;
       }
       nsCOMPtr<nsIX509Cert> foundCert;
       nsresult rv =
           certdb->FindCertByDBKey(rememberedDBKey, getter_AddRefs(foundCert));
       if (NS_WARN_IF(NS_FAILED(rv))) {
--- a/security/manager/ssl/tests/mochitest/browser/browser_clientAuthRememberService.js
+++ b/security/manager/ssl/tests/mochitest/browser/browser_clientAuthRememberService.js
@@ -6,16 +6,17 @@
 /**
  * Test certificate (i.e. build/pgo/certs/mochitest.client).
  * @type nsIX509Cert
  */
 var cert;
 var cert2;
 var cert3;
 
+var sdr = Cc["@mozilla.org/security/sdr;1"].getService(Ci.nsISecretDecoderRing);
 var certDB = Cc["@mozilla.org/security/x509certdb;1"].getService(
   Ci.nsIX509CertDB
 );
 
 var deleted = false;
 
 const { MockRegistrar } = ChromeUtils.import(
   "resource://testing-common/MockRegistrar.jsm"
@@ -25,16 +26,61 @@ function findCertByCommonName(commonName
   for (let cert of certDB.getCerts()) {
     if (cert.commonName == commonName) {
       return cert;
     }
   }
   return null;
 }
 
+async function testHelper(connectURL, expectedURL) {
+  let win = await BrowserTestUtils.openNewBrowserWindow();
+
+  await SpecialPowers.pushPrefEnv({
+    set: [["security.default_personal_cert", "Ask Every Time"]],
+  });
+
+  await BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, connectURL);
+
+  await BrowserTestUtils.browserLoaded(
+    win.gBrowser.selectedBrowser,
+    false,
+    expectedURL,
+    true
+  );
+  let loadedURL = win.gBrowser.selectedBrowser.documentURI.spec;
+  Assert.ok(
+    loadedURL.startsWith(expectedURL),
+    `Expected and actual URLs should match (got '${loadedURL}', expected '${expectedURL}')`
+  );
+
+  await win.close();
+
+  // This clears the TLS session cache so we don't use a previously-established
+  // ticket to connect and bypass selecting a client auth certificate in
+  // subsequent tests.
+  sdr.logout();
+}
+
+async function openRequireClientCert() {
+  gClientAuthDialogs.chooseCertificateCalled = false;
+  await testHelper(
+    "https://requireclientcert.example.com:443",
+    "https://requireclientcert.example.com/"
+  );
+}
+
+async function openRequireClientCert2() {
+  gClientAuthDialogs.chooseCertificateCalled = false;
+  await testHelper(
+    "https://requireclientcert-2.example.com:443",
+    "https://requireclientcert-2.example.com/"
+  );
+}
+
 // Mock implementation of nsIClientAuthRememberService
 const gClientAuthRememberService = {
   forgetRememberedDecision(key) {
     deleted = true;
     Assert.equal(
       key,
       "exampleKey2",
       "Expected to get the same key that was passed in getDecisions()"
@@ -59,33 +105,58 @@ const gClientAuthRememberService = {
         entryKey: "exampleKey3",
       },
     ];
   },
 
   QueryInterface: ChromeUtils.generateQI(["nsIClientAuthRememberService"]),
 };
 
+const gClientAuthDialogs = {
+  _chooseCertificateCalled: false,
+
+  get chooseCertificateCalled() {
+    return this._chooseCertificateCalled;
+  },
+
+  set chooseCertificateCalled(value) {
+    this._chooseCertificateCalled = value;
+  },
+
+  chooseCertificate(
+    hostname,
+    port,
+    organization,
+    issuerOrg,
+    certList,
+    selectedIndex,
+    rememberClientAuthCertificate
+  ) {
+    rememberClientAuthCertificate.value = true;
+    this.chooseCertificateCalled = true;
+    selectedIndex.value = 0;
+    return true;
+  },
+
+  QueryInterface: ChromeUtils.generateQI([Ci.nsIClientAuthDialogs]),
+};
+
 add_task(async function testRememberedDecisionsUI() {
   cert = findCertByCommonName("Mochitest client");
   cert2 = await readCertificate("pgo-ca-all-usages.pem", ",,");
   cert3 = await readCertificate("client-cert-via-intermediate.pem", ",,");
   isnot(cert, null, "Should be able to find the test client cert");
   isnot(cert2, null, "Should be able to find pgo-ca-all-usages.pem");
   isnot(cert3, null, "Should be able to find client-cert-via-intermediate.pem");
 
   let clientAuthRememberServiceCID = MockRegistrar.register(
     "@mozilla.org/security/clientAuthRememberService;1",
     gClientAuthRememberService
   );
 
-  registerCleanupFunction(() => {
-    MockRegistrar.unregister(clientAuthRememberServiceCID);
-  });
-
   let win = await openCertManager();
 
   let listItems = win.document
     .getElementById("rememberedList")
     .querySelectorAll("richlistitem");
 
   Assert.equal(
     listItems.length,
@@ -131,9 +202,56 @@ add_task(async function testRememberedDe
   win.document.getElementById("rememberedList").selectedIndex = 1;
 
   win.document.getElementById("remembered_deleteButton").click();
 
   Assert.ok(deleted, "Expected forgetRememberedDecision() to get called");
 
   win.document.getElementById("certmanager").acceptDialog();
   await BrowserTestUtils.windowClosed(win);
+
+  MockRegistrar.unregister(clientAuthRememberServiceCID);
 });
+
+add_task(async function testDeletingRememberedDecisions() {
+  let clientAuthDialogsCID = MockRegistrar.register(
+    "@mozilla.org/nsClientAuthDialogs;1",
+    gClientAuthDialogs
+  );
+  let cars = Cc["@mozilla.org/security/clientAuthRememberService;1"].getService(
+    Ci.nsIClientAuthRememberService
+  );
+
+  await openRequireClientCert();
+  Assert.ok(
+    gClientAuthDialogs.chooseCertificateCalled,
+    "chooseCertificate should have been called if visiting 'requireclientcert.example.com' for the first time"
+  );
+
+  await openRequireClientCert();
+  Assert.ok(
+    !gClientAuthDialogs.chooseCertificateCalled,
+    "chooseCertificate should not have been called if visiting 'requireclientcert.example.com' for the second time"
+  );
+
+  await openRequireClientCert2();
+  Assert.ok(
+    gClientAuthDialogs.chooseCertificateCalled,
+    "chooseCertificate should have been called if visiting'requireclientcert-2.example.com' for the first time"
+  );
+
+  let originAttributes = { privateBrowsingId: 0 };
+  cars.deleteDecisionsByHost("requireclientcert.example.com", originAttributes);
+
+  await openRequireClientCert();
+  Assert.ok(
+    gClientAuthDialogs.chooseCertificateCalled,
+    "chooseCertificate should have been called after removing all remembered decisions for 'requireclientcert.example.com'"
+  );
+
+  await openRequireClientCert2();
+  Assert.ok(
+    !gClientAuthDialogs.chooseCertificateCalled,
+    "chooseCertificate should not have been called if visiting 'requireclientcert-2.example.com' for the second time"
+  );
+
+  MockRegistrar.unregister(clientAuthDialogsCID);
+});
--- a/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_connection.js
+++ b/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_connection.js
@@ -16,16 +16,19 @@ const DialogState = {
   ASSERT_NOT_CALLED: "ASSERT_NOT_CALLED",
   // Return that the user selected the first given cert.
   RETURN_CERT_SELECTED: "RETURN_CERT_SELECTED",
   // Return that the user canceled.
   RETURN_CERT_NOT_SELECTED: "RETURN_CERT_NOT_SELECTED",
 };
 
 var sdr = Cc["@mozilla.org/security/sdr;1"].getService(Ci.nsISecretDecoderRing);
+let cars = Cc["@mozilla.org/security/clientAuthRememberService;1"].getService(
+  Ci.nsIClientAuthRememberService
+);
 
 var gExpectedClientCertificateChoices;
 
 // Mock implementation of nsIClientAuthDialogs.
 const gClientAuthDialogs = {
   _state: DialogState.ASSERT_NOT_CALLED,
   _rememberClientAuthCertificate: false,
   _chooseCertificateCalled: false,
@@ -155,20 +158,27 @@ add_task(async function setup() {
  * Test helper for the tests below.
  *
  * @param {String} prefValue
  *        Value to set the "security.default_personal_cert" pref to.
  * @param {String} expectedURL
  *        If the connection is expected to load successfully, the URL that
  *        should load. If the connection is expected to fail and result in an
  *        error page, |undefined|.
+ * @param {Boolean} expectCallingChooseCertificate
+ *        Determines whether we expect chooseCertificate to be called.
  * @param {Object} options
  *        Optional options object to pass on to the window that gets opened.
  */
-async function testHelper(prefValue, expectedURL, options = undefined) {
+async function testHelper(
+  prefValue,
+  expectedURL,
+  expectCallingChooseCertificate,
+  options = undefined
+) {
   gClientAuthDialogs.chooseCertificateCalled = false;
   await SpecialPowers.pushPrefEnv({
     set: [["security.default_personal_cert", prefValue]],
   });
 
   let win = await BrowserTestUtils.openNewBrowserWindow(options);
 
   await BrowserTestUtils.loadURI(
@@ -184,17 +194,17 @@ async function testHelper(prefValue, exp
   );
   let loadedURL = win.gBrowser.selectedBrowser.documentURI.spec;
   Assert.ok(
     loadedURL.startsWith(expectedURL),
     `Expected and actual URLs should match (got '${loadedURL}', expected '${expectedURL}')`
   );
   Assert.equal(
     gClientAuthDialogs.chooseCertificateCalled,
-    prefValue == "Ask Every Time",
+    expectCallingChooseCertificate,
     "chooseCertificate should have been called if we were expecting it to be called"
   );
 
   await win.close();
 
   // This clears the TLS session cache so we don't use a previously-established
   // ticket to connect and bypass selecting a client auth certificate in
   // subsequent tests.
@@ -202,64 +212,101 @@ async function testHelper(prefValue, exp
 }
 
 // Test that if a certificate is chosen automatically the connection succeeds,
 // and that nsIClientAuthDialogs.chooseCertificate() is never called.
 add_task(async function testCertChosenAutomatically() {
   gClientAuthDialogs.state = DialogState.ASSERT_NOT_CALLED;
   await testHelper(
     "Select Automatically",
-    "https://requireclientcert.example.com/"
+    "https://requireclientcert.example.com/",
+    false
   );
   // This clears all saved client auth certificate state so we don't influence
   // subsequent tests.
-  sdr.logoutAndTeardown();
+  cars.clearRememberedDecisions();
 });
 
 // Test that if the user doesn't choose a certificate, the connection fails and
 // an error page is displayed.
 add_task(async function testCertNotChosenByUser() {
   gClientAuthDialogs.state = DialogState.RETURN_CERT_NOT_SELECTED;
   await testHelper(
     "Ask Every Time",
-    "about:neterror?e=nssFailure2&u=https%3A//requireclientcert.example.com/"
+    "about:neterror?e=nssFailure2&u=https%3A//requireclientcert.example.com/",
+    true
   );
-  sdr.logoutAndTeardown();
+  cars.clearRememberedDecisions();
 });
 
 // Test that if the user chooses a certificate the connection suceeeds.
 add_task(async function testCertChosenByUser() {
   gClientAuthDialogs.state = DialogState.RETURN_CERT_SELECTED;
-  await testHelper("Ask Every Time", "https://requireclientcert.example.com/");
-  sdr.logoutAndTeardown();
+  await testHelper(
+    "Ask Every Time",
+    "https://requireclientcert.example.com/",
+    true
+  );
+  cars.clearRememberedDecisions();
+});
+
+// Test that the cancel decision is remembered correctly
+add_task(async function testEmptyCertChosenByUser() {
+  gClientAuthDialogs.state = DialogState.RETURN_CERT_NOT_SELECTED;
+  gClientAuthDialogs.rememberClientAuthCertificate = true;
+  await testHelper(
+    "Ask Every Time",
+    "about:neterror?e=nssFailure2&u=https%3A//requireclientcert.example.com/",
+    true
+  );
+  await testHelper(
+    "Ask Every Time",
+    "about:neterror?e=nssFailure2&u=https%3A//requireclientcert.example.com/",
+    false
+  );
+  cars.clearRememberedDecisions();
 });
 
 // Test that if the user chooses a certificate in a private browsing window,
 // configures Firefox to remember this certificate for the duration of the
 // session, closes that window (and thus all private windows), reopens a private
 // window, and visits that site again, they are re-asked for a certificate (i.e.
 // any state from the previous private session should be gone). Similarly, after
 // closing that private window, if the user opens a non-private window, they
 // again should be asked to choose a certificate (i.e. private state should not
 // be remembered/used in non-private contexts).
 add_task(async function testClearPrivateBrowsingState() {
   gClientAuthDialogs.rememberClientAuthCertificate = true;
   gClientAuthDialogs.state = DialogState.RETURN_CERT_SELECTED;
-  await testHelper("Ask Every Time", "https://requireclientcert.example.com/", {
-    private: true,
-  });
-  await testHelper("Ask Every Time", "https://requireclientcert.example.com/", {
-    private: true,
-  });
-  await testHelper("Ask Every Time", "https://requireclientcert.example.com/");
-  // NB: we don't `sdr.logoutAndTeardown()` in between the two calls to
+  await testHelper(
+    "Ask Every Time",
+    "https://requireclientcert.example.com/",
+    true,
+    {
+      private: true,
+    }
+  );
+  await testHelper(
+    "Ask Every Time",
+    "https://requireclientcert.example.com/",
+    true,
+    {
+      private: true,
+    }
+  );
+  await testHelper(
+    "Ask Every Time",
+    "https://requireclientcert.example.com/",
+    true
+  );
+  // NB: we don't `cars.clearRememberedDecisions()` in between the two calls to
   // `testHelper` because that would clear all client auth certificate state and
   // obscure what we're testing (that Firefox properly clears the relevant state
   // when the last private window closes).
-  sdr.logoutAndTeardown();
+  cars.clearRememberedDecisions();
 });
 
 // Test that 3rd party certificates are taken into account when filtering client
 // certificates based on the acceptible CA list sent by the server.
 add_task(async function testCertFilteringWithIntermediate() {
   let intermediateBytes = await OS.File.read(
     getTestFilePath("intermediate.pem")
   ).then(
@@ -277,15 +324,19 @@ add_task(async function testCertFilterin
     error => {
       throw error;
     }
   );
   let nssComponent = Cc["@mozilla.org/psm;1"].getService(Ci.nsINSSComponent);
   nssComponent.addEnterpriseIntermediate(intermediateBytes);
   gExpectedClientCertificateChoices = 4;
   gClientAuthDialogs.state = DialogState.RETURN_CERT_SELECTED;
-  await testHelper("Ask Every Time", "https://requireclientcert.example.com/");
-  sdr.logoutAndTeardown();
+  await testHelper(
+    "Ask Every Time",
+    "https://requireclientcert.example.com/",
+    true
+  );
+  cars.clearRememberedDecisions();
   // This will reset the added intermediate.
   await SpecialPowers.pushPrefEnv({
     set: [["security.enterprise_roots.enabled", true]],
   });
 });
--- a/security/manager/ssl/tests/unit/head_psm.js
+++ b/security/manager/ssl/tests/unit/head_psm.js
@@ -25,16 +25,17 @@ const { XPCOMUtils } = ChromeUtils.impor
 const { X509 } = ChromeUtils.import("resource://gre/modules/psm/X509.jsm");
 
 const isDebugBuild = Cc["@mozilla.org/xpcom/debug;1"].getService(Ci.nsIDebug2)
   .isDebugBuild;
 
 // The test EV roots are only enabled in debug builds as a security measure.
 const gEVExpected = isDebugBuild;
 
+const CLIENT_AUTH_FILE_NAME = "ClientAuthRememberList.txt";
 const SSS_STATE_FILE_NAME = "SiteSecurityServiceState.txt";
 const PRELOAD_STATE_FILE_NAME = "SecurityPreloadState.txt";
 
 const SEC_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SEC_ERROR_BASE;
 const SSL_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SSL_ERROR_BASE;
 const MOZILLA_PKIX_ERROR_BASE = Ci.nsINSSErrorsService.MOZILLA_PKIX_ERROR_BASE;
 
 // This isn't really a valid PRErrorCode, but is useful for signalling that
--- a/security/manager/ssl/tests/unit/test_sss_eviction.js
+++ b/security/manager/ssl/tests/unit/test_sss_eviction.js
@@ -5,17 +5,17 @@
 
 // The purpose of this test is to check that a frequently visited site
 // will not be evicted over an infrequently visited site.
 
 var gSSService = null;
 var gProfileDir = null;
 
 function do_state_written(aSubject, aTopic, aData) {
-  if (aData == PRELOAD_STATE_FILE_NAME) {
+  if (aData == PRELOAD_STATE_FILE_NAME || aData == CLIENT_AUTH_FILE_NAME) {
     return;
   }
 
   equal(aData, SSS_STATE_FILE_NAME);
 
   let stateFile = gProfileDir.clone();
   stateFile.append(SSS_STATE_FILE_NAME);
   ok(stateFile.exists());
@@ -40,17 +40,17 @@ function do_state_written(aSubject, aTop
     }
   }
 
   ok(foundLegitSite);
   do_test_finished();
 }
 
 function do_state_read(aSubject, aTopic, aData) {
-  if (aData == PRELOAD_STATE_FILE_NAME) {
+  if (aData == PRELOAD_STATE_FILE_NAME || aData == CLIENT_AUTH_FILE_NAME) {
     return;
   }
 
   equal(aData, SSS_STATE_FILE_NAME);
 
   ok(
     gSSService.isSecureURI(
       Ci.nsISiteSecurityService.HEADER_HSTS,
--- a/security/manager/ssl/tests/unit/test_sss_readstate.js
+++ b/security/manager/ssl/tests/unit/test_sss_readstate.js
@@ -4,17 +4,17 @@
 "use strict";
 
 // The purpose of this test is to create a site security service state file
 // and see that the site security service reads it properly.
 
 var gSSService = null;
 
 function checkStateRead(aSubject, aTopic, aData) {
-  if (aData == PRELOAD_STATE_FILE_NAME) {
+  if (aData == PRELOAD_STATE_FILE_NAME || aData == CLIENT_AUTH_FILE_NAME) {
     return;
   }
 
   equal(aData, SSS_STATE_FILE_NAME);
 
   ok(
     !gSSService.isSecureURI(
       Ci.nsISiteSecurityService.HEADER_HSTS,
--- a/security/manager/ssl/tests/unit/test_sss_readstate_garbage.js
+++ b/security/manager/ssl/tests/unit/test_sss_readstate_garbage.js
@@ -4,17 +4,17 @@
 "use strict";
 
 // The purpose of this test is to create a mostly bogus site security service
 // state file and see that the site security service handles it properly.
 
 var gSSService = null;
 
 function checkStateRead(aSubject, aTopic, aData) {
-  if (aData == PRELOAD_STATE_FILE_NAME) {
+  if (aData == PRELOAD_STATE_FILE_NAME || aData == CLIENT_AUTH_FILE_NAME) {
     return;
   }
 
   equal(aData, SSS_STATE_FILE_NAME);
 
   const HSTS_HOSTS = [
     "https://example1.example.com",
     "https://example2.example.com",
--- a/security/manager/ssl/tests/unit/test_sss_readstate_huge.js
+++ b/security/manager/ssl/tests/unit/test_sss_readstate_huge.js
@@ -5,17 +5,17 @@
 
 // The purpose of this test is to create a site security service state file
 // that is too large and see that the site security service reads it properly
 // (this means discarding all entries after the 1024th).
 
 var gSSService = null;
 
 function checkStateRead(aSubject, aTopic, aData) {
-  if (aData == PRELOAD_STATE_FILE_NAME) {
+  if (aData == PRELOAD_STATE_FILE_NAME || aData == CLIENT_AUTH_FILE_NAME) {
     return;
   }
 
   equal(aData, SSS_STATE_FILE_NAME);
 
   ok(
     gSSService.isSecureURI(
       Ci.nsISiteSecurityService.HEADER_HSTS,
--- a/security/manager/ssl/tests/unit/test_sss_savestate.js
+++ b/security/manager/ssl/tests/unit/test_sss_savestate.js
@@ -12,17 +12,17 @@ var gProfileDir = null;
 
 const NON_ISSUED_KEY_HASH = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
 
 // For reference, the format of the state file is a list of:
 // <domain name> <expiration time in milliseconds>,<sts status>,<includeSubdomains>
 // separated by newlines ('\n')
 
 function checkStateWritten(aSubject, aTopic, aData) {
-  if (aData == PRELOAD_STATE_FILE_NAME) {
+  if (aData == PRELOAD_STATE_FILE_NAME || aData == CLIENT_AUTH_FILE_NAME) {
     return;
   }
 
   equal(aData, SSS_STATE_FILE_NAME);
 
   let stateFile = gProfileDir.clone();
   stateFile.append(SSS_STATE_FILE_NAME);
   ok(stateFile.exists());
--- a/toolkit/components/cleardata/ClearDataService.jsm
+++ b/toolkit/components/cleardata/ClearDataService.jsm
@@ -923,29 +923,38 @@ const SecuritySettingsCleaner = {
           sss.resetState(
             Ci.nsISiteSecurityService.HEADER_HSTS,
             uri,
             0,
             entry.originAttributes
           );
         }
       }
+      let cars = Cc[
+        "@mozilla.org/security/clientAuthRememberService;1"
+      ].getService(Ci.nsIClientAuthRememberService);
+
+      cars.deleteDecisionsByHost(aHost, aOriginAttributes);
 
       aResolve();
     });
   },
 
   deleteAll() {
     return new Promise(aResolve => {
       // Clear site security settings - no support for ranges in this
       // interface either, so we clearAll().
       let sss = Cc["@mozilla.org/ssservice;1"].getService(
         Ci.nsISiteSecurityService
       );
       sss.clearAll();
+      let cars = Cc[
+        "@mozilla.org/security/clientAuthRememberService;1"
+      ].getService(Ci.nsIClientAuthRememberService);
+      cars.clearRememberedDecisions();
       aResolve();
     });
   },
 };
 
 const EMECleaner = {
   deleteByHost(aHost, aOriginAttributes) {
     return new Promise(aResolve => {