Bug 634697 - Add permanent storage to user's client certificate selection r=keeler,baku,fluent-reviewers,Gijs
☠☠ backed out by 840f99340069 ☠ ☠
authorMoritz Birghan <mbirghan@mozilla.com>
Wed, 15 Jul 2020 11:49:00 +0000
changeset 540513 928233ea49eeca3dddc25d4cdc59995b17f78092
parent 540512 2532b78b65b9cd8c8b557b86021a51a65cd6447e
child 540514 0bbf0602c3fe5aa75a0026909c317283be116a1b
push id37603
push userccoroiu@mozilla.com
push dateWed, 15 Jul 2020 16:06:28 +0000
treeherdermozilla-central@840f99340069 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskeeler, baku, fluent-reviewers, Gijs
bugs634697
milestone80.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 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
toolkit/components/cleardata/ClearDataService.jsm
index 2fb059f69e2bacef6d8e23a82141f9b9dce846fd..7011091aacc0f0b55288f6bf1de841eeb927c9be
GIT binary patch
literal 229376
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
zA@>VfB>(^b0000000000000000000000000000000000000000000000000000000
z00000000000000000000000000000000000008{|fdWAbzYG`UApL7E{c9)vYpX^u
z!wcBbe{kMLI@em8;E3lXP{}b2HXVIn{{p?0G|y6>;MP)t%BC|iQkYx@-9nmA)FC+I
zd3-9LNegAN*-UnPFDl(!nrWs)(8H(1b7)jk=^PVXf(xFW$)+ZMzr3+D*GPq6gqN<s
zP&&^*oj}C%7_2xRGoH<$>q}?rVY3D7BsM3V9Ydq)N@wd}^`lL3^Q3&&7;R~;Ru_UT
zp334gxNIsq;c)m}q&b>cPOKo_gY52u_|O<!zJ@eM9ouDS8+Z(E8iT7QovVs1&*0Ih
zDGVx~Po*W1Rirt}S_FGMBaO*MSCGu0Gtm_(NwXC72*?kO@5ABH6{Okn*qV|#v;-!f
z!Q;zG=gJxqD0pUaGLwzAg_RjYXY!;6gCJc(Mw{TQ#O8zxViOrOzCVjUkebX;Mo$KZ
z+#H<fmgu0UQdA^L5)BZ!in<7!h3AD^g>!}3!jZxrLJJ`w_jc|f;ag#>&^C9C=$`1P
zXq9M+Xt2mbq$j*2+$Ag*ju8e56>}ft*5%F=rJz*;0000000000000000000000000
z00000000000000000000000000000000000000000000000000000000000000000
z00000z)v$Ec;Kgpl%F<GQ(ZALslHNu?W`uhFuAi1SVm6vuI^)J**x1-DI)bwxRKyl
zwa&>N%b>(B*j;^(@bOiiA^ypfi8hUSYNPFB2{^oMN5yQgT<eZ<t*~6nj&d!qTw+J-
zHOF$zIx1_5<(hO<))>n*>Zq(CmTS;au0EEl*HNx6maEfIt~Qpd)zMaU!E!Y_DyxCz
xs&|yDhUKbul&gZ}DtC0um9SjJj>;-vx$+(5%3-;(9pw_RTp4|Whf;gF{|}%i(BA+6
index 80e69e2f5b691c4464d79613afe3624c3e0a4fdf..d454ed584a747e9c18237d7e75bc834ce92662db
GIT binary patch
literal 294912
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
z0000000000000000000000000000000D%9C(U4P+lBv(ukZ%oyIqb-&$th^bco0E!
zxO>TCK9j_3#C*fO0{{R3000000000000000000000000000000000000000000000
z0000000000000000000000000000000000000000000000002~hoB%QAtnE{AtNUz
zp{0v?LP8#`OA@Uc;}U)R|8zD00000000000000000000000000000000000000000
z0000000000000000000000000000000000000000000000000000000_-{^;JdhS8
zBO{HHq9Q*;LB34{<LBxV;)a$A3UP7s_jShj1?>*N`1xV{Ja(hQoP7g)(7RpzeX(v7
z@rI-*>`NJX6z#7gsaVJk9sKJC4GWpJrVJa3_16t*76xPg5WisDR0t~!`k0I$O5oRi
zIu<Tt{|Jnak269Fp=*V3L%W1{AcE0B!3f;JyeRHp529ybJ&1M<3B&}4BXs>dFn(xs
zATElGB1(QMFN+lJNK4!?xSa@5+(!uv2?{>u9~kTzE{2;%+Rxb+y$>BK^=n!wS7#YX
zlsFZwc+&o)Zw#cgq-?ydp3Z?j&cV)p8o|FO`PWa9{3r$1jTGf2BZ?CF{n7X>(Y^ux
zfzE;92yJv=FvcC@>Ku$lXoduP`v1x(!+~P^{kbvy^|}2=I2j=n^7kjiZ5HV7j`2Yw
z^g}RiXg7puKrqG^6X6_;@%JOcoe@c5PaR#%A_;j+D@n}bm^Zk0000000000000000
z00000000000000000000000000000000000000000000000000000000000000000
z000000000000000006*$LoDQyv_Zkn!5CLFjGrII&qK@EjhS4O6dj833q}X}qTMjg
z!Dw<?ayHTc4}Vu@GTbpc{>uz>xHs~cMv|Dhm_gh-0000000000000000000000000
z00000000000000000000000000000000000000000000000000000000000000000
z00000007{>5e{;B(vybghBz3uUCs9%DQCQ1Ftg8`a+v(r9mgY^)e;JXmzv9Cr1U&r
zdn#1aNRY9U%hM`)l(gKNBi~rYa*{4&rU}2qGB`2dW-DXcOA>Q9x;~mQ3UmDaasJ4N
zh^G;#@bs|RFwJAdq2EF+LaIV&f?b1JgE#|&j}9Ic4@mT%^xxxG;QPt<fKRy(nfDQ|
zTV5;}KhIuIA&(gM7w!t^Y_|_?dak7|8!pz)b<PY<o{k-kd=BA9o*a?3PqTYtr(t`>
zX2r(*aOGiYYZt2)D~>}!mJcn(4klPkSg4xkn=P3cnO-&}HL*9oY0P}U*Qm!x&@kFy
z)IffJmi~KvUA^<V>$+AtwL06hJ+$s=@oI)?3~TIGPgR>yQ{Pv#cX_Ybo{BwGs?I9S
zD(uREN&`xwit!4s6jbE%<QC-&WiQE+$k?G8Q9Go4c6aYaN*$McCW(?r6Q2=R6Dt(`
zB5Jbh>MjZqN8u*nok9VEeS$*B7=af83W#j}5Bz$3rMw%wRy;L4^xW=T?OZ&Z$2cBy
zNU^7|P2ma&000000000000000{};d_vEr1Pam*w^7!OBRbYQR}N><Jtt>_}-i26lF
zRu+YgMcGr)iYM()`o=&?$%ryVY5uvn4JA*3xUs))!Zf~-RIpRg%8O=u{9|&dCfy_(
z-GS#eWMndm%4DRZWTXfb9Tm;*!^mj=bxeU+S~4B&B6%-g*YZI={IJ0Jx6U$pk1q>W
zUy1tK*FJIRAugpD{*)*pQVP~rB)(0fpV((+Czs#ek}$4XeKMdtwp3Tbdgl3plM|to
znD_^Fkt)WoV-&_;`D~_e5Al>IH568<PTL+x9VPoXf)&7uP^$k&N^f-dUm;Qdq?GUb
zB#zO)jATWBVU&(!^QmB}T07c0c1#l0Rp*c<$v{OYq>}UfL<hTIKV{le_1zA`7R@{K
zbUw$>b!T?Oa3F3QJivt%#v78DN+uSv3k`4&rv;v;rnW06cn~~!#PXY=NSz(kHp&>`
zk1B*h>Lu&4EQn9hD(+@1bl2SNQh1#)w2AF~GvCz${TCwo8Mu%_cta`@5z?rux+{K{
z%<1OD$=i;yDLXqmKBue2XT^IdmN+g_qcRDF%%8c&cdoca+xd=nwr`_`T3&jHQs+;H
zpSiW3YbvGD$8aG9@rG0&B4h$>{qBsGlY8YqVX*?sv)d5`iXnlB*^#NV?N3*}-mfAQ
zGC6p~=9&EI>nWuB97(;pbC(niW?!yXcb?7*G8lFhron|o;teTJM94mseq&L^Jt@Tp
z6yBPBcU!K$)Xhlx@a7(dww&%F&2}Y1A?4rS)3*JlaN@nJ+WV)~iKlMH-|5tLeQ^GC
z?OU(;qc0+HAqDV;lp`YK)Ymwk<i~A~7AI@x!rr~-C+lyMx`;VDTDyMX2><%pPeLIt
zF4rZD(@(7^71u_oV`-KnH4M!;to=!hgE{)M4>4HaLL%^nR3;+if^DHiL)9mabMYhB
zq_2@~O!7}WzqrwSJMSmOA#GVMSwbO)6y3%z_OcXHs}E2)k=&%y*3})e^th-P&f$Y9
zn!Uz{3(1c+q!JM!>&z={G9P_0vdd~4-4r_+SQ<ZkcY&&Nv-SR<4@;r8455&jJ$u4+
z!Y93!jv<&H>U2C^)ZiLCRBXvdmieK!neRwEuAB4yy_?G_$S5ng{*y*&|Ey(U;mEPV
zX3?t~Q{TCt%1W@hR}`^%&}gK1Ahbz}38mcGu~)dgFr<fE%wK|iJvVDXwkUPO(kVuu
zWL=+MRId`3k{5qUVmhV6;k*~E6VD8Eu3j;V4US5cuNhRYc$u~5NJdw!k07#;P)gS?
zVMjtGKYieN*6c>3edlYmMD%y0u6alyslfK_?H_-&bFROg@U4(8|D=>@gDbCk_@Z{S
ze7i3Gc3FgzF<pF;TH*XL23sVli~foI1e;Jl;>yr=ThFfO{)u-!tb4^JA`b3oxb0YW
zyf=4TOZO)(Bq!dG#8eV-dzG(G*yPr^Vo&>f*xW}VMfRE}4!xh(3%kMQdE+w)p^)=|
z8iJIrQim1QJvUlV>s5T$r-u=WNncT`)*s?yD!1W6a^MX~%r(bX+>?{3EmFOU)A5qW
zsn3z}as?vQ<3=_;%_TfDMLW+D3i;J?_QhLC{puXWN`%!Xm9OP7ePt(Kyq2DLTf3v>
zqf;|3Bs<=a#9VXe&AXVo9@Ck9w)`}GIbBq|Vzqo!!B@1Y?K4kRum=-6p^&F05d-{3
zDOB!UF%`&e2=|mZxuZ-YIWe1|CHAb*#okZ2kZgEE5_8Q_?vN=ZXH-oe;8<xmcF(C}
zX=LXyMYqRO!ZYX(VJF0!35AqC9pO3HUHEd@biHa%Vz^Cm{MZH0jE)f!2~&NtpnGDt
zkUQ~)B<7lf*-e>s$)u25<(>c=2|Z)AW&3U6_We{L*KKUpJziaWPH>4~8{sbb(ehwc
z@ybMC@&4rXUiI#mXR2%41nJ6Hdh;4_AzAT;B<7mq_pQ3yNXWRK8~t%T!f3lupF%-;
z_6@ew)<wI7=k<dGD|z6@(5~5G50mc#x+XQz=~_Dv`kNk^H5F!8_4z*Dw~GuHk_B%_
zVy-zxBDUPh9(x|<%ZW!%-W=zwWD|2Z?SJt>b-PQkdhWqJghJBLcuMqSf6J?W>9C6|
zaPeSAMa;0E=ECXo?5@)0tP}aTZqEGoZZ6|0i&B#RCymm3@o1g`e-FR1{`Vdy#D|Nz
zuB9V$W=bxe$>U$5n`P$+r5yYa&ZcYIea9(iEJ$dQ{^c7d8S(pryoF)br>#Z1-*n+p
z?!cdtm`*uaSWX)DS(t(T%a7gfC(By*?-mWH5Zo2IdZ#Ipz1b?5P|8}$jyWUGmrpn8
zuer79v1+f{?F%|)_r6bBbaapGA%-d331|G<3Ev7S_fJY0zVVFfQ{!6_2iLuC^H(0c
zVcJ;#8GhP<yF%t0yT+9@MM5F3985>Y@S?&E)g8`79?-PQVChNdlVvZ8ujI0)_pmvG
z3(0^tBr%oLkcvWdWs;*wI+KN;VzTJ#jt4|!peIX1Wc#ALTN9=Uh1~CG=sa|We(H|c
zeVK3eyosu(gZo+QZfsZS+;wqkkL7+`$ZdE-5_8Q#iwJx>F4b2_`q{*N?0dj!%E<_p
z(CM)azJfzB#wq3(35C2J<?!g13B!vI_o#a~oTuMP2Wx-i;9l5sBc5MQF83-oE+jqP
zki=Ybu-nQ$hVC%CMCs$P%=?IX_bcmbGoIa#cQ#oFjC1|$i6Ioyu4nt+(t{a{DOK3{
z{#m}}u*>r78m=u&oZsI{#M8%K!-b^78<Lo7&f21<et!4D@TF}EhaT>kn{vG0QpDbh
ziH>&mF+=V2lOhyyHp!GPwHzs)Rr7V$F88V7uIRvmJDKz(rf>XqG@hLPf(uEDHzYCF
zoP0A?rHzrf8y5to*1F}AjU*DU*(cX9Y3~rSZYb`t=_M3$LG!~x&hlJ%x3O?bBtp%{
z+*U4b`;=pa<j`j(c`<=kxR5k>LlSe%`7{@6(%@)%!7;<`5uFV`lla#weGauZJ*#J4
zP29Im3?&ru#I)Uap8K~g-gs!eunDH3{7Pek;IO-)p1Wcumy<t0feT5EHzYCFoU60g
z<TAZ^)x^u%W6$0``*C1Be)g{G<xq#QBP)V}n0P`Vok*jUXqt=eT}?b}wP+@M%2%&)
zt*0WYePR4vh8TxH2(Ft`{aZIjDJiL-akmuY6y+3Dh)C&FTw``(eO3HmS;rIe!d)R}
zzw~a;@eyG?NB_jwq_p@xp_J)Xfl^Z<KBd_g)8!hMYx|>KsWGe><m)q3J(LJddT5MG
zNr^utF(*86rgG{QmiFF<hTEscHNuq6mZl9luOiYfnA(38t;sGYl=A*$@|}^J1sjjf
zKR!TleL#zg^~}=Ja7V-Id$x>`pA~g+DJk%#bRnh-Eg!YiJ3A((r1{D0qUHr=3+A4#
z^c?e~g8shGJD%CO8xl%+d0V}@&lqo@yrP)WY;reAW3Kf9r4Nip>BU5Iu37xZ#-$|3
zUrQGvQa<J>MP&%5y0GX)GSm4uwsJYnsFBhSSO(QHCNJ(;94C~L?(xaq<@L;~UfC)t
zFVnVd8xwYrT4oWWxpAsvq$h_V8kdp`e=Uh=mdjs1Kb%O2j?=i?P<duEIn!I*NJyv+
z-D9s^B`L;wAcauM+z@+%ta1GgvD6E;ulK2Ozj<KjsQ;>F?8<pJ)#ARd&u}S8@z>Is
zh?MU9=SN=|uJ2gcW4&ovzgF58)1M+5NtH7G1Y>_bZ?%+A%7!mdcA3`-gjfR+(#6$W
z$9{-^Gj~gvd4H6I^0WswAq|(31aC@3V%8br1$$Q}F9j#xI&N%h5k}&=KJOgg*klop
zUDWXZX*x~txeT@;u{&DrspdIpabN103pcrwBx!cJY`bF_c>ptKG*gI0#{4}bN=e3D
z#^s+hA}X^apUM`6sy^3Y(ywca=K=@j-&Vxmw0P|m;JhMD{e)1+(bSFXzFyMttRHS`
zM@+n9d_2;Y^1QV>1wvZBNXL%c!6Kvaha{#CxpaQlSIw@y!j!3YV;P|~X4@g1!HAB!
zTFHIW*g3e%jZjFb$$D*G8!eyfX+g~4m+2%_;>5|?Bo<ChxCQdF*pp6Ukx_U<64i!`
zY1O<+UrniWb@JZ5bWA+6pgr;ZdxH?f@YUyQDT{kq2!$Mr5}adjyz*SQaJo2AYiZd@
zDJE|7$T_l#L+jH~dgHj$eH?!!iRnUey;A%%Lbrl44;JrReNb<GelLZ<B1u4hcnhn?
zSO_&Up^zm<nTJ;2?j6ULS+ZRG5m*}%9OfE&#WjXQIi&o_uGx=RWF-Dd64Qjf#f$77
z<7eH!KlEw;v{|4AY3t0r*L9;~FPSpj+vrg1ghFcGG#NSFDKs1EndpG<tH1nCXJwt7
zrRBNjoZF6%O-FHmA&bCYNn(0X8>3c$e_qwow;EQvzDUjR6^%xVZYa&<(&ssTI>DqF
zL@4Bsy7M;{Ooi&wyAG`lPRMs0rWiUhQ4^$CQX`%<k#4#NiwwsblBgC$7O2*laa1rW
zY_#yc?pM)4p3gy&4>UjXeV><$BE30F@Ega_Y9w(*tM>Bl-fExDBVKwBBc<~iUz`cd
zq*I`JU%)(yMTY$?q>Q^8T2W5spR}NoJp;P)U)BAPL!q4#1BZw2i$$uAeZN=~n5w4h
zHsT;oD5NKc&b>(*GjnmQ%KP%!v^N!Xl~jo$-=CAd(?#qZI>C%Z9>X7!m=+Z2JIWfT
zSu|5<eWBQJy40K-t<tKLW$UK<);a%VURnU5kTFG11ZHo=xB0yhINi~7!nJzW^L-QF
zjz7Jyvpb+mQCAg<48<Fgs223~UFfv<)UJ&7H+J5QyDzPKC$^?wUU8pT;@j47uY;6=
zP{^!nR^;0lA2@8^m+dJq9THPErR>@&(<lClpJL^MEH@Jt8G^r(#I&Gu8DcXz15a}@
z=QHoi>fE>^Ie*q}L!rlve64RU=G_7tp^(#iAB{$2xIK@n;mY$ot=ZfCp#AV3(?qxM
zr(y4;NG`8pk-_*YNz^*%c<cwyDp8}EhqP-$A~dgk7ResRF3nH0e4AN0T9HU_eLn3j
z=@_0;O{Q}vJ}^Hwd#aG!v`l(9&x0qQQO@s4{1q%R2!ADsX+iYEnH&<#Vcsn><Gk|n
zP3t8_VnRCBw(HSk&DeWxS)U1od?Go}Q1+5KHIVPeOt}Vo`gOY{p_d}H`G)-$XhI+O
z_hFHNctaA^g5oUr&eO}S?wHdsiQKiRnsnOl!E1E?(*s3bSTC#FcRvscc`m-yZhPV`
z?~X6|kF0kn^ds}F1fO)cMhqziiBt9rHDQrQ|1G4vvZ9;oKWRZ}$2Ue#2DH774~f@G
zMSIEIC{eh2Mc}%X%!F!Ls4~M_LLra5q`?I8xj9a2%l7m5(cMV$j%-u2vU=h9>Z$fY
ze!2)OG5~)_Vp>q<(E3@PfiphC<I}Ci-O5*6c5w<0ej>~Ar7Kl>n%&kxD5OY@y!wkq
zxpqeb<(r5lZlh4&<s4*W>x6<Z>oZKGz$GlwA8$yaTF}R$Hkb2tiM+yE&8LK<5@eE>
z$k>Om1vj`!TLtz%(4i#wQzvx7g=#l0GBxQ+=^}J`nXz%Zq?Xtw{ia0JNfgu36)e&Z
ze<g`&K?6*vti!%M;uE~XSn8Bn9j>rQDX;64*V6ojXvy4k2tFmml70Alt^^x97iZ73
z)2@QmX_VLDfy4diVWapNsno$+SfnrhN)pq8mM*ucwJn-Syx2LKj82j2bClRGzTI-2
zWLHjmcm5qy2SOnu>_)Guocf`+CZNX}dm~M8#aKPRF`e$kJ+&M61uN$0u}B~Ml_aJG
zX_QI|9c*m5t@-nfdd?Esxs6j$Hko}bcE-In)4u8BFrkoE;Rl*4*hKo{ODh8pn2+V^
z$Ib0hNZskN)O*US;L$x>EYcfqNTOPhD4A{5f@VSL;YbR%i#-#qg(=M!i{e|kPu|O7
z6}3E~ODJUgcX`1cfxLC=183#PG1oh_8=?eB$BJ+3KN!4o`%Rkw7U}i(kZ2cKXE*tO
z(t^f(<NZ~WT;IwWTlR^)v$)nlyUXA0Q~&4Ch`8{)&oVWHLS|5p-llPQJmeAT7rl0O
zQn~b9*~rVGBR4KvBuA%tm6~Ib82llLX+evxH}ysGGRyBuQGYF2du3u{)4Mr3@t!p;
zUAo%zMI9rdklUU5ZzojGIWcfq-#(k%bUemZNS(5bgu-IalMl6Cj+|JeC*F`mwV)CX
zrLJcu&uDZ;|F|7?lY%)f>n2~xT4cM#yn5Ti>-%O2g^YR;U3@?G_=VBn1`%<lZJ(x2
zOuzE%r)=WnZsZhtcv>5a^uS+9Vp@>Jsh3$MUXmLupD!5G4YTzhei?K-Cj5-^x_?RJ
zQbG*DYxi;4!JrKL?QgisRs<L>e{DU-Op)_liIcSoA#pd={`(g!(j9*#iD^MOhB{xK
zwOqTI^sur|Gl%s@P@`q85C?zbyN^qb{+Dj~5ehk;Kf3!~eBp9c+E;%I-rdh;qEIZs
zW^*<CoaW0zq~+aMBpQDuiFz{V!OXF#<Ez(p9^y!$i`o%7e26zZu0o3YvwY^v>v<h*
zLLp5lZz|f3DXH?zYVO-{SV}LQw0^M9{T0=#BJnDx;4)q;(hYA&qFT_X>EmPbZOfM<
zdDPODtb`&RZeou{uY69uvJdlUn)NY1!H|oO-pw9S%je#6@&M=OuTxKH3r<z+S;aJ_
zv-fg!gdWBsUH>hljGHpr`Jc2P56*d1{Yn6Gt<|NvF7iy3t;F_i$4=BsOnKLvZPz`M
zKqzFk#Bnn9g0-ohrn&6}6(fg=lUY8DSu{y?i}4_^iS~I|qznF##I&G`t(K?Tim!JH
zsx0z<#PrviR9Gh}kf~9QI{ABUUZ9F16ta%y!zh{Oi<_m>=9e_zY-6vvTwAmFRpnx?
zAH_SBl^-9lNN2nuiE2SRU$+XTr_0f}31+!G;-&uNEaXq+>NB}?E^qm`#vD}_p^y||
z$L_`U={uFy?2`Mk%T1DL@0aFNvzQmB&2rnBlKXYBNGJT2B&G#jj0{DR_vX&A$NZ$f
zvVHl4$56tC<gt9s$s0)92K$yT1Q!@Q)3;Aq?QpvEX5Z}W`_#yfS%QP@I!Q5~)kB$S
zn4-e4NJspYB&G%ZL@727Ui;pA&wp4<%|Wh8AcjeWuH0CC#9A-i+|)atP{@<(BUWz%
zM(^C{XQGOzoEXzKPW*P9CFC1L!e*5YqW&Eg>43kI#Izt8gUW%*wkYQMDmAIBh4kF>
zAL|${*y^p&KKh!c)6=w*P)H8%>^D>ffg;y0Sn(A%XII~%R8rrzkQj5hQp@4K_~;@Q
zc?54rqFT`6lB-W$@c|#(Q={DW?~21r<7iY<cpsQYqNI~tZ8Qn~*!!`O`>vadUWUBV
z5(Uq!QE!9U${D(|?x6!^Sk{CZcyS@^{~pp!SxHvzAN@s4$^7Gx%aPzAN3JJ+ua8~|
z>}Z}oaNl*`=wnho3$`n{1YeYT<`gotqd(qgfwJu04jyg!ICAN10qpug5zF+)KP4>C
zSfm~Pki@hgH#RNT)2FrO(K^xGQW{B!loW?j_TJZ)Vq)jS-@H%zPVhPNJLk`B4|m9X
zC>J$;kUZ{iT-~R*(&IZU>BYqq-<6LUVUf0YLlV`3g5~%tY|?dK8?qW)4)^M<_c>w7
z9PwoDlu7pUfF^xw7lI+5zwPZSZm{`cS>$tAI`xefbK83@t`Vbm!a8x68mS&)kv8}%
zNlXh0wal(AsW)}G+B7K@|CGVPbMmX(clr}zY>9$ZN(U*f6AF2rgRi){;LvjJ&$*<F
zwD(9qsrxB}*}kqcL-H>cO9uvGk%#eDl9(3M*xzBt#i4hL$Ad&s&(Qu>+^gZ-lke80
zF4pVYPjMO$d<H|J+5HGr24~k~zWlV_{w9&h9Z#<AOd?C!Wz%y}*W#!%7HN&YlEkzi
zn&oGaF2xCEthp2dx8A<%qWjw3uA}RIg3eQ~=vXaxB*7otJ?YDLH<fD7)7^C|#(2Ab
z_K<IkPrt&QlPr2>!`mfs-#AuyLlV`3&Irn(DKo@Ke|8$kc#k1_d2U2BnN*0Yk|%{;
zd?@wcJ)w}Dv4S*q-xXg4ytt6i_TyWDw87Xi|Ggo!NMb(EgJ+~_SmdF<hjc}wl~k1f
zNeki<Wtluuoag(9s={h$2WQT-5#JXV^3E0$n{g%coZ4kVAqAW2%QcQv92e2kpgB*i
zDzjdmG`Va1B{@&X8%yQkTi38iOZ*{;X+hh4ML2phhi{j?mYclyLOst3X`K7!#a*83
zHx3qjsY<FK6jHdRmL$ob;gzb=nYjlC7|XvliC;a~i8!^^=$L^X`oxb#9>g1xs1{_z
z{sD6`(ECWo9<o^9>Ev@JYEgpuuhT-3({p#1QjF^p3Tdy`^)9SpGdQ+_s$Q-23t6yR
zlj(fT(@(xyO`gTtJxDCl0)HimX+ag|Bp(dcNs&#=GZ%ktn<*7l3sKV)SRCDZRn9}I
z{=q3iA!puN%a$Ku6&|F1E9-Ev@OJdlzUo|oob5gmRTL2iRrRn)bNrPgrUi9>4Af0n
z3k!%U<rVZuab`3n<+m>0RWKUJzmsvUHsB?pkk7ix?nwq^Uyc1bC@<@L|EES`XJ0ew
zbW7oZ&sX2*NM6Pw&G1)}m=@Ihg1Yx|<FP`4fa}}d+~O#zp!Vk+dOZG9y`f{*kqmx<
zzb|&pZijj=r;lis>)h~}tlQSA6_b}62lRVCX2hkvb$j$2i!{X>lBgD>#Hjz&!8^sr
zsOkIDkqA_RKx3X+@yZ#6288q-4vlhxKc!uMpt!-|ZU64cHUpENX_~fYUMp5a=+V8g
ztE85lugFx#B2E4+q=K@$vim=2LESl?cN#>EEkus1@cF%HJ$@)bM*LD!g~fsO*zUno
zJtKrdM#|?iE;doPAKgiNwuF=ROfz>YHG5Zy$B7Ci_eMj8J6NPK{*c79pcBDbPHNRf
z6VH^e8)?2vG_=PvH^>KnFlldpP_HiY!hqnb!A2kNK80pVdXmFGc=8yBxtgna`GcW`
zKoKoI@BW*pomk`nydjBdL4{IQm!4OJe|)o-Glk@a3D){+L9fu|d(#Y8240BEnjaw)
z^5J;pkxfq815x8o`#KC`zwPl&EksKkxkD3EmeQe@8;(U9;jbhyEoiw@W&5+&7cO?Q
zcxAkP#GCs=Ft9+`x}&5aEq9N^K8-v=Aq)I{)(y6G7rMUYSVEUsMz{vo`K#6mTWU|<
zthn0~{SAvW#9v8bT9Bf?E;@|;;*+0OzkR*hq;%Z8ke{)b-Xr<K-n2z30k0W?&tPC*
z_G_IzJ|fhtWhvycQU69s*<k0jikO~)AfL5B_ckoj0DmQkX+iJkHZDF2y1AD<{w&3J
z#z8M@vGuO)ygz$Pt}GUnmoV-n6p}H(fFH}}mvMx3o03re{IbB^6#bWTr4OVF^vQK!
zJiLWP?#COFxYq?ys3exV?5UQ?`+4W9m4_IA(P#JO`gh#<PT7&I)AE6YLf)0Viem7W
z;GDmk$17Z)cC1O2!DRlG+gRJ_t5%Iy>RGTz{lABFag~=>Qu!w>NFn4B_v|st_5ImH
zbhl%^u?aE8)d_2GxaXa}tJu<|phGBRtih8JzswznU2AijMV;2pC<yRav(G<n@RN`)
zt)^xOz#{eVha{#2wb0ct>8*TD_q4-Ue=%n<{$#Jp&XrphW=_(7HrYqBmQYBI#|KM3
z3%bql%PaVVkbRh-Yu6O&R!c5^_HFTn{!0sUEK(P5NTOQME&8J8^e(g>r*EOMrsDE@
zljvJjo*U+3%8K2YF(#A*Unug~gJuQeS{X||AST#W@cOj9kBf<{&0yCt+iDh<hJC$Q
zqz?W{64Qc;R9S12U9J~ZR~}eBb=2{u!Q%cpu`EC37p|VtiJx^P358S`v61}nu;#(y
zLPT}lrNJf+v4qXinTrgc9S+@-{m6y8;%MWqBrz?><MM4rs+(REw`x+V7E3={zAH)G
z_IQ~BDP6*Sb!^_cj8MoFp++vv=s1Tam0bN+kBWfZ`Lc~MOyuIBVNGk49e4I&ky`jG
zNlXip5QvNyHw?bgyR>{`xN7QI(v3vxup74u?iC!2tgv%@M<^sV!CA6yq?!Cjbu*1k
zW5#%yOZQxlq>KBxE9WA##C$EWNKL#UiE2UV#_`WLn?nu+4795i4(!+8#y;FH=ApZL
zii7*Kw(2_$g1_2-&4+)(*}}KGJmRZoe%X+{cvna&lYjhGRpWy}H9d(~q{hF6lyz5e
z{YR^yL!N2Kq=w3CtFkAK7I00s3waLiRNY`CKPe^gG%)JiK|&$>Rr#+LGpulNMb0dU
z)KFTLR+(Jfv!CkRn~PSnnUq(uu}F3NA&F^0B$uXba$<~`qr$yjot`dOAUQp|^NFC7
zesaYVlHQ$Rmk5Q7^C1a7nR0w(;qv=a{pHfW8M}R`7O%+*v3b0V?PFK8#v;}5h9s&5
z1#~K8pQ)GqitA_Rx|~r@w+&T3lpZ1x%;Adj^2tEx5ei9tm4Aim`-1ASv5|nAyw+L%
zmyh_~9*M?kpsUsQ%0#AOk^Ashl9(3c%9F3cC_-7<JZo#NLFIdzZuiDGlWrVkR;9(X
zv$@($LLs~NQ7s#cH2Hj|6w~xkY7%qQEHXcCIoI^*y*K>|%GMT(+>5`G#Izv#V++=&
z`Ih-ge@sx9zenuY6E@QJo>W3>GV1*;wfO^;ghDc-cl6e%?5Lmd5}b&XG>(ohHf(b8
z+4+v^1n<i@_Fpev+JnE6#Izs=KbF>!yQ`vi)(rQ&jDPo`IOJ*Wt1q{s@1Kp9&pmxh
zi%>{+okmwAL$2e`{u^)owG3y!ig7aN?l&?N4kSPDv%yLXi&VuMlBgDRD2h8bnC>S-
z1{EzDWgb>r$gJqdzlXxF_GC}5(e<G|g0E)DL-`cfhFytgRcT;)W3`f&lis7E)AZcL
z)#6<EhI=0tsq*)b&MMCGXoY{$f*Pu$m~S1WI*6U$9{)-A^{xGJClt)`<%2B+wuxag
zya@Km>oQ4C?dw>DLzpe859xEv?me~PODZ7K7q@nB)h7DK1{SG|KO`|N2#NGAp=j+%
zy{~9WC8yuE5g^P@&n$W_D62p5GS#)+1Yam(`To=sq#efmdP!aF16i{k7Z3M>d4Y&H
z#3F0dS?<gbEK&(?NTOO$3l|p2B`@_lq4k?wtay-k&8L^ylRdjxt!I8HWpdM^2!;IE
zY!nbzC$4cVeJU(OG(uz}(xCg<YcXBggc27`!IiUEq$2)G64Qb>IuD5$U?vUX&wCu9
zBYS0F%dF#me+M=BOPQZHu2X#>_=<h{!^bpL4vZXNZI^B+?;qYY7#>b_vA)(Pg`Tk(
z3vj_=kqY=LNlXiRNX6Wk{M`1#n~(>|D;FNTel%jdLsQ@Vb=&EWQzC3^i3DG~l$d(6
z;jxWTyc+8f@=Hb=#fOzN&*b+Re;X%HRGd?e$0FtNSCW_(BySLga*%63sn3S3t@tiK
z{oUo*q0G7A7}153ul;!zm<WYTm@}Sfj50oZ&A{>fkIN4g=aZIbG@@;3o#&oMyRM`z
zW07)rLlV`3yf@D=O`5mxkR6aj%qgv3)i+ZV@e(bn`~Gq7#G&UJTm*l|GSr42b2zD5
zqqavOEmn38@vvb`J!w^^`^Ck*eEoZdu}Il}3yG3f_-D@rJ+|?4>XpP~)aD43PA2zK
zJTyDoZ+&5IyolX?PjT3deS|{p73rjml9jQk7uy!3t`V7ck$ta<cwWt5?m`@w6Q%~Y
z=#{}Al9(3sL%E7^N+?j}pp_#zx@?&;@q2gUweeNQrZWo*11vKHe*o(2zN5VsNtbmn
zsmZTWqR+E$wSSjnDhXT9u~1CLLtQ;A5`{M;Q7s4^TmEhjMb*&Ta89ik@q9Na48`9o
zNSAMF|M<vpX&VE<uSvR+3tdy)moVmNyQ9xmFm#9$Vj-1lK`|8R`!-Vj?>@mIrSVsi
zm=?5l^Y$$AF2&*e-BvWJT$dyTiZi6rWc6#fJG?h)#vN}H3h8$E+0N8ETr3}k_+A%%
z_j)5<uqfFp(!+eU)$qrrCUX%Mxf_2aiD^OPigGocc4fAXNnO;d`DaI7rJqt9tz$B1
zijpq273*Oj_>T{qN|>S29f(S&`I22tBODTI-<sEuTDU8xl0p4@(CiQvDTTk1MEykU
zTl!r#e%cB5vDo1$+Uv$=l+1<w7mk$}bcie+{`rmIE38bu^isAPO_F=~9VMaou}DLn
z{dP*2HTKe`>gfH%eD_5xQW9@SqFNBOpJlLhF;lwJu*d3nXz5dp$ET0*rRs9F%@}ZA
zU!o%TS~dCA1hvI4UIF*#wOzmH-P|9N!Njz!N}l{Zg6xXTQ${%~QsVC+Rg_S&3jgSL
z#Ljacn3_M^JTPnj#7=QDRP=d<+#vVMO=Kh=3)%Rk8G=6%GhVxvAJc_C7JJ(%ql*3{
z>%o+e$aq?cHRYR=Wn>vYaf{x+|7&%B3rS21(y`II^}4!6gXHdw2Oak+KDV6plsZgX
zNQcCbC@M!$G!P2eSaq-b{6(&WW~;(&>UU%7T8@M)SY|8e9cPpKsq=I>4~zW!KUVi&
zLlXD8po<G>na->Fl_F=)+7v}+#Z07Yog<;!QBWL7vUk5aFQJesJEguoVH<7N@e*6S
zvv=Fq!8>_clJ_%=o$e_ph*V0gW09ixD@jZXdiR>G|3sXh5?`_Mll2%B745s{Z2jEa
zdf(^C6cJ*p2MC2E`#>^$Bsulr*{kcFi~<=&UWt`;oO(NwEnHULrp<fez9x6!uOu-o
zC~EfdC&3qy@!ZK3^+7o-14Vh1);=@nf;bcQJJWaO39f=FV>9)?eE-35o@|F?!u6~;
zhlV9)L%+!(w`<$&zy3e%oq0S|`~Sy}eF>4ZNOeL|bcQoCM<LRcHJ3I!b7sgg3^Qgd
zV>>EJDY;s7RVYQvy=_-TNl8Uo+!XCvwNbZJwCLCGJ{~`A^Zh+OGxx9G?~l*(-{<4y
z@&3H=cE+6Z9_P8K6lwwPq%0#yzj?v^Zc}E%?~$>SJ?MMy2B>^4GdLpHee!(!1D*SN
zQs0!fGNRIJeqHBIyu1)L=L?_zXx_{<%a?jBy{W03y?e#!pDENFSforNNU>bm^Op&?
z3#YUgOuM4u<~{Fjz#pIE)?sS)XFeFx+Ac_4X4M;!R>E%N#Drz(M`LNfKPex|lsg((
zF!QhJp^ud}-Jwu3$s!33+xFi*rs^$VJ8s1$uh{wF_h%bd8l5xHD|TRat`fdE{4W1=
zpH7gpBI_J9!?LHJ`7JXs+X`py^F7jf&K%J<JN)>p)tOSimkAU)8C;|+BPi}o!~Umd
zQWv;&<n;McJZr04)s(yPsOB*#ooAZ3)1>~z33#QgJCT@rxB1{^uY6{G$(?JHhu*BC
zar;Z34^?T!Yf&f)EK;Ts6yPl=vc2n~w1CzZ-hI5a&9nN3(Nu>fGkNusJ}ckwW=JdY
zR#%mJM)1Pgsl3H64pzFU*7<A9v=FIKa;i^E0%Mg9Q|KgcCuJEyo?VY_?KMvfvQWOg
zt!902d20sxAWnF;OCM(sh&wc-Zq&=l2_Mi6ex&Pj+2{GmrTO8STbx3}B2l%?wV$69
zld3p{P6T&SmJzgSFksK8Le|y(6-lQCubTbZyS*&`tKJE`qeCNeE72+^t;kt7%b!eY
zjH)m`tcF=N&Y!mE1LdkTwm>VV$wSv9j;Btc6TqF6Wdube+rOK<f1J0nug6h_s3>lw
zOO{@&stJR~`TDp|w^{0?T6tTf``QP)yZ3XZtgShB(;@!8YrXfxIm$)$tJ}hIsgo2c
zx%KbIB4rvuJGY%M)}0ViSeqLA{AsM=L#4H;AsSxoPwwQgJDpqyrM@Hfr=>|OGvB0=
z8&>buZlH}ZO!x`b!JdBamS#+kxZ?l)<%8tXKN^8E?b(cfGlDh+78^JkiU)>D=akNU
z+u_<A_|@Ca?TLqz_Gq(Uyi4k99Io>Qi*s``M+Y@F>O?zUa<8RgemZhwua>LatI&#x
zuhvkg3AjjEMo?L4@I0q7j!1m=YiReN{JqiLuA9rxM0w5`Vu{!8JzOlUNagDEzRM+c
zN!9+SY4PRv^&Yrx^jb`rbld7~e>F9HKZP0ti<D^unQn-FS!B4Rmo2jLD;y}hR~TD=
zc3HS~YS{~gsuN9hQtuoHRjH7Z=bv&jxLl=nCRV|yCH~9M&yT(C?Z0~<^Q&Q~0)>tP
zcT$!SG`2rm)W1bNgR@pnrQ#)FRjv~_F8ZfM==awSt&inbu9v!@MTer2;@qmn*Qjn@
zF-Gyy)N*q-nyF*CwdIL>+@%T{6gn2%Nm)jaXY5%GpQ4qIcT;jR`?o2k*IT=uo>}$Q
ztAFF{M857Eskh5MHdV4&pI>Uywyz0keR$X}&?73>dht2OwyXmep7(5hOQA;KPRjH`
z%>Pq*;Fl|x_{*=HI)6Er3c7jLrn%ht4tvTA#OZPBF{#@demm0Ca^aW<ZH2aT_S<=j
zPE~JVJyq^qJYc<Yb=Qm=e^RI+ut=FkkcC2ra9Xjl!t^`Lxp8BRlI<AXov)F%u03LM
zxxq8#a;a~C658+dF8O(9^;`~5alV(kFEm(qxazgloX|c)f3GA}3N?@{l1bXp2)lnX
zg2F7_-q<DYG@E}k@I{7Wu7g43F72@;&ly$+Q#&syI!Il9yqn`wnX<CZWWMKVr*UoS
zXJX$LtLKfHeZAm|c4v|9dl7}|gNu}91TBdO3TSkGcw7`=EmnQF<(rdE?n&;d>#aNR
z7s76jeP5&%nO4m=V`op+abdMvM)=MrHD@02YxgAnxX$H$sJWTwK%siTB4rvuDg#aO
z+;DuI*7P7dwTAhv?(GE&YaJY(liO#Q(Am?Aq!sy^e}PkU{MDOd?Vs}eJ~bXP_&V<E
zv<DYjZsgZ!sTqA<LZQ0gPRcTZ2K9?pk13cE=3UZ2^ScpZikZ#bX{)qj`SDrH1H<aK
zNquf{@$3p~zi;72DLwwVUf;H!Jj|V-KA5Hb^1#myxu)iMA1G9Ed!j@qWf?(XOP+I2
zPhNiOwhy&2uXTq{iSgmf!RbC5ee;}EcYV;gDXmETd37-r!Yjpdoc5;L8h1HOd_=lO
z#V2<g&p3zArPpkvP|4+q5}lM~1hri%jp{vRaBq#3%dVp(4ty8C(p`&w35~tK(Aixt
zXmE|x=N9GPPg<bpm^ce->I`}@x<G07f*si<e{L%{fAx&*8BQ*RY6FXuX#|<39r{f{
zA^6emp53-*jwgS#aY|=zx+Vy*x%x3C*ye1c)OTsiuAF-=+Fv{+u9Z48zGmN*${2-}
z>-qJwy81(Gif6l0=;;3_lEz`v|J4H;J1t|2h<7<@ld1++g^xLL6+zIlE5$o{@p{#q
zz^oHe??iQbUlTQ9Z*cE%U&n?=dG6b4`0oD8jIMnyjWc>AdN9~bp<3V~Wf?(x>K?Er
zPe+)ypG;IY$<W(z=wg$bQrz`-b-j<h#234!N!@bO)0`v-JJu8U_~xrS=cZV+Pkgo}
z)TOUsA-y9x`Nh~|3e^M_Dboll^Lsbu(lKVWciFNFYgb>1zemoxaep8zAOF;^*s>%;
z>LY<`x9(83X;ynxc=yqM#!z95y5^xN{q*IuBbz?DY`TwrpOYHkPRcTZ&c;4${iSrs
z*Rq;ue^ojA%~o%Hi{ITnd+};*U+yPfhSVKa1S2v{Sn0&AG7g#l*T;^p>IVJ?bkJ!*
z)SB9arpmDtIttuLSw_(2W}}Mm9jD@#Ra^MoEgYlk@%_(Q`|+ZF3-Q>qdo`Ovq!r10
zaLJ&7FGyQpm9@e;;6cK#f0fP<_10?7P3-Q_=e-!9P<3!8Wf?)J=vH#VuXB9KMPoh`
z=|>v*Rxae6AG3gWpwIHu{>~LcQvZqiG9<pG<yV2%8<WvRMh7c)ioCAx*cP0FCtV!<
z*=JoLg{lFIlxYO{e%_MNvZW(NC*Vko_g<Cz8~)5$+Ii5S7Z<K}({#CQEcMDfz0})u
z@wMYiDw~@#FYY%tir$3A<hLX^S9jFhRw+@WP*uqy83cp0`&U;%i!-g!O$is*PqGt4
ztX-@Xe`@=UV+VuI6?nb&ev>uMd!4i*X?H#z-WeTaR~Wn1AaG|RX*1PJC-x6>Z8Pha
z+h6+f4p68HxJX$>P=IP$+ij<<_Y8{9w_4hKe6P3ag4O-5>w5;P7Inm_<(!vRq@~lo
zf|Lv9eoJTVNmUzfGKJJLEKX`yTlZ?2X5Ag5foT*fxrOq_B4rvu>3D6q!lG?kKGP1o
z`0O6F4~;f_qtt)VW5SN$LOtu^MyWT72s@r?^Bx+^@tcy+XPB6m{*--4KEgVlYd`aY
zf1#y4g-R}=l<1@^BdCmXjrHo?A4ayev#hbA45wz{E>oJ(d-r*s&W2UY-{{hc99)Q%
z@tv22HSerdR5Ym_sNjCT=F7?HiB{%cocHS8cnX!=K`GHmSw>LjH~E(QQ)rqIg4#OP
z<*jj?@w3vlQxlS`=T2X4?)dzo)QjFO`TE3LRkzIIn9mmcr4es4T4nOQt;NFolPW(Z
zCDo=<sN@PtiB8J2FQ{wXhK0vC8;wg4_r~17&>Y3hXUBK%qp#cab&cmS-CU{v`a^z6
z-_RN0IDOYQYL>;t?2LvPUGM4(+O(fF5aM~pofIm$f%3;9Wg0<iK3K9ZMAh{KpIw&f
z;g(mj_<FOrKzqZII`LIO(fE^67j0eCIxptGzIClfW$w)(MIXIopHPDalaEQLfkN9;
zH;;9cxt!8?JXbG~B@m?W_?#s-_8Y2AdMnq&)=DP=U4FYs9u#5}g~gB5rHMuSN0|@p
zd7l%bM+q4kA#$YC>x%r0f{3fZ=lh;Bv}`<?_W#?hBF4&U5qa)%kqU}(R*G7|caKdx
zWcw}duO;f<OHvfI1A4b<4_q^UIb)$p<I&77wdx3h?BrS@+5OowvyHQBvs1ILXK%_5
z%wlED$-0}hJ?l$WLsm}a%FLK7#msYAlQW-W?#}o<qbPG)MsKEPrbfnP@eT3O4F3$h
zjHC=Z@%!|z>G#BG;#uO&;vlg}x>>qXdU-mTekz?xcTMw3o1S()ZB^RSwCc3jRDSA$
z)V|aMX_~25QrD-HrlhCpr*x*`DIZdfi5f)}DGs8cl;D){qWi)g;RO*}WG>1T%@rvN
zwUS>83xwXn8eyE!I+>nqkbE#%kbE_{IC-HUMBpgs5^NEC6dV_b`OEkm{x|+<fhoV6
zUzxNgX*J&>=^6hgzDiO{VteADB%h?wN!%ox#5cURygw89iMENwiT;UW66zAR#OKD7
zTu-i5!eGKJo{+bg$K)CD4)aRlPsdj#I3}3Je~a%<5GRCiS8-$GmAFs2=egDKuJLC7
z*PqD+fj}S-2m}IwKp+qZ1OkCTAP@)y0)apv5C{YUfj}S-2m}IwKp+qZ1OkCTAP@)y
z0)apv5C{YUfj}S-2m}IwKp+qZ1OkCTAP@)y0)apv5C{YUfj}S-2m}K8|H1?X7x|Ho
zT(h-{ie!+qaO}UK+1es|fF46?OciGT?c*ZT{zqdY@m(N|AypvFKz4#O9oYfWI8q7H
zc1Q(C6G%BoGm-5QeX*s}2s(S@;M;&6L$?0-<^R^?NPG)OV@N4TGmy<7O-D9?G>&Wp
zX**;CNE1j2NHdXNB>F;Q+hR<7<lx0Xk0I-S{PKTmyOH=>kj9WgkY*rjK$?!M25B5A
z0BJj96-X1vN|0tE`I3FXm`wY~;SWAV@_?Q|R)9Q7N0tNgB(e;c$B|rMo`p~#&%lrz
zQw0~fe|U^Zi=vUk=gS6aA`7HRdL}SUW&qQ;7?@_IgERw6`%%-PIFSrH+VH_rftpAG
zX_77irb!_%jVA-sECEO}FutV52?l56)4-E}nn(m`lFkFB$pl~;j|Zk%T##m9aS}R`
zv}JMd;e*8jH4y{SBt06KCYJ)!coZ<riUer}#*x%C4iU*3J{TLQ2@<49It!R4BY<f<
z9GGT>fiwdPmCzi5X=^v~qZk6zL@-E`^dMlG3<Rd}0AQN61f&_*VhPQTjAYsq!v|Xg
z)WkxNCg}@+Y0@8<#{Gb4*3Tf#z<eb&orof$h7UF$s0kmCCh6Y5H0cFQ<DS4Y%LAkt
zn7f1~**MO$A3oSTpeEcvnxy{(Op|kgY1|c<X3YU<2IeBEZKLejBi}J+peAO6G)Z>?
zrb$O&8g~GuS+hWzfz6cAEPECnNgqC#Jx~(_NRxCXFikRmX`BvBvv81RV0Mxk!|DI{
z9kT^$f(Ftg9RsGx8Nf7d15C55L7IV0m(cc1%$7cKtvC&+2`i8$=~IDe(h``)rvTF|
z3y@}D<`SCVux<Zw5o`w3#AJ{r=_oKwP6DR!iNG{#0!TA3Q%U`OvalJ$2OAI6gb7HK
zbYoze90yF}V}WUw5lAyILkZ0!?P!GE@WBj#n$QPnlCB3#le)k(J_eX(>3}o?)0WgU
z4x2u5Ni`a%2`!K&>6*YasR2ymqkw6aI!H4xH3`ii7^L0EcT5$i2^Ekg>B_(~sRT^p
Zioi5W0i+q2{3wO-YKbg?Ace>0{1>#HAEN*O
index c6c8b47aa1e09e400f22dc29a0be559a43fab2d3..a7bb340e7c7e64b2dca15763780432dfa9cca233
GIT binary patch
literal 2448
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
--- 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 =
+    nsCString("no client certificate");
+
 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"
@@ -38,16 +39,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()"
@@ -72,33 +118,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,
@@ -144,9 +215,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/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 => {