Bug 622859 - Tests for bug 622859. r=briansmith,keeler
authorCykesiopka <cykesiopka.bmo@gmail.com>
Thu, 16 Oct 2014 05:22:00 +0200
changeset 211184 92f19cf15b2dfe0683669b9f07dbeafc3e4c071c
parent 211183 b3b581cda9405581e89480d211c472693661a39d
child 211185 f564fff0642cfbd82f7192d7e2d8b00610e16091
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbriansmith, keeler
bugs622859
milestone36.0a1
Bug 622859 - Tests for bug 622859. r=briansmith,keeler
security/certverifier/ExtendedValidation.cpp
security/manager/ssl/tests/unit/psm_common_py/CertUtils.py
security/manager/ssl/tests/unit/test_keysize/cert9.db
security/manager/ssl/tests/unit/test_keysize/dsa-caBad.der
security/manager/ssl/tests/unit/test_keysize/dsa-caOK.der
security/manager/ssl/tests/unit/test_keysize/dsa-eeBad-intOK-caOK.der
security/manager/ssl/tests/unit/test_keysize/dsa-eeOK-intBad-caOK.der
security/manager/ssl/tests/unit/test_keysize/dsa-eeOK-intOK-caBad.der
security/manager/ssl/tests/unit/test_keysize/dsa-eeOK-intOK-caOK.der
security/manager/ssl/tests/unit/test_keysize/dsa-intBad-caOK.der
security/manager/ssl/tests/unit/test_keysize/dsa-intOK-caBad.der
security/manager/ssl/tests/unit/test_keysize/dsa-intOK-caOK.der
security/manager/ssl/tests/unit/test_keysize/ev-rsa-caBad.der
security/manager/ssl/tests/unit/test_keysize/ev-rsa-eeBad-intOK-caOK.der
security/manager/ssl/tests/unit/test_keysize/ev-rsa-eeOK-intBad-caOK.der
security/manager/ssl/tests/unit/test_keysize/ev-rsa-eeOK-intOK-caBad.der
security/manager/ssl/tests/unit/test_keysize/ev-rsa-eeOK-intOK-caOK.der
security/manager/ssl/tests/unit/test_keysize/ev-rsa-intBad-caOK.der
security/manager/ssl/tests/unit/test_keysize/ev-rsa-intOK-caBad.der
security/manager/ssl/tests/unit/test_keysize/ev-rsa-intOK-caOK.der
security/manager/ssl/tests/unit/test_keysize/generate.py
security/manager/ssl/tests/unit/test_keysize/key4.db
security/manager/ssl/tests/unit/test_keysize/pkcs11.txt
security/manager/ssl/tests/unit/test_keysize/rsa-caBad.der
security/manager/ssl/tests/unit/test_keysize/rsa-caOK.der
security/manager/ssl/tests/unit/test_keysize/rsa-eeBad-intOK-caOK.der
security/manager/ssl/tests/unit/test_keysize/rsa-eeOK-intBad-caOK.der
security/manager/ssl/tests/unit/test_keysize/rsa-eeOK-intOK-caBad.der
security/manager/ssl/tests/unit/test_keysize/rsa-eeOK-intOK-caOK.der
security/manager/ssl/tests/unit/test_keysize/rsa-intBad-caOK.der
security/manager/ssl/tests/unit/test_keysize/rsa-intOK-caBad.der
security/manager/ssl/tests/unit/test_keysize/rsa-intOK-caOK.der
security/manager/ssl/tests/unit/test_keysize_ev.js
security/manager/ssl/tests/unit/xpcshell.ini
--- a/security/certverifier/ExtendedValidation.cpp
+++ b/security/certverifier/ExtendedValidation.cpp
@@ -85,44 +85,58 @@ struct nsMyTrustedEVInfo
 //
 // If you are able to connect to the site without certificate errors,
 // but you don't see the EV status indicator, then most likely the CA
 // has a problem in their infrastructure. The most common problems are
 // related to the CA's OCSP infrastructure, either they use an incorrect
 // OCSP signing certificate, or OCSP for the intermediate certificates
 // isn't working, or OCSP isn't working at all.
 
+static const size_t NUM_TEST_EV_ROOTS = 2;
 static struct nsMyTrustedEVInfo myTrustedEVInfos[] = {
   // IMPORTANT! When extending this list,
   // pairs of dotted_oid and oid_name should always be unique pairs.
   // In other words, if you add another list, that uses the same dotted_oid
   // as an existing entry, then please use the same oid_name.
 #ifdef DEBUG
   // Debug EV certificates should all use the OID (repeating EV OID is OK):
   // 1.3.6.1.4.1.13769.666.666.666.1.500.9.1.
-  // If you add or remove debug EV certs you must also modify IdentityInfoInit
-  // (there is another #ifdef DEBUG section there) so that the correct number of
-  // certs are skipped as these debug EV certs are NOT part of the default trust
-  // store.
+  // If you add or remove debug EV certs you must also modify NUM_TEST_EV_ROOTS
+  // so that the correct number of certs are skipped as these debug EV certs are
+  // NOT part of the default trust store.
   {
     // This is the testing EV signature (xpcshell) (RSA)
     // CN=XPCShell EV Testing (untrustworthy) CA,OU=Security Engineering,O=Mozilla - EV debug test CA,L=Mountain View,ST=CA,C=US"
     "1.3.6.1.4.1.13769.666.666.666.1.500.9.1",
     "DEBUGtesting EV OID",
     SEC_OID_UNKNOWN,
     { 0x2D, 0x94, 0x52, 0x70, 0xAA, 0x92, 0x13, 0x0B, 0x1F, 0xB1, 0x24,
       0x0B, 0x24, 0xB1, 0xEE, 0x4E, 0xFB, 0x7C, 0x43, 0x45, 0x45, 0x7F,
       0x97, 0x6C, 0x90, 0xBF, 0xD4, 0x8A, 0x04, 0x79, 0xE4, 0x68 },
     "MIGnMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWlu"
     "IFZpZXcxIzAhBgNVBAoMGk1vemlsbGEgLSBFViBkZWJ1ZyB0ZXN0IENBMR0wGwYD"
     "VQQLDBRTZWN1cml0eSBFbmdpbmVlcmluZzEvMC0GA1UEAwwmWFBDU2hlbGwgRVYg"
     "VGVzdGluZyAodW50cnVzdHdvcnRoeSkgQ0E=",
     "At+3zdo=",
     nullptr
   },
+  {
+    // The RSA root with an inadequate key size used for EV key size checking
+    // O=ev-rsa-caBad,CN=XPCShell Key Size Testing rsa 2040-bit (EV)
+    "1.3.6.1.4.1.13769.666.666.666.1.500.9.1",
+    "DEBUGtesting EV OID",
+    SEC_OID_UNKNOWN,
+    { 0x0E, 0xE2, 0x7A, 0x44, 0xD3, 0xAB, 0x66, 0x1A, 0x31, 0xBF, 0x0C,
+      0x1C, 0xFC, 0xAA, 0xD9, 0xD6, 0x27, 0x75, 0xC2, 0xDB, 0xC5, 0x69,
+      0xD7, 0x1C, 0xDE, 0x9C, 0x7E, 0xD5, 0x86, 0x88, 0x6C, 0xB7 },
+    "ME0xNDAyBgNVBAMMK1hQQ1NoZWxsIEtleSBTaXplIFRlc3RpbmcgcnNhIDIwNDAt"
+    "Yml0IChFVikxFTATBgNVBAoMDGV2LXJzYS1jYUJhZA==",
+    "PCQ3",
+    nullptr
+  },
 #endif
   {
     // OU=Security Communication EV RootCA1,O="SECOM Trust Systems CO.,LTD.",C=JP
     "1.2.392.200091.100.721.1",
     "SECOM EV OID",
     SEC_OID_UNKNOWN,
     { 0xA2, 0x2D, 0xBA, 0x68, 0x1E, 0x97, 0x37, 0x6E, 0x2D, 0x39, 0x7D,
       0x72, 0x8A, 0xAE, 0x3A, 0x9B, 0x62, 0x96, 0xB9, 0xFD, 0xBA, 0x60,
@@ -1077,18 +1091,19 @@ IdentityInfoInit()
     SECITEM_FreeItem(&ias.serialNumber, false);
 
     // If an entry is missing in the NSS root database, it may be because the
     // root database is out of sync with what we expect (e.g. a different
     // version of system NSS is installed). We will just silently avoid
     // treating that root cert as EV.
     if (!entry.cert) {
 #ifdef DEBUG
-      // The debug CA info is at position 0, and is NOT on the NSS root db
-      if (iEV == 0) {
+      // The debug CA structs are at positions 0 to NUM_TEST_EV_ROOTS - 1, and
+      // are NOT in the NSS root DB.
+      if (iEV < NUM_TEST_EV_ROOTS) {
         continue;
       }
 #endif
       PR_NOT_REACHED("Could not find EV root in NSS storage");
       continue;
     }
 
     unsigned char certFingerprint[SHA256_LENGTH];
--- a/security/manager/ssl/tests/unit/psm_common_py/CertUtils.py
+++ b/security/manager/ssl/tests/unit/psm_common_py/CertUtils.py
@@ -178,16 +178,43 @@ def generate_pkcs12(db_dir, dest_dir, de
                           pk12_filename)
     child.expect('Enter Export Password:')
     child.sendline('')
     child.expect('Verifying - Enter Export Password:')
     child.sendline('')
     child.expect(pexpect.EOF)
     return pk12_filename
 
+def import_cert_and_pkcs12(db_dir, cert_filename, pkcs12_filename, nickname,
+                           trust_flags):
+    """
+    Imports a given certificate file and PKCS12 file into the SQL NSS DB.
+
+    Arguments:
+      db_dir -- the location of the database and password file
+      cert_filename -- the filename of the cert in DER format
+      pkcs12_filename -- the filename of the private key of the cert in PEM
+                         format
+      nickname -- the nickname to assign to the cert
+      trust_flags -- the trust flags the cert should have
+    """
+    os.system('certutil -A -d sql:' + db_dir + ' -n ' + nickname + ' -i ' +
+              cert_filename + ' -t "' + trust_flags + '"')
+    os.system('pk12util -i ' + pkcs12_filename + ' -d sql:' + db_dir +
+              ' -w ' + db_dir + '/pwfile')
+
+def print_cert_info_for_ev(cert_filename):
+    """
+    Prints out the information required to enable EV for the given cert.
+
+    Arguments:
+      cert_filename -- the filename of the cert in DER format
+    """
+    os.system('pp -t certificate-identity -i ' + cert_filename)
+
 def init_nss_db(db_dir):
     """
     Remove the current nss database in the specified directory and create a new
     nss database with the sql format.
     Arguments
       db_dir -- the desired location of the new database
     output
      noise_file -- the path to a noise file suitable to generate TEST
new file mode 100644
index 0000000000000000000000000000000000000000..fc7e8d3ec2d9a9958b9806b875a0bc1cc30b79bb
GIT binary patch
literal 32768
zc%1DW2_RHm_sx4_-z7_up{!Y+8OBn`R@P*zC}kU4w(KeiZDgygEs7E;Ey@-uQHe^W
zMM)t<lC2HNKkp3<efqyG_4nsw&Yb(sz31Jz_nqY~?`CFV=;BMlIeL1#+xp@N02aVt
zfJHbQ001K74{r2>A%AGdA1pux4Djb50!X)kNI?uVgrsRHU(+xR)9~{Fi$Qdg9;!nU
z0?-ij9_oc&LocCbsDW~E8m3_yeo5eGCnFwKGMdRuMl%@6h=ZPt*l5X!1##ufAaaot
zS_?oQp>C*+to8SyYUm171f790p;RaVih{zS4bXbXnVe}FrePZX4$wnbjBL575hqHN
z`NeRcM4?(HJ4)nRjj*A_i8=MGC~;itG7Cx^{xrah5{Cq;m{20o@i`+(#7FWnpv0~%
zmh>nQk>*B+5+SjXv?vjrV?u)xz7A`#DB-=+20{rJFFlYB!ZOG@#VW7>NFc8dAb<Z3
zb`UUhJc5Fl7zJNjJ2#StkIyncJ2w~mF9fJ%s-t19gEQCAG}OU;xr`HcalkDz)icsC
zwZs|dSmG>}>X}&R;Eb2zw2YT7Hq_HH$7yI9o0?1EY+>?8j{L!sKLmtEFCbUskV{HP
zQVB^ap-Ci*l01SG5JW_fB7&3<q>Lb21lf_1GAatDU{oTEM=|9-@+ek7F%iXzC{{wT
zGKy_cY=>fdv|^O%QR;`%cnXb5#-oz)sAN1U8IMZFqmuEcWCB`>fR-Ylr3h##0$PfQ
za)~IHh;oT2mq_8FGKr{6MKq@p1*0v9{!%<lp^>t9w6^jv8SrS8M@h7;(cA<yHv!Ep
z4^wheGE%M(P%MvP1r#IqmPhX@kKR=t?H2{KtO8nA0j69*%G#3@2=W94IVy>#lH)SS
zQ%MCXNu-jBR8r{+Nu(AdQi~C(#fa2m#Ia&TYITUz>JX{bAyTVDq*jMWtqze|9U`?l
zWKx+*+EPh7Drrw89jGLUN;-Za(FcJ-+EJ@xhg8Qw!4`I~Lt9)4MuFPCL}dvO(SOJg
zQD8pG*ECGSH2g#04VA%$*)YJNnQ}}p11)5MrJVs<n2jaqnL#ZLIc}H>NzgH~7<u}6
z_}aR7;Fi0P0_5hxLdbPS=2=Fb8(iGnY;n>!o#i+OlAWIu&X?rliz62nfccS3Ow3$n
zBzr$^7vCV9j)#+r2Z`kE;^8DG3rizxh*@;yGA%P_lA9YM!kk=~%*Bb5Z|Cjj;~U`V
z?du#QL6(R3e;V)#07XKjkT!%RlhZH_zYr{<rRCuf#8|p`IFJJE*V(!_d<iWXMk7wW
zrP?|xaVQT7E60VNNR%g`MuSSQKqa`@+L7G8<e;A*0p)!yfgqucrRCul#8{){ef;cP
zN%p>9a?nkXFv|U7E#xHRKw2IhK@32Vvfj<bm$cT_&({-8ul<sHt=tz9(tv1r_{M&^
zi;s^V$@>eFX2N|b%&%{&Bsc2+4<HRGNcozEX_$up5ty?U8@dPsuaqN?u_%6h{ujS)
zKnlW{xojYP@$TL}wm3X24@=v*_~OKMmP^Rt;5n3tf`{ZUO=e4zNSd||(k>pp#s<>%
zw#Eh===>k}3V;rPeGoTf3FSd5P%u;ny@%dFcc2_79`b`sAUwoM&NL0v@XG=n#EHoO
ztT_2070kD^VKfi>ggj&>ISY~#$-_39hm{+G$MTG0vy8HtClP_(g`AOTG!NrM5o2tI
zQ8qn0G;fTJGU!Gbw6h?kNo5-w(2Qom&V*#X7Hw<*jdDQ-h?jxn@9pX7OVNLI09*;G
zgC*b*2nW%DZ@>poK6DU_1lL2RkTTQ`)j(UJbw9fYr{RANcp-TVua1XM_RM{I6MF0S
zddLN33lu+B<op(c17Q%Y?X#J~lXcSL7bGv*()zRj^VER-TMRaYA?6em6>>8_iT2at
zgvB?x(qy|{?q&TJg9Ty8EF!gqC(J#)Xp^>JrS*ZhaHl3K=5H~W5Qap&98*L?^!~Yl
z%B|o#|9IGA@iWG6F&GfWl1H<-W$8ZhOF3Uy)7$-|irbnsk^Wl@I)w2iJL&#`)o(7~
zmgR4%+nLoYroM@m_FD`Zgh8OgJ}_-5l7DiCNw<G+b<$fxMGp2`3<zQD)la?4%ffs-
zVO?D&>*>T6RTG+8kOz`yn2dpRB6T(Z4#Nn;EVK-g+jX~pV8LK8GyoKaVFSq58No0N
z2FTNkSbY#+kLE}lIJD#Vi@O>1)`PEmcRpEh$zg_btW=A))ChZ=QkgG!Lq&3lYN@zu
zm-^FM`x+|=t^iDF9q%LCRRap^9@JJ6T(hGX))OOX%WrAh7O9zNF6GfKmdU>FdP3<o
zpR-V+;EwhB-1aW&4F0p98?8$dd3F2xMKKno*uX<>&jU}%X?KZNtO=4(vd>JH)J<k2
z9%c1@5OkwR<oU<zdx^5c&PkbNeuit3Za9^{YM6B@GX3Ul`ACdQA**=$Bj#C&%$|g`
z(ueo&cTl&wbV08@`*>)FO>^)LU8V+$hIpPq-erf1EevZyk1B88mBkq;U)mQ)DvN0K
zG0v5s0U->4Iid+Kg4xJ{mB0)PW&}$EL*y@*6}iBMT);vgW;-l^q*<}tSgva`>9v*E
zn(;e$3}o<b&uW&d%*-0!%1mf0V*qdKOrx$Q&&LiM`4+b<F!LS;?k(EeU=q^4#7k{6
z)FX~%;>TxptFT*Ein@Hx2z<sZFLGqfu^rAXzV;oWv%+BW$E)<`T@2G+|0GJ1;gB%Y
z<vClZdgsG~frWRJh2(47g=Kd2Sl(G>!k#<Vzr0u)$8xz$#%`t*|HASkE_}B?2n~r^
zO5W4pxL}jj#cqEhFnvK?{tNB2Cc!L^HrWQ<8=d|qlk)dOoZy(LTEaT)s@<or{Gsq}
zRBgsUWRVeZS*M^3eeCM|2Pvw<dpEjf)LfRjp;y(RZ;$CR=+_uNX6we7)uELUZ>}a{
zuw$!laaMCuR8mgCgYDUU3X2YHR_uxOK%T{4XXXr~0iPG#dh+X3crx`z_waqu?i*kg
zL)f!w-omT&dvnV>JrZ0`9^YOo#@wP$yChE3>V9Nw$5!IIbHb-R=R3;IGY*Kc3%~5n
zJCOcHAj~w-juZ|>m+7ozf3(u+Vv5kh9fZAoJa4b}`+N?8Q*W}F)CqDv&6Jq4mSoT3
z7x<>+>Mf>M?OP4=9?tK$bPFz0UGXtF`uL^22L?1Q`RwDpqcfPvb#7_wy0?<dM)>>I
zVrO&IZyIjJJvMSmBGR9!&^_kY>-_3;!|CYH+jzN7)g?e8nYy2|QubQkw8eARbo1Un
z>9g@@kJ&!STl9q=53F96Z(U}VL__rW^r~ZzOz6_ZpN)kx7i}&!u$ryYDtWJt<|O;g
z0cnbMhZe)3g@4p<CRD#s<)(%8Y3b+FVrXdSFc_>Fybx9yOT(D$GS0rfUMjM(0RaIr
zq(EDDFE^5my{Eg15*cLw5R=KmhKOJsRtMICHE21>Vz8J_y=}9Qf0%Gz1`IqOmKYNc
zVz>oH#k&U~&xwPlJNcoKar3mdb(6LC@|n!87zjCSzPC}=oPOZc3mad8$Tg#!=smg*
zK39;khqzkum`AJ=_g+r+pg-qO86WOC_ufI__V5J!!gy(g09<a|Y37xm<JP=Bc}3Hc
zX2j3_2;Eisl5Hl3{ZAe7x>77VbF0cmB5oj*GlebU?A&lazuZ_2hNp*5r|?CcPo6EA
zbJS*oVl4;fjlnxD&3L2XI&G8OYYIM2=hs|c#{KHD73)IL^DZLFLRW`XH-su0>WgS(
zJ!NfX8(vCi?0Z94d`l>ad6v#@FIK_XuS-_uU2Wt_4$NQm@od$`+Q!+#^a(|0g)1-3
zKO3=rUBgwbZcn8VjSsgu3u-?C;oI)2cL6J2CivNi8~$Q;1qzVg1e^Yy5x)|3#6Jt>
zrPP??4^P@;0Rsk^{|5m%0P}*3{tAT4f&o}AR#wih8C;z504soOH)17oIkz$cUu9t(
z{rpov_AMZ_#Q@|X403_|HK|P_1HvQ!{qErk*_;8GC{9ce(qp_p91-9OvzaxnO~Y*D
z|FqrzRi8P<Dv-a(9YPsy!eLkrI1C&(Otzxnm<OF`vVI*+h3D|F$Pwh^@OU`_OoZ`P
zJS=!536CcK*MAAQV;Cv=zZw8p$>=*nxGeT(nF?PAWVhl3Q!%Oeqne7}J@!FO#V#iZ
zH5D>I+y=x{aF1)#Q28k~72Z2-fKgNNmFFT`4FVhn@l&h@>K}h;n;|a;%MoFMoT8ip
zVl$8=VKg}vj{jSudNME}=x^Uk5FOl-@5Md&Eaaa~Bb0VU5Q-#NgYEX;Op4HQJ6P0T
z-TB~tU9J`;yr#aOi?cDqa@C6chweMQc4bSMmp^cJK1naQzQOaYV!_AY<B26$KS;Hy
z*n1O?f9V<NctyjYrO7%FbGFlU4chIB=lc>GAJ!0R%!ZP~Qrx9H0#hztdy=cwlI<g(
zVi)V4AJ=JG#CuHdJebn89T0uJZAU-f!}jxgDwHz#wTyhSL<y%~x6CWykG}jc$z14N
zrh3ZZW*ULdcAm$o-?&5_JdxO9d)~}`M)APn6$OfOa;_BU3|B2^xg4M8X(CVBzx##!
zmP4jjJ#mr^nxd8dj>maU3uW*xCg@kE8Obg1;cL8EQZ+|nbfA$AhaQ5B#|<UOBLG-^
z+)#q>7lsmFwfzqmPwd%f=DF(tS6rs%a@Lco%{fIJDhqSg=oFaNw(}L}+*~E2%PJfZ
zdwEaT!5O7ONsYG;TgRKy6x_n`=?*rpDm?M#xUfXaHU1KTm+PE2AN8{GcK7P8R&v<F
zx<-51?#SWyZU@;u(Wklh5+6vv>$M$WceJ>ZYquF(AKuNT8p1SKY{>Rz{czfFri%G3
zqJn-=$(Bg5m7kut$zQuCs&@O88Yx@VvgVxNOX&l~U;=0V7QvGhf<{MVKRaFT%2_es
zxUZ{S^yp*pL(M1m^K>0voyQ{4U*nON9rbC;89RNO!qfRzGWxUNLV?=N*E8Oqvewa5
z*m`dGpp>SNWKKUu$GpKe4S6pPm<l}wv6xoOPI$#Xl>BE}IoT8=CH}{-1K<@5`@b;W
z|2GgWOZ&58mXO#;;H#Kr(k`RMEWf)MMPrso0u36oC;_qJ09U9y@3=M%Rh#0NB{;_f
z7$39z!4X1L<l#;(C2*mr_g9h2RQUUeF$QsBj6t*-voK>n9ya=i+Y4sGGbnXn9=}XU
z_VPl1^!}`f_h%q`e*k#K<t<Vvx~y~$VF=2*Yx-H><8ZhYN5^BmZ6SGQI##`IB~)+K
zcF(%Exa0i3mkQgL?hmmrIR4(~nlbUCy6?H!#-a<4DOU#BJUGmLAuoQ9zzy@wRu}_7
zSbl#+;0L;z@?bfI8z$EcWe3IklH+D7tI0m6+pU&us%Zb>;f>aS1TBMxG$Rg15B|`O
zn2c35Bf~ShUf1g`+#50A48LXrfq^zbx#V+l2?xscA~)O8yI~GIj3T^_o>36DtjRqw
zUyd_6z~qMO_3n}Cs%^(wX6aZ6R;PTj6LYK?S{U8_G$0ypdLdAoRz5`k?mGUO&x)3u
z8h4he3chk<H*alOV}50zeAM~p!=dN?WR_89Txg&SE5ZunLIa7v5E`J}G35aP07&nN
zGdr}>aOuY81zVV8xi6|P-3tknagCT?sUy(dsKRq9R&nR%0{@G`k9?2Q1b3#ac(-Wb
z_Sex&^bzysey-qRtyfdL@cvmOOIPYe&l`oaDo@^Ox+W109KBI;zFw+yiD_10p}Jg;
znbh-ax;d<LbG%M7==vN8(?8Hl`+*R8v|UW+gmyKvU{!^p+VJ3zXTF~QU=|#mUKAQ(
zR<^NnW^Ffn2V-9Nl7bs$`^<P!{MI>e-1J|7j|ieIkm)`o8Bj-Gy{0LoH74;2{Wg4n
zsuHbF^oYp4x~F~bxAm`<5DMM9L?#t{&Js8O;<7$9$NCMW7E;MfV&Wqg-8r}&7T1e1
zOo0x8(876&-&y8li;|=MUjhK1kkK@J8^UGi|5{+c_}v48U0W=HuL6Tf`;r<M{N@&x
z5*P5(p>e@HAXbVT7f4Q+%aEMnxF90U4HzF6j5<c>COI0&8=b~LH2kYz;5$3wiE)79
z#5h0^d6v+a|1ZTG{4gKo7My?FvGk|o{gPx=Hoxa=!2_h+j7mdqPLhqVdZJ#)29Y|<
z%E679PUb$(gN8LO&DwF`ind*>YtUon#?X~z$CvLGRFgc2h08cR4!*}U)O9{@jIL~Z
zz4=-y<j<47z2?-cyZi9`#rM}K8J2Heb$r|Lz^MI4FFJ`IND{HNo-=YTDfj>p?4`Z9
zIlw2@<BDne=XNd4e$K1RDT=0DW-DLaERqsg&b)+fd(_T3*A^(drDa6L-t=@!CGoe<
z5cNKjVBlLGJXq=C@dOIX-Fe)Tu{Ja31g|BVSMW{FLWPnGaYIR*%t0=9<$2$?FMnV)
za??Wbq)+aZoB)wmGTv)#VC=Fj=erIhcF*a7MqPdh99r}zF5h6B%U6e0;RWMdzU<#v
zSo|@Le^x|lUWM~1hX>~zJhUaX4Ok?FZyGq<whEwOZrJjO7kA0%0=+@8=S3g&eh(%d
zN5Q!q7Gg04MamHZZK(&qZM!QsI8-&7zZ#l5XSHz8f`&c$O#<`#QjW3%xYyFhhWejs
zdL7-rYIxRQPQeRF*$$!l?%0!e)<;SAyge)0!Eki7yNrp0QY)xmwcBV#*@uw&*Q_5F
zbTmD@cjLIrlExBzr|v=LboI2H^+A^V7;E%)e#l?YQWnXamKS4QR%>AR<fy7$1Ru9(
zF(%=RMpvuoc3O+nBQcV;w%iF~k}>y;_w{DkYrIVk{}^Xdo}RcqZ?U6o+;RrzzK;2s
zgqy<o23so-<@w%@9}DEG7{X@%a8&T$v~;p<Or!pv1pqIh<nImPvW!1#@So`T9Qew|
zPugEpAOE}CREm=)GN4W#24Zy)CqH5EPn=>WA0LU_?vD!=6j%R*?CQ%$2mYu||5RT;
znMEO29(|1emW7$*m4b=8oBuQzD2&<W9NcwcuI9^(9<clT61McU9oJSqwQ}D&)8mk`
zhVdFFOVMG~#)b!d(#Kr8iYlCAX2j5xM_#hE@@mX{`#SYXkGqnnd#T8^<_&)QCt~aD
zjyx_)-Wtxdy3D*W5k9PFwa5O%@U6@9-a=8YL>rFU%}Xwj==1H&3&n2WzR&(Kwe-oR
zh;$zRWsf7%JA-5MU)~o}5f?Mj=)Y_Emai+p<>9)Q9@@t?riDGIQUe?#R`~2rV!oKI
zx9qmrvnFd<AIWGwoCfLPo*9;NiIItIfhQGN*GB8xDt25K1_2A@n0tJD?2^%%CkM5}
z%#4!FrP}9jW4!-i)=2L%P;7{ENA=UWqrt!tIP@^QY@EB-hBe_u<J`Uc-<|yb5k4OS
z9GVgRbZPQl*9L1j7RlzLhF1sm@&evxH8&M$ySc%fYd!sA;=3!m?HoDmyj{u|j-(VS
zBwc)6D~%-$hAhOb0xX@kgxk1$v?_kz8s)xL`3AJYbx2mjh(&9LeMD>3mO7?u_it-Q
zJ$*cvxh1PkZe4cc*&Vwi4_sa%rcCFrp;G&hw7s!U{JHPeuJ&*}{IN?a<uivh*Qvbk
zyQLQ3DDe7zm-?wa7W3~0CFZUl30P=TXg6$g?x`xR`^)&JvD~e1PldiIDZk=O_t{Kz
z{~jB06|qg#)lAZPtGhb)t3O*iQ_6ku2v(JwA#@XQpFvWX$10)c92Q!Fft9g*8RvGS
zH5teyAsRC!{+VnhqOA7(y?1^7j$%%>@p;t$GXh`<hVft6!v6yZmu3E0&j0YI0pKg=
zKWS%Co&WD{Ln+Q*nF)3NDnP6Z+4&PEIR8ac?EDW2Q~}?d`KLqxx2S`CifVrq0ZfGv
z`6>=jnivNtS&cU@<oa_Vzh!h<zKkQV>D4`R`NG32X2l&Z&+d42(lpv&-l`tw!jC?6
z@CPw`vUXT_RQ*hjm-VqRSJa6i??55LW_zcLYaR%I`hHDpG*>IKVy#y`O3!Rl>(lWa
z7T99`Nb)^_hK?cMrl;7YGoM2SZxW1sMu@>1Ua?S)-LS(ic-@TJ_<7<BQdh3t^F&#Q
zLAfdOM8}ZVqRo1{S1(RvcxaLJI1y`jwxVL~=MK6~URUQ;FB~tkcGHFlogkSsbtug;
ztq>n(Gv1)qA1cM)=xZh3HN5L+d(~>+7mqc(V$M7sHa^$YJpW88w?><HQ~<%+RHp3|
z9p?$Fd&Hu(!rXpqKO~y<yXvP}Em-wK$LM3Pi~Rt9om-ICvc7ppRV2%(_3T;mV{3fs
zTVUOw=S9XBMlvl;?2L<*2qE*kqQji@A3hpt72YKRSG)$UglIh8wp!=iy$gw*1t}lf
zGIXvv7cCJ~s%B%q!BSEZqP{^mAj2}bx;<F!1?RHvnunyv^sXL*jU0@8C7T|^;FP^t
zj5Y{wzijX1)_mToH`DCm14901S9x*Y_3oNU`)matZmdZ^)^$|1wdnJqPL>lj!xuv}
zN8;r@N<MuEwDzX2yMM5|lL2$4XV<0T7$Q5~b|6-I{?Ppa={byE`!^|8#E6SXYfHsj
z_UjI*W<GFxxIoB$MWajAAiHqOd%2_~mf?)T#yzVfY!m{KC;Zph9|U4CzAU@{o@s#p
zyJ;AE)+T#ZYIOhaN&sXaqwfgeGORyqy8OhPdf+Q>I_XcRdeh(B@=><_xv`9nq~kUt
zTmOFONcy<eW#Frk^w?7ihhY`SzEogr2_4an|C7ys$`hTl@}z_Gf35c4UXCX>IX4pY
zvtcd);9O7~lm_vjBDfIL0Ow#Xfs4WYU=OAO(uXqsMc+=tR00+PFr1dyP<hN$Y$V}8
z#Iqv^L=YB1v<RX{5F>(^5yWba4VA=v=NT=!sSwIAWo<=cg$*TQrbL6;{(<PfI9y;t
z^dAIM0WcLZ{@D-nG)%)p2$jW#*<gMh2M_&f6-L+mzSBJ8xParoF93Yl9TmMH=iS-X
za8~ZNUh$L93S^!}S@>Cxtf~_W%q9?oOIM_n^LY`C?^WM(lrF5E`&P8zwFS#ixp%|7
z)Jvkey(?dJ8)az7Ebtsk=AyOJmcZTtSlep!i+VkayjroD?b_beR>v;s+RAS}QF=Qb
z*G9Z@=cFiR&ajyEzToVt)iEcfd+fKH>1mYg+PSXp(cCoL@Z}fI4JS6~2{(0$pR{%?
zT+XZ3fp2T-#EN%3fsNfSr0nLXukYKp_Zh7IF?gf*r|lP+4+}eW=c|Q+mxc0_tu<5N
zOD{6__QZSuh@?X}E0HyxAMV_352u~W+p^v<JGanvYrE8Hsq@*Y=e(Qxr(yx%hfOE|
zK<Yd2mZ)`yf&W#pA_b2Vb)R0yYqg%1lRB8CVp8$WOSPmODo?ks=@;KAI7>#E6u95i
zm4+vA%iV1S%tOmd1Ix=f9vp0Jmhvz4e6*!r8c(MoCT#2AdxKAd(-_MwBHUgdwM_yy
zk})%(xA*eSvNNZJ-$yvnpQRaeaBMA+m3~;lwbigR$dH~S)Gyz6JA}xwQ?Ygi!>(B)
zBK_;nz1Vjo{e1E5BYd|M#RBN|80fSeBuEe+*;h(s*9T{LeY*T%vxUFEvw_vc#YZ^1
zvO+$j&sLwQ<xhKu$9ULbzLv`JmK`yR9PW8mm)`8YYccboMXmkrxtc6?o%Z78p=WdW
z9i__=jhPZRPafO|ej5J%^Z#S=Cp%nabpD?S0824UKh@O#d<d6i|5*zFg=(3=S5p>~
z_7-)@;&->9lm!4Kwy^~OsUN-okZ&~tOtt_(b%Wz~`%!fJ-z)(9)#3i1%`s5z3%UB}
zyWrpZP{BWa0U#}2V4vzSqs2=N$}z?Cg$KIz+8Q<YylLlMG$^1Y{7hJ@{mv?HyX(zM
zXd|^lY9A^ldxf#2#c6L%XoEVII5V2Bbg#Vhz&ZBqmiYsAQ3)4VE`F|HW}VyHmm5CF
z`o8m2PE%^G@?#y^sE}QQ3SKMID*CLR)gI|P*t9{DSVq$HaZL46-76j8gmF8h^Um(B
zy-k8K+g{(+SdmPuhD)1VkU>dy$z0j<g`JfnWk=fM=LvV644CnXKM0!+UVU?5Nza<r
z!8(mK#+8GxLMjgbcrSNjZVaJsQEY#A%XaVH{Gz&Ty*sY9CY+ACsle7h@`}Oh9zzpb
zf~R8DNB=fm?mHUa*Z)s!`ya5NuxcK>!E#nLzOJ*GMrT<+sUX)$n8&==+lVWupKW(m
zq*U<*WnH<F?sUHer?V=fg3Qk5UWnj77J_+ln$PfIC%lI)aS`COU#4WcbE$ssHbtnZ
zsn<O28IRt&vt63Cews%v<@V(r7OZPey3y>8b15lVJ5rI5y09?*F@vb{);N=Eo(p>B
z`QDqcDY~HK_Ot6b>`VHd9(3<IvWqV^O^BIiiCx#{f*E=4!uGO6H`e(l?W^#5*=n1D
z<9d85TV)%BEbl|K2d{1l_M?v&o~KqExJg~;d81r%kEneqXVF%VmRGb#=}p&$B^~!$
zR27j;YnZTWv6$Du62AAnAtMD*QGweKm6@W~{~9VEP2E|alO4x4>i=1h{eS<)8vdU^
zxD4mdTD2%QH3Gg00VeG*Y6$R~ThY<|e;i{GfaD)u{+sFupv*4@m>2<k?FXT1as+U0
zECN8Z`$xb1hleKw0OTaqz>q6H8=3#30T%+`LU1?O2`z@w{zZ#S!*2ysGV4EO6ZFv3
zP0+JU-2^?u8f>T<X3EY4ph5JX8Po+pT`&uxhYF#~P$hH+s)HJ#cBlvX__Lp}Y4|nZ
zADmPFcjm6xrbzymb+BLU|Lqw&$$RX)@3Eu7$IcEPJ7Rq7IP$Sm%g0VQA3F{GXFoU7
KFb&i2^WZ;T`UGA8
index b7ea48d517058bcbc65a5930e2e522252218d515..c947b11aee4d6c182a4db36fe6e821b9add6fd1f
GIT binary patch
literal 714
zc$_n6VmfBf#MHcinTe5!i8)Cw-+-HqGoj6cF_oExnaRM#P|rYzjX9KsnMXAuz&SW0
zH77^GJGD|FII}8MAtbf9Br`8vA*DD`!P3k?Hz~8kP{=?4q@Ih16DX>ioamI8Vjw5Z
zYiMF<U}$DwY-ny|7$weY1mYS)xm2>HiE$PXOR}+RwRxPgU||Guc$g{~4m~&i(z##h
zy)yH|_my)+yg47QOt|DftN*WKoPhH+?XY`hbNQ;z%F93X-1fUmy6V8voK;QoY)J|y
z(xWt*MCJILlv^2Ya<Wz0bWYA+zK&HP>2&1&SLdcoO#PK!r}Ik4u=mb;?%I>8pAWa_
zGP1mwwp;K^&nj0_|H(|E4BK}fX!1V&C+>!Do!XncLlZ>*tSDrv;C7PKo&CN2PV;`&
zB&GZO(^lTqT;s6SmMh$kd1mK}@GtpA&$rK=l6T$X+y0wYwlY35ZavAk#`M8&Va(6X
zam909Uyy6MYULBLBjoc0#S&e&Y24d&qQy6uB$YBg&$w23Wwp}gb;`}!udhfPxGN-j
z=dOTBS7Aw8&x#V}Y6hl?tezzAdpkQ%Fw0!lsmT4ioqx~LsH$RV)_u>TZocPD&1_gJ
z(02Q^RH^Utx$kq1CiyR1#<Jj;TcEG`Voza~;^@4svspjbn#5i)uK0fCxG28^uf6}S
z=l<IdTvzr#&M5IBv0w4D@wb`V10z>o+%5C5>r++WkB7mZZ#phkFpx9g2gaGKFeBrC
z7FGjhAO%coKmmRhU`k_TLrHkd1`Gzezz|&Se)R@xZ>6E8yYPP>(YyT07MG4Qi3D8D
WukkGVoAs6{Rc~)Y$T^1}rk?<1k_^iL
index c57957fc455ca242a26c80cfaeb17468e7961cf3..0d23ff16acd40ab6df8cdb1bf7389cc2fad1b557
GIT binary patch
literal 742
zc$_n6VtQoI#I#@mGZP~d6Ejb-sR1_|XF{6?V=6NXGn0Xfp}v7G8*?ZNGmlzCfOBw0
zYEF)VcWR|VaAsAiLP%<HNoHQULP~L>f}w$tiEdJ6iJ_nYKS%=?4+l_KH#yPY+dxj7
z*U-e!z|hRV*wEa_FiM=)2*fppa;aoX6XSLu)?s7UYV$Z}!NLgS$TKxIGJNpueRrSV
z?cvETZ8?YBM<I5-AKDzQ<#8Lvsr{aM+}}^Hm@gn*;i&NYlIY;n)J?Y&_$Fv(EU>+Q
zX6C!e9f?|5GBPud^_eJhzuhM`KdbECiw~zt=SZkq_VdZJ9f{N8{<BW}r}k=*m|Iuw
zRxLTa;=jzRcE11e>K`k(lJ9r;O<J&-NtEGZ-OIP04Rb4Qb58zt<ZX6Decj?fkkjVw
z+<WqFy|c-q*H<qImGYe`jnLTnEcDm9pSyl9`!ZQ?k1_9o6`?bwmaSKu^^N7?1oQC!
zA8#zWTy|V+#mcIgCyZyzD6=Sy)HGeVexkVTIoY}p+1KY7k52o$#H4t|WVxcER?qI-
zBKMVYUp;3pi0xSr%-&PlS>nLduGDs3YWgjsg2T*>EeuSJ4Mkx#U*8Ar7mYvKs()f@
z?wRsr=k=};DmDAe)$<dqo^q`YG}--*dm3j%m1p^fp!QoE_xU;0-jryH*PMIh_nDWT
zet#cL|C2ZG^+aoh>N37X=lf?Z*sH}-;_^hXWZT!-0T-X1tbXM_`vj||(8JK0i-(*Z
z+<a9rudVZ<$f_JJ`zIl*7AqLYf#XwFn33^63#$P$kOC$|pa4G$Fc~tkp`=P?eFg&^
zCK2hWx^aakroEdX_HXr`!zS(m@q3Rki6}qb?D=o$beEel$NGe%Q+KRZQ_=?jd_N*)
index 07629f06038e7b03599ef159c6e983c8e65d7cf8..a7947ec96f63b99c0a3f0333dafccdea62a04075
GIT binary patch
literal 699
zc$_n6V%l!d#8k3?nTe5!iG|4`Tit-0jWeOmgE5tvg_+5~%TV7ymyJ1;g_%b!BEUH~
zBQ+;S!8^55Avm)tRUss`xFj<#T_L47QNhr_$V4|Ov&2x`Koq2bi-!*=tecrv;_t1S
zoapauAScdiXkut!Xl7t+Xl`T}CC+OE;u=G_2L6V6209SCRPozoX=VVnO4dLcVwDKU
zs?=1c#1v!;n;2&Uu_PP2R-4B;3l>Hohli<>;m~vAFP;09-YYXdd|x?N#GCW+%7jb)
zv-<x!#tArI(+<05HkYsZti1eF&uzcEq^k}r%~{nX&z7WcB0Wl@NmP!{Nx7BbCMR2^
zP3PqN<?C1#l1@kNe|2uk#MEEubvmzv414dq=dL}e`uT8+E+fl}X}bl#^sI6<^`Fcn
z%CLR+fhO<Mf8uTk*Qve9J2XM`&x%5(3T`J!-PzyU?=<gcO;WngKW*h*%{2~NZMnkz
zm}hpr2>+5_^nCl=DS6jDzU{whWh>(|<JOamYfK;f7RLPC99KN&^#!@6t5!Y{J3>BB
zP%P1Po5sCeCt7@iNm41}^NeeiS5_-+UZ>ow{rZZ;fxAMYckT+9bQPAg^{gmiu3-QM
z$Hq@LQ~mA=o|IqAJ?GSi4uhM2iqoIHe70TXe8M5+{VZ!fT%N`eQ@iPZ)im41M!TQi
zsyMf5y62@E((#O&l<S+C9oMz|p5<I47_YnG-|~=;KmUvF2|e9VbE?-X=-JG^`b};!
z&05{9!jitFK?W^Tr_|_6vX?%I`FHO-N<w2cU@*{S5(%}AK7Yi>X>)pc?kUs8VwJ63
eJ5zzd_C(lzdX2+0=AKKN4yJ|a&a!+VeFgv=Vi7(7
index 9b5cf38bf6f09a71c3ef86b2f51ad9605ec6005f..c01e16e6dfa83d4783f5997bb79e2ac6a9a86df7
GIT binary patch
literal 729
zc$_n6V!CS3#58dMGZP~d6APoxG${jaHqL}L55`nx7G@>`FGD>89X94r7G@sRhydr{
zjMSVQ1@F{Kh2YGpRE3b#;*!j~bcK}SL<LJT1Kp&|5<>|CF_3yL9)6&xZf0JIQ(}s4
za-zStft)z6p^2e^p_zfPp}CP^lsK;uh-(bx8Uz^X8|XspQp0bTp@ESJ*fLoIX^3Sa
zAj?uy{k>6aY+~FF#5!#3T5TTZELa$U9C@b3Murc*z3=YxyFEPFr7h=>`zXY&_d}b*
zwLEUaIJMtXkNf-S74rq8D;yPmUlJXhn!4$B0^bD9j0Lv$&&+%`xg$|4OGakqu|5-J
z?zj8I=4X}Nd-35^=^P1l%YHt2wj*&`+<(@I|I}VB5_9Xy-Kr&rSNxZG)z0@{Uj1VQ
zSMvQ1zex)=Gl?>Mtb6&^vte$<ZO+Nxj=ar|sIOZb2y)uooqJE-t#>wg^!n;0p;Eq6
zr4brCpN0Nf_jA|pWnU)i?J?#(up)G()Ux%8v%axhoM0aQ|Kp8Cm&=Zetyoz#^Mvt?
z8D$owk(#Cp*H09;JttciBK!Ir<I!n<mzWf<m@HRR)au!tTjah{?yKkQ1+hH~g4ugY
zJ4+mx+LhYQOHIFJRB)KNv4w%Du_59^b_KhZaCfuV+g*}I5f^v2F?^eqvQg}2qu!SF
zavH{8zuY>>+M==JwaE3fmotn$W(T+VrgudyUXt=4{X>IA-bOLA=<>1-sR;*sx5lhe
z&iL|ALhpUZ#InAw3zH@@2Kv0X^QlcgLwc8^!|Ev-izihYUY>V1VJ?^CSKeK{kN@QC
zLrI0qh71OJz%X0XBc{$~)^olvMPl{uo>i<rUOapa6rNYJ_RrbdXP%wBs>$dYvm=*1
Hqx~5Gn5HC?
index b3b083d686e299d3bb358ac9ca88dad5d9cb50d1..063df6a78dc81ea90fee3314c3bcb9bc90ee0403
GIT binary patch
literal 729
zc$_n6V!CS3#58#UGZP~d6APo`tJenHY@7*g9*n8XEX+&>-iG=Hx@^p$EX+J=5dqG@
z8L2rr3f`%e3c;CGsR|*f#U+_}=?W>ui3)}WMkcyRnI(o224Wx$Ts-_hVcpEU5`S;q
z<V2^$6azVNUPBW@14A<dV?%Qz!zgiHBM{dZ$~6ce-7;ANX^3SaAj?uyfp#I=*u=O4
zh;`W5wc0$+S+FnyIr2=6jSL@rd*9vXcYAoUOIyw%_fd#l?}s*rYkAy;acaM(9{2at
zE9MJGS2!yCz9c$0HFeYN1ilHH84GOhpPBh?az~<8mW<5IV|^yd+;8`Z&Ce>k_u|8;
z(m4|9mi>J4Y)9g>xc{sZ|EaxNB<9wYyH!gLulO(Xs-5q@y!yuquH^e2ev=k#W)fxi
zSoiX+XT#iz+nkfX9eJA_QD3(>5ahJEJNKTvTkmZ0==If0LZy7CN+UFOJ`4S|?&q%G
z%f3w3+hfdoU`6Omsb%XGXMJP2IKe#p|Hm7PE|(n_Td}fg<_Y5&Gs-MVBQ;GIuAeAw
zdrr14ME3PL#-r2zE-@)yF<GvtsMWJOx5#~^+*i-p3u1c~1he;)c9u9WwJWuqmzsXd
zsNgVjV=Dv59WQRMGR4ghC_2(GVb|-H83DVF1xU|$<?yo2{&D;q8;!M<8+UpCaSyn2
zcy^}acdlU8YTf;roBpWH59!s&^6Oju@yXr`jdxQ0Wy-VyM1|Qu2&(ioOK)lxIql+F
zf7<VV)4okJjy?}RdL@5WagoG=fR6oKDM$Cqv>wm=tHt#!IfS_#B^@&BGZ^SFiTL)h
t<`+%d@anLh{@fJH73a<zTE2lvM3(1yqf)K2u0Q|8=InJ0vUv_Rxd2v?AgKTV
index 97ad32b1e9e1b0ab4784fb70b39ed5b225640245..c391cca156216925c7ecfaf633da74fd41c3645f
GIT binary patch
literal 727
zc$_n6V!CY5#57?6GZP~d6APoo-@gXjY@7*g9*n8XEX+&>UWWPxx@^p$EX+J=5dqG@
z8L2rr3f`%e3c;CGsR|*f#U+_}=?W>ui3)}WMkcyRnI(qe2BIJhTs(Y0VcpEU5`S;q
z<V1gO137VCLlZ*-Lo)+oLvtg;C~;mR5Z4&WHSj0hE*S$Uh+V=UyHZnuRv}r~#JC-Z
zb=cUo+C0u#urLBS@=T453?F=Z-`(eTdw8--Th1Z(QHWjdhc<_6dEAC^YQLu*_xIB)
z<_kzyI4b<UBsw@Xb<^zxz6qKc3vBP7nfY#VN1|4ijLghqeJ0A>Z}*AK&nmn3;=`%Z
zITGrY{e1FlN8+@&|Ev@Lsl8ex=GK+FRZ9-9_%HLSo$tTA`o{{c<og|dlNM}d5@q;U
z_wuc0!`zD7oRhyDd7B+kU$;0A<g~dv_ny34?`-nu_0>y4rF^GKBQ$nC3;nh3=dRz&
zzD(BJW6XPCMd(baW$P7ZePg*e!94u`#~X_-mmL>dv9fCB3F8?v$}CDFHBA?;pD1p7
zPPQ&Y_Vqc&qtpH_F)3a#S+1z4)w4Ud$bF^USI^lCVtW<@v-gyCmN+oAE47`Mntscu
z;4pJz3j<SQL%N&dsy#ZVI&LPE7W{8sKj&`UvO}K(nXc4XMOEt;F6g^bsO;hW%!#Wq
zQ~1)QXFl9hwr7YPEd4MyEB8`C*wZ%oG{@u7|L%6(FW0lW_eka6k|?*M>)zg&@y+t5
zm-N1eE5Gq&7&$DT#_@ND=AW`#v-VC}`zpC{lSF9OkD9;9J7a#lMoEOs1`Gzez%c8S
vsGFqX$-F4-O3Lz$m(MDzubTIXNhE2{OTEix)ytZ{E_olyVpC*!;b0*E8zCwI
index 79795850171c81c728430ece330b041a35e3aa57..ad2a39bcefb5d9b521f9d9a5b5707a912c9ffd6b
GIT binary patch
literal 719
zc$_n6VmfWm#MHTfnTe5!i8-b6l>s*!XF{6?V=6NXGn0Xfp}v7G8*?ZNGmlzCfOBw0
zYEF)VcWR|VaAsAiLP%<HNoHQULP~L>f}w$tiEdJ6iJ_nYKS%=?4+l_KH#yPY+dxj7
z*U-e!z|hRV*wEa_FiM=)2*fppat*u;^$c_%wy5H_#nQ|GY>9+{7{n5OkR_RUB~FPc
z5WAWfX92M!8@pDU$2kiYMj(fWsgmK)bK@_a`<31+Ge3M^IakD+^YO}rOa8O^|2oDA
zIA7BayJt3+ullUK{8P_uzq_QX4lK=C)g;fBq;MiVN~1|sj?YQCmEk5QTcu6s<oxC9
zSQU~^NA7=hZpy^eU+Hx^uY?SH@4V-(J*oQnaEmS@%Zq8d1;6yHay9jz%p}UNefNPT
z@6&(cZV1<@y~#T?LG;gxLZ%9CCrRDe-`npr?`KU?y3apt<z3A+4qI)x!u^<McD@Mz
zl3(<E``jsc*FC=NziDMF<1^#dlZ<OjAN&@^{M;N@Jm>WVxu&aDJ`p=YK2K0A(RG`~
zy<I0-e1l0+DdY2uYn4}4D{Wq<+^qfjio}7tLZWx>3Yc^imbCS(C}FN<V5*4Ynf7bf
z{M|hPyw6`Jg}vgt;C^|6Yl&csa^bE^UZJNYtn0VjU@hOfV)^r|<C6EMC_X%DvXRqa
z@iI+T+Z}6|9!p)hd2~(blLn3tTV}N!OWJwb@<FY?*R1xJ?~aMSZuwl%b=2lXRl}yA
z|1;D3@+H_gR{ZME2{`pr?B!ww137T=kQHWR{LjK_zzn2-DGn&W&jL(ujBF^$k6E9=
zK!-_0F?<F4oR25^=eBx1n(y+gaZcpL7fd3lI%_{999li!SAXxl`X%SqNv-lX1pvlj
B7ViK6
index 09476591dc20b5b84e48f170c679cdc4d39ac768..035ac42e0c72c98716487764adf9a7970cf1db85
GIT binary patch
literal 751
zc$_n6VtQ@R#I$k&GZP~d6AR-Fzhnb$HqL}L55`nx7G@>`7ehS*9X94r7G@sRhydr{
zjMSVQ1@F{Kh2YGpRE3b#;*!j~bcK}SL<LJT1Kp&|5<?*a0g!qw9!{XBZgQeiVv2#B
zIIp3Jp@E^9fw7^vkztfLuMvoA4CNYl8|oYALTpjPZ;PRUkqOuu2?H^RHT)oJGV@CO
zy`h#hG423j9X58YHji@_EQ~;oJX2#M!w28qclY_-9-i#dmUGB`6k^x=q0Ql19=Bnf
z+V82y{r&Wc`2x}vjtajoi4IOp-E=#FZ-QpV0^9p%X1<%;k*Jj=BQx_@pNTT}+kIm5
zv&!zh_;9Lpj)b~pKc76?kvJ{xKkLMQYOfZFxpn1k)sn+2{>!{-=ld_O{;`59`F@Ar
zqy?LqL>WHTy?pE0Ft_41=j3lk-eyPC*DVeNIc@IFy(jP1JDWUuef5%1Dc`Bm2#uZ3
zLVvCMx$F0`FO&8581o)j5js<9*?PrU-&ihAFc1I#@y4RdWyi%<tgM=O!g$7vGK<nk
zP1A+zCyLvildTJpeSMDc=(N8}Oo~@bmMbc1_3X|qa$hO;)pPcO*q#N!>^-HOB@RsO
zN^R$*rr$CuILzGG$^df5y_5awE7*6P`S!<@n>j#2^s=W=Jl~$#CW6!bd7dmQ{r54V
z;rahpKBufQSD*2_@-N{@f8i|lKiRJT*R?G^J4x-E#l1@gw%<xz)F0grEe^A}cBoG7
zO?&(v=VkNKLIc+ye!cOggpc9ZTPbIjD7Q^Im?|B;u3#gR?4{`a-)=SK`6Ml0tY9E#
zzz>X9Sz$)T|17Kq%s>j5Ab|q>EWqT*$cB<Sne`bAbeKfazAAX>=I=L2I2`XM6D%9j
foNBa>Nkr9d`;m!@)o-@ivVFSP|NXP(ZgE=xbQUIj
index c12bf8851064c59d9abe94e33878c1e6766d0ae8..4a1a9a91fb2e17e13d99a05115e825702b95bbfd
GIT binary patch
literal 750
zc$_n6VtQrJ#I$??GZP~d6AR<=4F?Ul**Fv0JQ!1%S(up&TnzOMblI3gS(tg$A_AO)
zGg5PM6ueU_6@oLXQWZi{i%T-|(iKvQ6BP^%j7)TsGD{2v4fsJCxOg~#!n(<c{@w<1
z;=G0?h6aXa2F8ZwMut)1yhb3dF_dfIMY=8G2BHvK_&~N~=9Tz+L+ol|+z!M#Z0uTX
z9_K7r7=avlrp88w55B$c?(@4nJlUl!=aBm-#IE;4o5Qs{Zo@dW-&2qK`{@<)1*9t+
z6@Fh59h{oF>2?C&1kH>Ew)fA>d^foxQ7cPEX6CUz6J_qV`^4sFmEC*s;Z*4y33bbU
zK6$nyaa!De)`|brUM&)H>&o4#C5Ko1mwDCB_g`N9V+B|8{SLoL3pO)}GJLFi`PQ>x
zZpCfR$={B=&5o$ATO0^-+T5LcPu{I}HhJ{=>LsC4zEh<U8atnb{#y5Q*Y9OtChP4n
z<~^_?bf(m@^@_8;v0R*B9{&I1jYXHsj*G2WSvB*7@r)T|7NwDzrVH0k6t_JmTNfhx
z`W)lYX@8fP6t9>pS5(yM*_~VDzEbY1=j;WsJqv=_drCV?9GKdb+RjT&zhzW#n7Ofq
zfvK@UU-Ep9=%u?XZ_?R!PEMMBVCT*Xb(`>sOJYCvM@~_U>}e7a)7hI^ap-~8o{I%}
zzBX@`)tkRN_H@cAo$AeRm1bA&s#{jc>=_kntf3uJqws?v@(SDY-?c{{aRk1P4-;Xm
z^$csjuzKI(6USZU@_s$}R3^Uf9oKB@dw)#2%fGx!+n2jo!9Wh2c4UPa8UM4e8ZZMX
zU~&Ws@Us9DBO@D1+GI9hFwkWZiC~{FWnK5;IZYb<3pX(HM6Quv?hXv=XIq~5TFvM>
RwD_Bq+g1*{r8%rG+5vZYBwqjk
new file mode 100644
index 0000000000000000000000000000000000000000..eabede0ac26ab3d3eabc6e175c14ffc35b0d66ec
GIT binary patch
literal 976
zc$_n6Vm@Qg#I$t*GZP~d6SIwqxdAU5r&gOs+jm|@Ms8LH17AZE10y!(P!?t$?T7&9
z;EdFq90l*xN`>Ies#JxL)Z&uNymW=4;zR`_0}}(?q|6cp4c9PDLs0`^kS;DBp42j3
zptNpsqEljuft)z6p^2e^p_zfPp}C=XlsK;uh-(bxQro&FMnz-~F|sl+H!<=t0L3|(
zniv@v?uitso=^+eJIVMr^VW+&|73ssZH^LrdDFACe(Q#p(Qlp_pKfu<U2)0n<(65`
zP22ot*N1wq{N{Vi-|UBd$z~aUHJfFYCn^)JE)dwYb;=~!lOc6cjNS}NCbN%Jd}lv@
zxYp40WZ-ch{a+fNW=s&Zw9~)OKGAMfka_asYbT$UPj&XbyU<sVD^I%dW#7{1^Z);f
zzI}7s!)9{l&kTb%{7ei#pUE4}*laj;&SB54x<rl~#yQt|jNkMMZ=VqGFn8KEL!sXC
zz>`_W-~T^-s&&~DDc4Z>(=-1hsi&R)ZPWYWPI<3U(5?y>Hj{d<i`mlW|CvV$IbQIy
zm4B5Z5c2d%T*#rHhnbie85kEgZZl}yY`_l;KUrZ$#{Vp=2FyUpfEy&h&%y#s8f*rx
zY#iEbjI6BejEpRn2IdB)Funm}n`TByNr9EVetCJhUTQ^RZb43}UUGh}l?4#!BS(k6
zfe*+`1r}EWX9GtzA)pB?jITXgr9hCexrCF^K-)kQW-=3_m@L%f+{zMQ%%|k%CT8a8
z<>V(P=IAFE6r&|oW>AFcPMQ!rKf=ea`jK@5x4zguEAC766?$2n+9zCPUp%l9U)OKm
zQMbKppVIY`m8`X|XNG@uuxWeK%gxcLqWtfO2;Xfx^IhNWb@9HPw=e(X4yhAs&OSV*
z+03xy<en|Jb@sXkt=O@{-ta@P&iz&Fa(wJ^1?xFIisv+W&H2do-MDed3w77kE~k0q
zPaQG0`}^y6{x;9DUn>lH7wv593_e(WLiF-`ftOrco87mcJUA;@d}e8Oir|?tYopFe
zw(WZF=WCVU;5Z%ku>NV^v_l-NM&-5^Y{k9*RWIGR^XXgb=NL`J#>wt_^O)}QPSD;L
c@X0RicGcccof+Kf8vpm@3W}w;-B#lS0MP(uZU6uP
new file mode 100644
index 0000000000000000000000000000000000000000..c2f4fdf85865e54b4eee235bca2bdffe94b7f0b2
GIT binary patch
literal 975
zc$_n6Vm@uq#I$(<GZP~d6AR<r6W0xR**LY@JlekVGBR?rG8hCIniv?dF^94+^Jqr|
zI0t8>=Hw`Nr&cNiXI7;ugrpXiWagzS6cr~b7#WyY=q6>BC}_BbX&OoyNPu*4@d&1t
z=>ny7GxJLPy>*il{k;w3#CZ)(3=Is;42%uUjSQm1d5u6^V<^`kf)qOq5OyjU$U*EB
zhuWE%>Xev*Y;zN%BC-b=Ss9p{82K20;+#xPj0_A5r^wE-UFPfN=Y5!QH^+`S?>(PA
zaGLb)g@nT|S!bntO3p7XL>DC;f8@^A<x+q7n)!@^Cf<b;Tw10+V}9wL!4(pbdt(39
zjQ%eT+CP(ertae1_wNV~pYq2~o0@;|eS5ub?ZbJSEN{B9_0)I&GA)Q$c;r*my~~R~
z&3#zqWOgvssW@$3f$e17&UD6{`L17+E+!{T_2-{l^0Z%dIg4ZFGs8;nJ*)O8>u=fd
z`o#Z(i(gDpQF^<kT=<oACCehFqwnUpe~5ef>xN^T|A}7)rt=hxZcY|^u&K}ZlSBXK
z_fOi2K5pB2qxEC^(Wg___na~1|NQ?IXTc@Thx}9X%}@O(d*&f_!I6oXk%4h><6?ux
z1qK0Z9NKJ*tgP&ej4Un&P6iGzz5!#KNk&OYft9{~d3m{BYDHphK~Ab(a(=Fr1rX@t
z2zz}4A7JFjDzLa3I2$;!2>}gbVSMe`Dg}a!%_W?S2HFOiFiV&i#blwD<W`mdV>~54
zH!(9$FDE}aF-JeSpcpNk0;7?UAzH<tDpKmS(T&%SSX~1?r*7Yrt|T7vvB+1X@-zR$
z6<s>JcUgKE?s>nc)O!7j6Frr|8#nFhlwMZPcx%0+&$ZVElh~&@Fr?4c+tZe@*Xv`e
zIrGDZA44YG6Zg#C_}1xisng>9n?7w_Ab;b<^plTr6*BkiiT{6O>O7krQ*LsqWwcBP
zJeF_$L8au9a82*_J?HKnUn}7L>CW8Tw~M<a`xh$mh`T4f{kL6sYpznVzF7{R_L}5V
zMxLweYHBBZC_eF2|E^->6=t@%M{8<JIXeHU*zK;Uu~)qRz;MO~wdB1*J6rOeykc9z
j5ftAvePyY`sm@hwK2y8h)C+#POMd%U|9^W=Pem&L-^zOa
new file mode 100644
index 0000000000000000000000000000000000000000..3be15bfe7840fd23cf980260e9e9d9a2f7d6147a
GIT binary patch
literal 976
zc$_n6Vm@Qg#I$t*GZP~d6APpKpT7pYY@Awc9&O)w85y}*84Q9AO$?0Km_u2Zd9)(}
zoP#q`b8-~CQ!5pMGpkY+LQ;!MGV{_Eii#5zj0{W+bdxem6f|7JG!3N<Btg2kc!W~R
zbb->knRz8ni7C3tiT>UOa^k#(CWZ!vW(LNF=7yG0;=D#6t}&Er5J8Hi76?lf4CEk|
zibE|;P4)LivAKy+3E78?tPIRejQk8haW1ANMn;D36MK5A)_&diw3$!r*+-2v_qOZZ
z=?N{3{U3cpy<(NIvC`h~nTI6{%=|B%zLciB<FxV@we4?0d4C@+x~np8znaI#h*$4@
zmpbZM=l`A|!j|Ns$#Q{#@7Z~;ogede7CdEH{=%i`bkwr_9*HJ(tM{IpqVUY@(1kT>
zjB<a~V`tT_Iu+BmM)yN<Td=3&p6-t9PuG<fD*Qe0IOFc>8c(H%uQk@hrtJumuzP9r
z?BQz`jhD9!{Bw8BoG5tv_NQ5s?-|(tsI4yg)3%Rifl~VWZFY@J2Nbtj#yZV3*#CI>
z<PUw{8O&1WD@3Wr<$u3$@kKM6vc!|Zv{jpSWVO7|iP71z%64<n!_Q32j0}v68y6ci
zE-(mS<IrYfWMyS%WMpwMa58X!@eLT;OfpJJ3as??%gf94QY#X33vyERlJj$|EPy~C
zN8sxl_yA)^R)NLUz}di&O$cZh3*&3gRw)o<Y%bwsG|)ECgjvGGC?*TFB)75z809JX
zxrv#1dO7*Yi8=bo1;uD76&Q~U4D-G+omGo{>0NeIeWz*O>KlI^n>asRZ>TeOg;n5@
zuLZVyUN9eClzjfPMu)tVo@Hvq?4T@G@o5bgTetK44%=IC_^{yBxep%cl<m#G-f&yj
zh}}_LDKVwwq@<&eKZ}^E(u><Yt(pq|mx@mP`0+r;!42z`zICQ^Y-IhFlJ<0uzV5X>
zA}v09D}6Xp6+fGNI#+Kd*kOKIn6q2zzv}10&5vg-UbJQRxy6!a&DG1<CwaR*n`^9T
zc0Kuo&Z^tBD+>M`_+A%UR+ix%wa;y_(AyRD-xtZ)i#nIFT@d&Go1*P(751dP&mrYf
i{^`AE-d_wAy%u^od7`otZ_?{zjl+!_*Gi}99tHqwIdo$H
new file mode 100644
index 0000000000000000000000000000000000000000..f04231307a4fd4d41beb058e5bfd75261cc4c5b0
GIT binary patch
literal 977
zc$_n6Vm@oo#I$t*GZP~d6AMF6)FcC5HcqWJkGAi;jEvl@3<kl5CI&`q%%LpIJlYWf
z&cPX}IXMd6sg(-BnN_I@A*sbBnR)37Ma78<Mg}Gpx=EQO3L36qnugK_k|14NJVL2u
zx<F~&%)AnRZ{6fXr^FNkIdNV?6GH<-GXrBob3=<Lab6=3*BHt*h#=Ea1p_&VrQ%Ra
zQ&WL<BHP@=sD$i8Mpg#qCPsb+pg0#(6C)$Tj=t86+PABfot`iK!1R8LJO85im&YRR
zMCG=K=FPWs^p8uARQqfD;O^B=y34ZO?mUvwC)~$+xNCo6RKbJgU*60+^dZ+mEqAZ#
zu}4*<(yRM#BrU#qa7Ifrcg(?%2h$7|m`6=YUj6s%0hKSzJ+IX6E=f|Ev0d|1$?L6+
zELCDx1b)ohd#k2%k$73a&8|hSYx}o7zoKrXp&sb?`C{Z3$+uH8uVp{ab6Hlsu<7b4
zJBGB*@ZyQndG@XH3^*5j?_sQdu~x67f@A8nNy3rJW?j>sRje`Ri|_SHG=F(qiHRZ9
zvhR|lq<~hh)0$t->cPG<LUdkew{l(iF7^Lo0F(M}q4v{vl$n?r85kEgE;eXfU=YB@
zq0Pp~%F52j$l_w)WZ(ef8!)z+WR#Q?Sn2DRmzV3MRwU*Y<fQ5)=jU2k0D(S^z}GkM
z0mhE30*kAGvw<U<5YR9d#@C*$QXt6KT*Ap{plzTDvxJFJOcrWMZe<BD%2V=l6EpMl
za`KZCbM%u7iqTRkGbsAz3-{jfn=v`-Zmc1%)}tjpM}K*4E&sOS(ZiiCIXMPG@%d$a
zQ{JC=pOhw;RFrv;bMed_rqlPmxva~Q`m5eXA(|mFqoFw=^GDR~Z%=!2<1J4zhiCoP
zcl70T7EbPbdaB_D_pvMITzc-@ROWfI;)Y@Nss|g}yS3&Va96ivFLSiId@Z%@!6%LT
zB`t4XG<zB?+i!JP^siI4)wfS)?aI?+-&}cXziv{f_QlF+n+pGz+a&Br`kS!%jxAg6
z^C@@w#h!jy*Z6MF;X@hh|AN(KPfF0RQm;9Enp<~k%-h$q?eE2l>g2lpXR#IIY^*Vx
d<vqPAFIw@wV5qZv#fg5&rJLIqKJ+%64gl!cb8i3u
new file mode 100644
index 0000000000000000000000000000000000000000..0d7a0fe87b6e83f66f2a06a7dfd0d2fe9cee5543
GIT binary patch
literal 974
zc$_n6Vm@Wi#I$JvGZP~d6AR;0#ts8sHcqWJkGAi;jEvl@3<g1lCI&`q%%LpIJlYWf
z&cPX}IXMd6sg(-BnN_I@A*sbBnR)37Ma78<Mg}Gpx=EQO3L36qnubya5+Ge%Jc6lZ
zx<F~&%)AnRZ{6fXe{Tahab80cLjyxI17kyTL$fGxULz3K7|JyWC(}-O16hcjVo*C%
zQ-M|@S=_{^gzP^?RtDxKMt%mMI2ThBBO}A!x1Gj2HTi0jW}lhf>6|ln=jYR}uU@&a
z$(gbF{O#>;g&r)8j1HeY|4RCsEdH4)+kS4;PW7z4eK-G$`Su^RE2r&YDP^{OxVxxE
zyln3V-6`fim3}i^nR!;FA9rMHGvD%Q>Vs?Njn4=Fp3yWjS0}Gx=DuUMHaS08Rctad
zsXuqygx5hkC6;+^VVe22jX~{AYx`%(YcIA;I%2U@+S#{wg_`mDH&0adNcSGNHa$e~
z>vH><3m&n`{!7YVcKTgr&)n71o+NGwP8Qz%(=B|vx!l@A+g<;jvVL-4%GUfqlhoN0
zADcAH4?3E!pmo<t?L=AHO7ZoIOQqe6y-qLmHMB04d~jyZDLG9hW=00a#f^&$8s{7M
zvvFv%F|x9<GcvL`8#o%+!}tb_ZN?cTB?VUc`sL;2dZ`tOxdl0?ddc~@Ru({@k3H=5
z4SaxcBdfsTY5+8iO$cZf3*&3gRw)o<Y%bwsG|)ECgxSHwC?*TFBe${y7~v`Txrv#1
zdO7*Yi8=bo1;uE|lo=Fzld6OByXS~ZSnd?Yx5oC-+MR+{Hf!Ttw+CH*A-Uc4OthW{
zpHgT4fk{nsh4(5>e{gO=?35tZ?PnDvJ$^lk-m&`KN+r!F$E5ejKF`jmTT&2Jlw0ur
zv_(n-Uz|(8#IC>Ja^~{?;aHga(d?@3*N=(+1=2z<Y)YzQDr|nwZ(Gm(Yqt;oyTZQ<
z|1P%*IcsL>wR2BHmwLpXTRA4jE~(j_du5lp$~N-+X8Gs3bNrd63Vm*nUvos>cd`Dz
z^y6>WhW|{P_4b9@lA9XyAFY`!{&qpkR$k4|=kvC%>iN^KA;~LY$NFuDmVRDgutWB8
f-SMU0*2TIynYL{HJ6Fd^QETmIM%R$LB@0yn7H)X)
new file mode 100644
index 0000000000000000000000000000000000000000..50d382c3117549d5f764a8a57cff1760e175f17e
GIT binary patch
literal 1081
zc$_n6Vlg#nVwPRN%*4pV#KKs@JJEobjZ>@5qwPB{BO^B}gF)kRLv903Hs(+kHesgF
zU>JvkhsoK|P|QFC#9`;*_02EMD@n}EQwYmUEjLs)Py~r{@ksgRS7qkpBr51CxP~dD
zq$ZW7E0m-bmnZ-=%Nj_76mj#21g9pK7G;)HD!AsQXXd4*7G>t88|oYAf~1*w)FJ|$
zgELZdazI9e05t<;6*Pd>6_pm3l;;<fWK?Pb%`=b_=QT7jG%z$XFg7$dw2TtxH3D&s
zp<IJtLlXldh>_ZGBfV2A6@oLXQsD*{6(=ef8JHO8CS{f=Xt;)H8cG{TLOdgsTBZw>
z*3HZ-aY{_lO-}UpHfUm0L=G`VRtDxKMm`3hI44sRBLl-h!HS2kE`^xvSil>+`{nbE
z?XT7Z^?IvBf5_PJqxgowcXgu~E=|onw?ze?-|p`_WN%jgl}XX(QF8jexT~^EUZoHD
zS&trB(H|ReebMq~cAs2J{>nClT-W+$%*xKWE#brN%-7ol^^5{*S?(G48TlLvwd}8I
zFRjfMzC1-m!+Kss%%oeEiky}Ym#=>LyTGB&b7G9!G|p?GD{f9>@!5FfNc_K-?5`!V
zGNK=+9pHP<)}**PHSpm}3#p(Z8h`oytL#2E>PSB*iPCucw|mKpQ!yovZ#owAZMgZ@
zfAiZ%+8gGHIX)}uDL0M{(tEa!U1)XGC9|FJN@At)-=_tC&hnZUWgX4L%*epFxN(m`
z<4yy9U?|E8Gcx{XVKra|QU=^00e%)1VB%vl@Mh!CW@BV!WoKk$u{W?au!ivs7~AwS
zN=gc>^!3Zj%k@$#5_1c3QuUJabFD0ZKp!(w^bLGKCM&SG8aNv`vIzmrVPSmj*(wEs
zjLjvSj0V~UnlSU37{z3v=I2&|(q>A2E-)eM<>V(P=IAFE6r<$`VEi&NY}&r{N#Ud4
zwyG<9pKjb3vMjFn_7ek-%KJP0cl}=;8JOh1+rqeB`)zMiy4SVqzn>~~s~Q}6!*HnH
z@n&m`>(@)WroG-i^T)HLuE#QVy31Rf<`+20yJt_meU(!A(#RR7U)0(?77BQO{#xoy
zj;y?24+Oa+_taeNQ?M-J^{rBBJCK~7^Jq)d$K}EMt{QLqmt~?+Qkd&BeO99Uwd(VW
zmc3nK`*i2O`LB6bpZ~kB(dqvble|5DzE{K+aoo5v_x)>5#tk33_wVjA6EI5r*{`ep
z`^ryUIj(})HReb9G*oq6bf!dp_V{hP{A$iMYsKX72brgS2`D}JW;oqFvYAWC|3kE9
Hf@uW+Z}Ex^
new file mode 100644
index 0000000000000000000000000000000000000000..3147b266c44938b472deebeae887c6d8c923f900
GIT binary patch
literal 990
zc$_n6V!mb2#B_K8GZP~d6AQyOD<1=1HcqWJkGAi;jEvl@3<kc2CI&`q%%LpIJlYWf
z&cPX}IXMd6sg(-BnN_I@A*sbBnR)37Ma78<Mg}GZx=EQO3L36qnuekV!XRB-JUppo
zx<F~&<V2^$6azVNUPBW@14A<dV?%R8^C)p%BM{dZ$~6ck#X1Xwb<zfs5bK1X)@A0E
z_<KVwZDLeH_7)>619KB2KLb#li>Zl`kzvmaTmI7f{Ix$*H!VHkQzVp{pkzPIv%X68
z24lpp>gDMn#rG@!I_{ThpL571sXwdoCeMS$h=VJ`Cd%7s&1Eq-D3~|*8{^#@ukSzT
zJ@M>K-LZMhW#Wt4&aacYILk<S_myl5pTl+0D_d7q^vqteFI{8Kbk)RIx&ND|*Um9x
z`pCAguDrNE?@-X9e=nS!J_{Y?nQ0#MHaOzdnVmYSVLa~aZ9N@w$E+=L7B21SKa-y`
zFID=5uv*cEsoo`rYk!@{%)7<hw5eldKG)^tYgbD|@)y*e5!zw8XV-+^(}j2{GcTG*
ze0vdgHR}JFQ1dm#n+~llSAC^d6rW(g640>a?VM@v<vuVoF*7nSE^gdo(74lp9~g|X
z!i<dnSy&C2fs_F^NPwS(1(-zG47}MmwAmP0S=kvGS?mpL4Xj~&1I9M}jFOT9D}DX)
z@^Zb@ip1Q4oK(H!{9G#wAkfE*6@3FAkjV-xt_IEqj%-3eb66N(d$vk}AY*e0C!>M3
zfhNp+CPpz?sQI~-CBS5mlAoKHnWvYNpPZPZpIlIkmTrL&%)lVkIdAKcjCCnjH>c#e
zXt{XvYAK!ZPB|A<&dPJQ;ktyve&1aj-n;Yn72AK#;}%boR~8Ia@7uo9vQzfiyg5v*
z6Hip7oO%%Q>bJ67jM4||yOXv(l-2$;bBO?h!W-RXzdzq`Dp)c*`mfZlwc8(S>AzIG
z{l0(Ag~A@)4_`K_z2saHldBh)V)2y8>(oTw@Pps$Z@=ODZvFD%wM!>gX1YJvWAxf%
zZpI?}g=-5dBWH1)_w4w-&HBl~E}n&3`$7(0_V&58#5So@QcP_(<J1j~Z=b5Qv4zfC
z+^3b8C^l7HtM8KktdA>_9ly+I{xKo&@S<sjTiwzUCxmfke0r(9-1v;rHt&`r0Pdl0
AG5`Po
new file mode 100644
index 0000000000000000000000000000000000000000..660da8e45d9aeb8a0857c4f6f6acdafa260b6dcc
GIT binary patch
literal 1079
zc$_n6Vlg&oVwPUO%*4pV#9VGtW5CPCsnzDu_MMlJk(-slpmDh&w*e;`b0`a&FjHtS
zjKjgh<m_lDW*`FMu=DWx=9lJ`BxdF*gk`3d8!8(pg2cIaq<r(MGIMeg6?7F`!xU0d
zlS<PSN>YnU6o8s#4WvPexOqf^Q<F=JGD|8IT=UX1^HNibGV{_6^$m1E(#$++5dqG@
z8L2rrAR|J6nt`$k8bIrcN{dU%^NUI{Dm8)T8OVwA8k!gy7@8Rv8=4!MMv3zpfw;y{
zu0fEYiGdNsNNu>0-l>%e!I@R5aD$7A6BUdMOe}PhGD{RRT*EXCr3@q>o)Jtf(*;WF
zX6BXnd+R1A`g<ERF)ASk7$YkKa}y&!15licsfm%1;Uv>3&Zc{(C3YO;n7rxm>%6I1
zYgV>hR_A%*#pXUiE$T{F|H~G$ubY+D=WD0wtN54qB{d(&mH4^noorK3MN(=rbMHad
z2!ZPn>HB6X+O!)_{v`h8_~+t(^#=3K@CV+I7rL`tQ!YL=nYXm!-JYXoxnI3#@!5J!
z`{n+#20LxTf6VAzxqtGUpN{*BXGvUe{k2?VvtNJq7cCxNqbsrM8`s*O@o7=G>6<>?
zjAO$Qk7cDFGhVH~yT12dtAxn98&jE8mwWtMF>`Y4nM5P8^Y10DtSPQu@*#MZ)>)1n
zKjy>)Y>Pb@Je}1n@6W53lk^(>-2VA1EqAEf?HwiK`c&)E4c0XRXMXB3F*7nSE^gdy
z(73~Z9~g?V!i<dnSy&C2fs_F^NPwS(1(^2O47}JlwAmP0S=kvGS?mmK46I;$1I9MJ
zjFOT9D}DX)@^Zb@ip1Q4oK(H!{9G#wAkfE%6nz69kiiNpt_IEqj%-3eV^|npd$vk}
zAY*e0C!>M3fhNp&CPpz?sPVa#pro0Sp9@UKdO7*Yi8=bo1;uC?f*BO8-iqmUm#RHN
zIDW2soKRw{ddzoi?<9|_|Bj@t`YrNgE6@MfX_F7k$m7_Ya$-tzmhz>!N-vtH8re+I
zH7!@zG+{kY#J>q~Z`K@g%4hvwn!K3(D94`Gzy)RN78e}atuNYQRc)s5vr%X!f9FQ!
z=F-wl{f?Y>7ObBs*|TMajMmyE303Bo1%*!jy71(Yk?-FdE`ghlnHHySi8~%3_Ub?s
zpN-m<OjS$8qknCy8qIyYR2^5`;d{jY*U$LDr+3C~XBDUONV!fd;FFhmvnOKf(FY<k
zDz-)c*m$b?@&lQ_98-60R64O=dt+x|_T8f*@AEDGJAOYWwEglAhUV6b_HP-&pHD4K
H(C`5OG2Dfx
--- a/security/manager/ssl/tests/unit/test_keysize/generate.py
+++ b/security/manager/ssl/tests/unit/test_keysize/generate.py
@@ -13,126 +13,227 @@ sys.path.append(libpath)
 
 import CertUtils
 
 srcdir = os.getcwd()
 db_dir = tempfile.mkdtemp()
 dsaBad_param_filename = 'dsaBad_param.pem'
 dsaOK_param_filename = 'dsaOK_param.pem'
 
-ca_ext_text = 'basicConstraints = critical, CA:TRUE\n'
+ca_ext_text = ('basicConstraints = critical, CA:TRUE\n' +
+               'keyUsage = keyCertSign, cRLSign\n')
 ee_ext_text = ''
 
-def generate_certs(key_type, bad_key_size, ok_key_size):
+aia_prefix = 'authorityInfoAccess = OCSP;URI:http://www.example.com:8888/'
+aia_suffix = '/\n'
+
+mozilla_testing_ev_policy = ('certificatePolicies = @v3_ca_ev_cp\n\n' +
+                             '[ v3_ca_ev_cp ]\n' +
+                             'policyIdentifier = ' +
+                             '1.3.6.1.4.1.13769.666.666.666.1.500.9.1\n\n' +
+                             'CPS.1 = "http://mytestdomain.local/cps"')
+
+generated_ev_root_filenames = []
+
+def generate_and_maybe_import_cert(key_type, cert_name_suffix, base_ext_text,
+                                   signer_key_filename, signer_cert_filename,
+                                   dsa_param_filename, key_size, generate_ev):
+    """
+    Generates a certificate and imports it into the NSS DB if appropriate.
+
+    Arguments:
+      key_type -- the type of key generated: potential values: 'rsa', 'dsa',
+                  or any of the curves found by 'openssl ecparam -list_curves'
+      cert_name_suffix -- suffix of the generated cert name
+      base_ext_text -- the base text for the x509 extensions to be added to the
+                       certificate (extra extensions will be added if generating
+                       an EV cert)
+      signer_key_filename -- the filename of the key from which the cert will
+                             be signed. If an empty string is passed in the cert
+                             will be self signed (think CA roots).
+      signer_cert_filename -- the filename of the signer cert that will sign the
+                              certificate being generated. Ignored if an empty
+                              string is passed in for signer_key_filename.
+                              Must be in DER format.
+      dsa_param_filename -- the filename for the DSA param file
+      key_size -- public key size for RSA certs
+      generate_ev -- whether an EV cert should be generated
+
+    Output:
+      key_filename -- the filename of the key file (PEM format)
+      cert_filename -- the filename of the certificate (DER format)
+    """
+    cert_name = key_type + cert_name_suffix
+    ev_ext_text = ''
+    subject_string = ('/CN=XPCShell Key Size Testing %s %s-bit' %
+                      (key_type, key_size))
+    if generate_ev:
+        cert_name = 'ev-' + cert_name
+        ev_ext_text = (aia_prefix + cert_name + aia_suffix +
+                       mozilla_testing_ev_policy)
+        subject_string += ' (EV)'
+
+    # Use the organization field to store the cert nickname for easier debugging
+    subject_string += '/O=' + cert_name
+
+    [key_filename, cert_filename] = CertUtils.generate_cert_generic(
+        db_dir,
+        srcdir,
+        random.randint(100, 40000000),
+        key_type,
+        cert_name,
+        base_ext_text + ev_ext_text,
+        signer_key_filename,
+        signer_cert_filename,
+        subject_string,
+        dsa_param_filename,
+        key_size)
+
+    if generate_ev:
+        # The dest_dir argument of generate_pkcs12() is also set to db_dir as
+        # the .p12 files do not need to be kept once they have been imported.
+        pkcs12_filename = CertUtils.generate_pkcs12(db_dir, db_dir,
+                                                    cert_filename, key_filename,
+                                                    cert_name)
+        CertUtils.import_cert_and_pkcs12(srcdir, cert_filename, pkcs12_filename,
+                                         cert_name, ',,')
+
+        if not signer_key_filename:
+            generated_ev_root_filenames.append(cert_filename)
+
+    return [key_filename, cert_filename]
+
+def generate_certs(key_type, bad_key_size, ok_key_size, generate_ev):
+    """
+    Generates the various certificates used by the key size tests.
+
+    Arguments:
+      key_type -- the type of key generated: potential values: 'rsa', 'dsa',
+                  or any of the curves found by 'openssl ecparam -list_curves'
+      bad_key_size -- the public key size bad certs should have
+      ok_key_size -- the public key size OK certs should have
+      generate_ev -- whether an EV cert should be generated
+    """
     if key_type == 'dsa':
         CertUtils.init_dsa(db_dir, dsaBad_param_filename, bad_key_size)
         CertUtils.init_dsa(db_dir, dsaOK_param_filename, ok_key_size)
 
     # OK Chain
-    [caOK_key, caOK_cert] = CertUtils.generate_cert_generic(
-                                db_dir,
-                                srcdir,
-                                random.randint(100, 40000000),
-                                key_type,
-                                key_type + '-caOK',
-                                ca_ext_text,
-                                dsa_param_filename = dsaOK_param_filename,
-                                key_size = ok_key_size)
+    if generate_ev and key_type == 'rsa':
+        # Reuse the existing RSA EV root
+        caOK_cert_name = 'evroot'
+        caOK_key = '../test_ev_certs/evroot.key'
+        caOK_cert = '../test_ev_certs/evroot.der'
+        caOK_pkcs12_filename = '../test_ev_certs/evroot.p12'
+        CertUtils.import_cert_and_pkcs12(srcdir, caOK_cert, caOK_pkcs12_filename,
+                                         caOK_cert_name, ',,')
+    else:
+        [caOK_key, caOK_cert] = generate_and_maybe_import_cert(
+            key_type,
+            '-caOK',
+            ca_ext_text,
+            '',
+            '',
+            dsaOK_param_filename,
+            ok_key_size,
+            generate_ev)
 
-    [intOK_key, intOK_cert] = CertUtils.generate_cert_generic(
-                                  db_dir,
-                                  srcdir,
-                                  random.randint(100, 40000000),
-                                  key_type,
-                                  key_type + '-intOK-caOK',
-                                  ca_ext_text,
-                                  caOK_key,
-                                  caOK_cert,
-                                  dsa_param_filename = dsaOK_param_filename,
-                                  key_size = ok_key_size)
+    [intOK_key, intOK_cert] = generate_and_maybe_import_cert(
+        key_type,
+        '-intOK-caOK',
+        ca_ext_text,
+        caOK_key,
+        caOK_cert,
+        dsaOK_param_filename,
+        ok_key_size,
+        generate_ev)
 
-    CertUtils.generate_cert_generic(db_dir,
-                                    srcdir,
-                                    random.randint(100, 40000000),
-                                    key_type,
-                                    key_type + '-eeOK-intOK-caOK',
-                                    ee_ext_text,
-                                    intOK_key,
-                                    intOK_cert,
-                                    dsa_param_filename = dsaOK_param_filename,
-                                    key_size = ok_key_size)
+    generate_and_maybe_import_cert(
+        key_type,
+        '-eeOK-intOK-caOK',
+        ee_ext_text,
+        intOK_key,
+        intOK_cert,
+        dsaOK_param_filename,
+        ok_key_size,
+        generate_ev)
 
     # Bad CA
-    [caBad_key, caBad_cert] = CertUtils.generate_cert_generic(
-                                  db_dir,
-                                  srcdir,
-                                  random.randint(100, 40000000),
-                                  key_type,
-                                  key_type + '-caBad',
-                                  ca_ext_text,
-                                  dsa_param_filename = dsaBad_param_filename,
-                                  key_size = bad_key_size)
+    [caBad_key, caBad_cert] = generate_and_maybe_import_cert(
+        key_type,
+        '-caBad',
+        ca_ext_text,
+        '',
+        '',
+        dsaBad_param_filename,
+        bad_key_size,
+        generate_ev)
 
-    [int_key, int_cert] = CertUtils.generate_cert_generic(
-                              db_dir,
-                              srcdir,
-                              random.randint(100, 40000000),
-                              key_type,
-                              key_type + '-intOK-caBad',
-                              ca_ext_text,
-                              caBad_key,
-                              caBad_cert,
-                              dsa_param_filename = dsaOK_param_filename,
-                              key_size = ok_key_size)
+    [int_key, int_cert] = generate_and_maybe_import_cert(
+        key_type,
+        '-intOK-caBad',
+        ca_ext_text,
+        caBad_key,
+        caBad_cert,
+        dsaOK_param_filename,
+        ok_key_size,
+        generate_ev)
 
-    CertUtils.generate_cert_generic(db_dir,
-                                    srcdir,
-                                    random.randint(100, 40000000),
-                                    key_type,
-                                    key_type + '-eeOK-intOK-caBad',
-                                    ee_ext_text,
-                                    int_key,
-                                    int_cert,
-                                    dsa_param_filename = dsaOK_param_filename,
-                                    key_size = ok_key_size)
+    generate_and_maybe_import_cert(
+        key_type,
+        '-eeOK-intOK-caBad',
+        ee_ext_text,
+        int_key,
+        int_cert,
+        dsaOK_param_filename,
+        ok_key_size,
+        generate_ev)
 
     # Bad Intermediate
-    [intBad_key, intBad_cert] = CertUtils.generate_cert_generic(
-                                    db_dir,
-                                    srcdir,
-                                    random.randint(100, 40000000),
-                                    key_type,
-                                    key_type + '-intBad-caOK',
-                                    ca_ext_text,
-                                    caOK_key,
-                                    caOK_cert,
-                                    dsa_param_filename = dsaBad_param_filename,
-                                    key_size = bad_key_size)
+    [intBad_key, intBad_cert] = generate_and_maybe_import_cert(
+        key_type,
+        '-intBad-caOK',
+        ca_ext_text,
+        caOK_key,
+        caOK_cert,
+        dsaBad_param_filename,
+        bad_key_size,
+        generate_ev)
 
-    CertUtils.generate_cert_generic(db_dir,
-                                    srcdir,
-                                    random.randint(100, 40000000),
-                                    key_type,
-                                    key_type + '-eeOK-intBad-caOK',
-                                    ee_ext_text,
-                                    intBad_key,
-                                    intBad_cert,
-                                    dsa_param_filename = dsaOK_param_filename,
-                                    key_size = ok_key_size)
+    generate_and_maybe_import_cert(
+        key_type,
+        '-eeOK-intBad-caOK',
+        ee_ext_text,
+        intBad_key,
+        intBad_cert,
+        dsaOK_param_filename,
+        ok_key_size,
+        generate_ev)
 
     # Bad End Entity
-    CertUtils.generate_cert_generic(db_dir,
-                                    srcdir,
-                                    random.randint(100, 40000000),
-                                    key_type,
-                                    key_type + '-eeBad-intOK-caOK',
-                                    ee_ext_text,
-                                    intOK_key,
-                                    intOK_cert,
-                                    dsa_param_filename = dsaBad_param_filename,
-                                    key_size = bad_key_size)
+    generate_and_maybe_import_cert(
+        key_type,
+        '-eeBad-intOK-caOK',
+        ee_ext_text,
+        intOK_key,
+        intOK_cert,
+        dsaBad_param_filename,
+        bad_key_size,
+        generate_ev)
+
+# Create a NSS DB for use by the OCSP responder.
+CertUtils.init_nss_db(srcdir)
 
-# SECKEY_PublicKeyStrengthInBits() rounds up the number of bits to the next
-# multiple of 8 - therefore the highest key size less than 1024 that can be
-# tested at the moment is 1016
-generate_certs('rsa', '1016', '1024')
+# TODO(bug 636807): SECKEY_PublicKeyStrengthInBits() rounds up the number of
+# bits to the next multiple of 8 - therefore the highest key size less than 1024
+# that can be tested is 1016, less than 2048 is 2040 and so on.
+generate_certs('rsa', '1016', '1024', False)
+generate_certs('rsa', '2040', '2048', True)
+
+generate_certs('dsa', '960', '1024', False)
 
-generate_certs('dsa', '960', '1024')
+# Print a blank line and the information needed to enable EV for any roots
+# generated by this script.
+print
+for cert_filename in generated_ev_root_filenames:
+    CertUtils.print_cert_info_for_ev(cert_filename)
+print ('You now MUST update the compiled test EV root information to match ' +
+       'the EV root information printed above.')
new file mode 100644
index 0000000000000000000000000000000000000000..dba491b555c9bb73295e2308200897bb07a907c4
GIT binary patch
literal 48128
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
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_keysize/pkcs11.txt
@@ -0,0 +1,5 @@
+library=
+name=NSS Internal PKCS #11 Module
+parameters=configdir='sql:/home/m-c_drive/mozilla-inbound/security/manager/ssl/tests/unit/test_keysize' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription='' 
+NSS=Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30})
+
index f7079a333a18af457a124c02931266d2f500c1b2..b7ff2c94e03e8e855ec42946ed5cfae2e4351837
GIT binary patch
literal 548
zc$_n6Vp1?@V(ePL%*4pV#4J(AXu!+HsnzDu_MMlJk(-slz|~OSK$nd<l!ci`Eh4}<
zI3qPDN5MO_QXx3ADpesQwYVfRFI}OiI8njSz|c%LDYL{-$Up$3fs2O|D6E^D=#-dZ
zAScdiXaZ7UU~Fh^Xc8sPYXssNL%Gzlrg0v!`x#jom>YW-3>rI_8XFjP1mqaon(T7B
zwOPXMef6*YKY2`vDa+R83e2sUEtSj_cUr}EM|KI{FAkO0syx5nWo~M2S)92><Jb$n
zl^bG}E+s7voG)v`Q*6WBbE)3=%<S6hiubt}tl8@PfjM>Q!RbuOYprtTCC4!`EYDCd
z@N9DPzP<T>ORP$PwY+N-w{of@6Eh<N<6;E^IRk#6vt@-D8UM4e8ZZMX18$H2KMM;m
z64=nfpBd=zgzjrH@1F#@Jeq!VN~on%mBba62ocT<d0VYLjBAqi<tw}tIN|x@+lG}(
zY8v7s*rR>ECZ7HC`$^^7h?%YKdjA$T{F66iFWhnapwM51S?8m;Ot_zg1*oyF-*0fq
q;<y(Bcgfv3<-W<+Tb3Ezbm{JzW^B~Ly1RLw-mjdai!_Yp9s>YKhPHVC
index 0016f5152ca9fcb536e6cf63c605826391f8da32..ab42878ab1455ea8ac473caf0498abe468d222e1
GIT binary patch
literal 549
zc$_n6Vp23{V(ePL%*4pV#KQRTV1fZJ8>d#AN85K^Mn-N{1_KvEeFI%K=1>-99<_)7
z=irRgoE!!3)Jlcm%&Js{kksOm%)E4kqT)maLjxld-K5MCLqP+6kOnRu4xq4Za-zSt
zft)z6p^2e^p_zfPp}C<+lsK;uh-(bxQpuLa`N*zkWMyD(>}4=$>||<eWY~6ZYm@T>
z`+F~KmHao(IJkR>v`JXw*ABm^hW&H%+o!z|%6$6g4SV$|)7P(Fx}E%dMwey%q}O`#
zUV$^-$0+`pc_P$x-o2VE*6+*YH3H1nR{Y^JoZ9oIwPkL~{KBc(pKE6S3}@j=y(pa%
z{wI3rfkQ>2q2a7E&5j@Vb8p2`J=G5GXeMSx2FAq-26A9$%L+3x{%2t|U<OhK+#msd
z78YP6u%QJ%GtlLUVQbfiy`AuB=e#YR*H_+9E)0DrD8sHVxv<z;C_JQVpHxFs>zl9T
zl6TVjlrrD!Jly1D$53|n<<kWd>tmK>9AJBUCg+y&pRWIED;JpDNzYt*L1%5E-s9st
uZkg0K9pPwtdW4fHVQOrc$MN8{;BA_^-t1CSgx!m_)Lzz|D!8-edp`g#p2TGU
index 7397577653cc496ac8f07e8b7351fe4af172cb1b..2ec11beb7a00d95f163c485082461ccfbd7c4c44
GIT binary patch
literal 532
zc$_n6ViGWDVys-i%*4pV#KL$Z*3*EOjZ>@5qwPB{BO^B}gMpW!zJV?qb0`Zlk6J{4
zb8tp#PL6_iYNbMOW>u;}NNRCOW?s5NQE{Szp@ET!Zc=86p}2u4NCOuSA5d5~Gq1$o
zTQ@n;-`hY=oY&CA(7@2lz}V2-&@@V%*9gQlhH?!8NU+P$3~ZOIfi%P}5s+P}sZNP0
z$Tl|4L-r3ND+6<54}(Et2UBAM!yS?DL0OL&gAzU#-uL(+bdO>A&Lf_xw)}0KR^Pt-
zs-L;?`LZ`1H=O3@=NfD%af>>-cA1rXVIZH1!Y={$8e_Zn+e4De=a#Hq);gQ#NRz|)
zHK#R}M$IfxZl5}9`PHoDmn6N58UwSWqP#){Hy(Yo&oyX!a_RlUM*}1S|Ju%*eB~q)
zGa~~dT4*yjHZoLC;5zYGJKLOZ>71(zwwduRELigFuXvR4^(Cu0!X2NMI%!8u+xv7T
zQ>Vj@5{s<9ywaldxu$ic=7}4WimVPD;g%`7uA6IF^rgOd^HIC189f2NrSlf8oi{(A
ta?{NNY9U1-dku6yH1;nlc)qS^`mCe?S?Pw0sp@APoZs|0=$^Q32LRU(z`Xzf
index f8d60726e084558f2f7dc76e0c589b359b21182a..bd23f70d7506a3dcb8c84f5c65a8299fe5de1ade
GIT binary patch
literal 532
zc$_n6ViGWDVys%g%*4pV#4N)tV!+GBsnzDu_MMlJk(-slz}ryYK$nd<l!ci`Eh4}<
zI3qPDN5MO_QXx3ADpesQwYVfRFI}OiI8njSz|c%LDYL{-!axk9fs2P9D6E^ASK^eI
zqMMxP?`<F_&TD7_QfFXnXl`g4CC+OE;u=G_1_2~kW@G}kOx8deVwniYveZ<6ZxkCF
z=OcTFk(GhDv6sQ1v6HE>k>U52RM)EOJpBK7&%9A-53V=wzIdPUp2+K2mjx>>eT~>H
zk*{{U;Ubf=@ddH^h2n+c1xsa;L<;I=I@db>d2-{(8gpF+j~(+b#q2C=sSx~h^|@2C
z;;cJczvo|laP*DH%I=7-FTX^lG)fB26j!wKtco*w#b>4Z{p}B*#aj+fH`Tbbmx-B?
zfe|gdnHw7z`0pFO5ZrlS;)Tj<2hxn2HoK&C?K98haCT(3|L|CJ<GS<B=Xd6RQtonH
z^S@Fos;BRGjlsuFM%m_k@d=%bd`Eo#zwqm0D~z4vqk7u(%LW5MZ=P%Ue-4%}%spMW
q_l1Gq#N96?npT}sS<Ymlnt#aVh2*h~er59>Pu$<T@10ykk0Stli^1gp
index 5ec9faf69dfe2fb5754b3066887b16bba2090b32..8ad88d3f551804afa4cbd6739cec647cfe3735d8
GIT binary patch
literal 534
zc$_n6ViGcFVys@k%*4pV#KI)-VX*-(8>d#AN85K^Mn-N{1_N(HeFI%K=1>-99<_)7
z=irRgoE!!3)Jlcm%&Js{kksOm%)E4kqT)maLjxld-K5MCLkR;hkOnRuexR^!W?qTE
zw{CKxQ(}sNoH(zciJ^g^nSrsPxuI#4IIj_iYYgQY1dwi-tbsJdG7*qvsi{D_kZo+7
zkL)2vRtDzAUIv54PNv32hOIf`>N&S3{>ZYJykYfMhZ99Dwu@))l<K)WVY>B`YYPiz
zYIR?KbSvFvZ`%X22L&bW77<e<eL^&ZmoHD&`nGZX2kSQ8@O!JdPTP0<tXiLa^-RW!
zXIGw0yv|w8oySn5V7sqrdFVy6W#4>TQ`x02OU_MO<ivYrnU7ey+o64_%hz()GchwV
zFrtMwGtgZM+`d;FpIdOaY>ek&VXtI*$CR3zEBN{T^eWYrFPMM4uf1xpuW!?4z1fi_
z?_Rvo`@Y}1^0y#oes#&r!ovX)P3yj<R=(S+`qZ_oZFzu}bEj{utfPs`hWHal1F!X8
q`ZlpAA;785&QMWn|4h{#`*)nmt2k<!aHgs?ddicTN=G;@aRLC%Cc%#Y
index 94dfef87e0e90302740d7280c42f1bbd7599b625..be843f5263e288faad1ee2be7e75fa46da6f3708
GIT binary patch
literal 532
zc$_n6ViGWDVys-i%*4pV#KO2bWtRaj8>d#AN85K^Mn-N{1_LiceFI%K=1>-99<_)7
z=irRgoE!!3)Jlcm%&Js{kksOm%)E4kqT)maLjxld-K5MCLvaI9kOnRuKA^B}W?qTE
zw{CKxzqf&$IIp3Jp@E^9fw7^vp-GfDuMvoA4CNa5lWv!cffU3pVUS&^sX(icENq;Q
z>>Wl{2Ij_I27|^<rp88wwU>68H?3ay;L>V?tD0wZ7QFoJBzN4>HgI+U2iNUyk{gyu
z^VNtqciZ<$XYBn{{d#XyNvrX^A}^y)v$ix%*c_X^Z%sB&8tYf4FI%oEZ#>S!Ij3-;
zx^<*HOH#?(FwF$XV$(mRS8vS`to)yy_O8JEbj0REmsZ=w2pu-q@brr0{3~~vm>C%u
z(L$RU=&lufZ}%7OwOY{fiRI?eo7tgt*V5;|7M(KhY@*NVX1x^~k1g6I*FMuK$-tNW
zw`Yts|C20pIf?Yufmg$F_P-bV`io=67KJ0d`8iB;4yoMSEm0>YknOdmjk9@Y=nc+@
pkYCCowzFJ6PKtk-P^<Q7+I63%h(zi22UT}y8!mF|S+GFZ2mpamzwiJ6
index 707d0004daf4ea55bd44da53451e5ce96065e5f3..58b688db61cf13ec39a953cf2167b3600d4d9a25
GIT binary patch
literal 555
zc$_n6Vp2C~Vw|vmnTe5!iG@k!VW$Bv8>d#AN85K^Mn-N{1_KvEeFI%K=1>-99<_)7
z=irRgoE!!3)Jlcm%&Js{kksOm%)E4kqT)maLjxld-K5MCLqP+6kOnRu4xq4Za-zSt
zft)z6p^2e^p_zfPp}C=HlsK;uh-(bx8hDdni=i3V76}6}h%NjeTQc)XoDx$YmNm{p
z_5>p<19M{!gF#~lQ)2_e-4jpN-xa-ISX5bXbN`al(WW9lwq4=7UAg_c=DGEkb$ybh
zRU(~Ei<MvEZxBCW*s#<^Yya)Lb8aR`vh&MTB!4@m^i}T9#0T4VhDxt-iZ9j+7W}g3
znSI6exAXR2cbF?<C{z%g$!}`5_(t#s*899ue$Eh>8+GG0`^TgFtcQgx-o9mGW@KPo
ztY9Dq4kB4$M#ldvtOm?L%77arz|X=0j0!fiNMLSkWC%<2pJno6-u2}>MQ{A|o?%q5
z%%7LnbNSPs2S3&eyRSU<nSFg?zi0Jhxf3FmzJE?Izs%B4Z<Xi{o1K!obKSQMhBo)K
zu6aGo`r=mHp4@RnO5&qZqSq;&7SZG*3d@bwPnfFDzfthM2e+7ZBLD8{Y(WEEYgNtn
QdS^1fZQbO<<HBwL0E#HS)&Kwi
index b7391c49ab365f162407d3e272a5e35fddf2c038..26f46a1bbc47f0d42c3b2ca49b0a2515a9505714
GIT binary patch
literal 556
zc$_n6V$v{ZVw|*qnTe5!iG_(Flh1&cjZ>@5qwPB{BO^B}gMq7|zJV?qb0`Zlk6J{4
zb8tp#PL6_iYNbMOW>u;}NNRCOW?s5NQE{Szp@E^9Zc=86p^$+9NCOuSCs0^7IngOG
z#XwG+*U$u{!ob+j+|V>ioYx4%HHLBxyh*Ue$OLSSgn<~u8h(&9nRzAt-cZXL=Og=q
zk(GhDv6sQ1v6HE>k>P{nm#S{_U80|?{=GM3Uc<h8li%zYM;)f#eUW;(#oupZ6TkP<
zRZ9<EsP$?ye0O<?YISgB{qc1+R_^DkVsc6jnNLbvy)(pDH1_c{slAaki<@fi`wK5<
ziCkQCFr-9e{*=SFo4@V!Op#aL?#tr4#_-qu3VF%p&%cH2-}!96`Tyhb<xI?s42+8v
z4CD;>fv%SoW@P-&!fL<_qzt%00{kp2z{p@jiw5S#28IRR7Y)Uvjz(VH=_3*!(;;v$
z<yX(S3pPA|if><?@uJZCaKTM>$y}=zrkRIZZ{N*-xbgJ;ln))Dh1|CeySAOqoF}uK
zy(8&;(&B`7e>h&x=REpkTF(7xMoU?xn!Unybj5$(xq-==b=oB3n>TiIGN>=$j!3Ea
RzrniYc0;rNvK<%x0RZxn$VLDF
index d41c1cb05c90f8e10e0453581b3aee6e0c63ad00..74c7eddfcac8594e6ad1d78d40ccb43e1caeeb8c
GIT binary patch
literal 555
zc$_n6Vp2C~Vw|vmnTe5!iG}gS4krU%HcqWJkGAi;jEvl@3<fTS`Ubje%%LpIJZcdE
z&cPX}IXMd6sg(-BnN_I@A*sbBnR)37Ma78<h6Y9^x=EQOhJptCAPrnR96({+<V1gO
z137VCLlZ*-Lo)+oLvuruC~;mR5Z4&WHSi+c7I6bnh%I~|TQc)X{JkM|HO@!&10yQ~
zb7L=qL1QOVV<W@5Nk)p?Q&YNT?TK#gIwoH2&>FPr%nK{N@9r&i5?Z>!M_y=5|K;=M
z_rLb%2U1qw+En}EzwejH3~g7xT+4kI7^k1Qr=(zh*lo9jGX0bLZ<}&HS@Y%Sr2S<Q
zkIZlF+;&uFq40{6*Y|Lk7frK!w&EpMwBy+VkAr)*96WM~ccQ|I8GY_d%!~|-ixmvy
zz(FJ{%*gnkh1Gx=NEvX01o&B4fKkDQ775HimsidRG-{T*X`}s2=;qv04-0D@PS`is
zuH|?%O)jgg&rfAb@pZ-hH!mK!o~ruk{L78=rZcVN-1|pi(eI4-2Pdu@U+Qs@v#;^I
zJ@4T?rIzOFZ<pNt!Oi4v+55Wuox$uiSF8lB??0|&^*Gb~Epc<J(apbXTIM#ZPOaE<
N-MlJIfx~ld8vvuy%)<Zx
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_keysize_ev.js
@@ -0,0 +1,154 @@
+// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
+"use strict";
+
+// Checks that RSA certs with key sizes below 2048 bits when verifying for EV
+// are rejected.
+
+do_get_profile(); // Must be called before getting nsIX509CertDB
+const certDB = Cc["@mozilla.org/security/x509certdb;1"]
+                 .getService(Ci.nsIX509CertDB);
+
+const SERVER_PORT = 8888;
+
+function getOCSPResponder(expectedCertNames) {
+  let expectedPaths = expectedCertNames.slice();
+  return startOCSPResponder(SERVER_PORT, "www.example.com", [],
+                            "test_keysize", expectedCertNames, expectedPaths);
+}
+
+function certFromFile(filename) {
+  let der = readFile(do_get_file("test_keysize/" + filename, false));
+  return certDB.constructX509(der, der.length);
+}
+
+function loadCert(certName, trustString) {
+  let certFilename = certName + ".der";
+  addCertFromFile(certDB, "test_keysize/" + certFilename, trustString);
+  return certFromFile(certFilename);
+}
+
+function checkEVStatus(cert, usage, isEVExpected) {
+  do_print("cert cn=" + cert.commonName);
+  do_print("cert o=" + cert.organization);
+  do_print("cert issuer cn=" + cert.issuerCommonName);
+  do_print("cert issuer o=" + cert.issuerOrganization);
+  let hasEVPolicy = {};
+  let verifiedChain = {};
+  let error = certDB.verifyCertNow(cert, usage, NO_FLAGS, verifiedChain,
+                                   hasEVPolicy);
+  equal(hasEVPolicy.value, isEVExpected);
+  equal(0, error);
+}
+
+/**
+ * Adds a single EV key size test.
+ *
+ * @param {Array} expectedNamesForOCSP
+ *        An array of nicknames of the certs to be responded to. The cert name
+ *        prefix is not added to the nicknames in this array.
+ * @param {String} certNamePrefix
+ *        The prefix to prepend to the passed in cert names.
+ * @param {String} rootCACertFileName
+ *        The file name of the root CA cert. Can begin with ".." to reference
+ *        certs in folders other than "test_keysize/".
+ * @param {Array} subCACertFileNames
+ *        An array of file names of any sub CA certificates.
+ * @param {String} endEntityCertFileName
+ *        The file name of the end entity cert.
+ * @param {Boolean} expectedResult
+ *        Whether the chain is expected to validate as EV.
+ */
+function addKeySizeTestForEV(expectedNamesForOCSP, certNamePrefix,
+                             rootCACertFileName, subCACertFileNames,
+                             endEntityCertFileName, expectedResult)
+{
+  add_test(function() {
+    clearOCSPCache();
+    let ocspResponder = getOCSPResponder(expectedNamesForOCSP);
+
+    // Don't prepend the cert name prefix if rootCACertFileName starts with ".."
+    // to support reusing certs in other directories.
+    let rootCertNamePrefix = rootCACertFileName.startsWith("..")
+                           ? ""
+                           : certNamePrefix;
+    loadCert(rootCertNamePrefix + rootCACertFileName, "CTu,CTu,CTu");
+    for (let subCACertFileName of subCACertFileNames) {
+      loadCert(certNamePrefix + subCACertFileName, ",,");
+    }
+    checkEVStatus(certFromFile(certNamePrefix + endEntityCertFileName + ".der"),
+                  certificateUsageSSLServer, expectedResult);
+
+    ocspResponder.stop(run_next_test);
+  });
+}
+
+/**
+ * For debug builds which have the test EV roots compiled in, checks for the
+ * given key type that good chains validate as EV, while bad chains fail EV and
+ * validate as DV.
+ * For opt builds which don't have the test EV roots compiled in, checks that
+ * none of the chains validate as EV.
+ *
+ * Note: This function assumes that the key size requirements for EV are greater
+ * than or equal to the requirements for DV.
+ *
+ * @param {String} keyType
+ *        The key type to check (e.g. "rsa").
+ */
+function checkForKeyType(keyType) {
+  let certNamePrefix = "ev-" + keyType;
+
+  // Reuse the existing test RSA EV root
+  let rootCAOKCertFileName = keyType == "rsa" ? "../test_ev_certs/evroot"
+                                              : "-caOK";
+
+  // OK CA -> OK INT -> OK EE
+  // In opt builds, this chain is only validated for DV. Hence, an OCSP fetch
+  // will not be done for the "-intOK-caOK" intermediate in such a build.
+  let expectedNamesForOCSP = isDebugBuild
+                           ? [ certNamePrefix + "-intOK-caOK",
+                               certNamePrefix + "-eeOK-intOK-caOK" ]
+                           : [ certNamePrefix + "-eeOK-intOK-caOK" ];
+  addKeySizeTestForEV(expectedNamesForOCSP, certNamePrefix,
+                      rootCAOKCertFileName,
+                      ["-intOK-caOK"],
+                      "-eeOK-intOK-caOK",
+                      isDebugBuild);
+
+  // Bad CA -> OK INT -> OK EE
+  expectedNamesForOCSP = [ certNamePrefix + "-eeOK-intOK-caBad" ];
+  addKeySizeTestForEV(expectedNamesForOCSP, certNamePrefix,
+                      "-caBad",
+                      ["-intOK-caBad"],
+                      "-eeOK-intOK-caBad",
+                      false);
+
+  // OK CA -> Bad INT -> OK EE
+  expectedNamesForOCSP = isDebugBuild
+                       ? [ certNamePrefix + "-intBad-caOK" ]
+                       : [ certNamePrefix + "-eeOK-intBad-caOK" ];
+  addKeySizeTestForEV(expectedNamesForOCSP, certNamePrefix,
+                      rootCAOKCertFileName,
+                      ["-intBad-caOK"],
+                      "-eeOK-intBad-caOK",
+                      false);
+
+  // OK CA -> OK INT -> Bad EE
+  expectedNamesForOCSP = [ certNamePrefix + "-eeBad-intOK-caOK" ];
+  addKeySizeTestForEV(expectedNamesForOCSP, certNamePrefix,
+                      rootCAOKCertFileName,
+                      ["-intOK-caOK"],
+                      "-eeBad-intOK-caOK",
+                      false);
+}
+
+function run_test() {
+  // Setup OCSP responder
+  Services.prefs.setCharPref("network.dns.localDomains", "www.example.com");
+
+  checkForKeyType("rsa");
+
+  run_next_test();
+}
--- a/security/manager/ssl/tests/unit/xpcshell.ini
+++ b/security/manager/ssl/tests/unit/xpcshell.ini
@@ -101,16 +101,21 @@ run-sequentially = hardcoded ports
 # Bug 1009158: this test times out on Android
 skip-if = os == "android"
 [test_ocsp_no_hsts_upgrade.js]
 run-sequentially = hardcoded ports
 # Bug 1009158: this test times out on Android
 skip-if = os == "android"
 [test_add_preexisting_cert.js]
 [test_keysize.js]
+[test_keysize_ev.js]
+run-sequentially = hardcoded ports
+# Bug 1009158: this test times out on Android
+# Bug 1008316: B2G doesn't have EV enabled
+skip-if = os == "android" || buildapp == "b2g"
 [test_cert_chains.js]
 run-sequentially = hardcoded ports
 # Bug 1009158: this test times out on Android
 skip-if = os == "android"
 [test_client_cert.js]
 run-sequentially = hardcoded ports
 # Bug 1009158: this test times out on Android
 skip-if = os == "android"