test_cert_storage_direct.js (10786B)
1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 "use strict"; 6 7 // This file consists of unit tests for cert_storage (whereas test_cert_storage.js is more of an 8 // integration test). 9 10 do_get_profile(); 11 12 this.certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( 13 Ci.nsICertStorage 14 ); 15 16 async function addCerts(certInfos) { 17 let result = await new Promise(resolve => { 18 certStorage.addCerts(certInfos, resolve); 19 }); 20 Assert.equal(result, Cr.NS_OK, "addCerts should succeed"); 21 } 22 23 async function removeCertsByHashes(hashesBase64) { 24 let result = await new Promise(resolve => { 25 certStorage.removeCertsByHashes(hashesBase64, resolve); 26 }); 27 Assert.equal(result, Cr.NS_OK, "removeCertsByHashes should succeed"); 28 } 29 30 function getLongString(uniquePart, length) { 31 return String(uniquePart).padStart(length, "0"); 32 } 33 34 class CertInfo { 35 constructor(cert, subject) { 36 this.cert = btoa(cert); 37 this.subject = btoa(subject); 38 this.trust = Ci.nsICertStorage.TRUST_INHERIT; 39 } 40 } 41 CertInfo.prototype.QueryInterface = ChromeUtils.generateQI(["nsICertInfo"]); 42 43 add_task(async function test_common_subject() { 44 let someCert1 = new CertInfo( 45 "some certificate bytes 1", 46 "some common subject" 47 ); 48 let someCert2 = new CertInfo( 49 "some certificate bytes 2", 50 "some common subject" 51 ); 52 let someCert3 = new CertInfo( 53 "some certificate bytes 3", 54 "some common subject" 55 ); 56 await addCerts([someCert1, someCert2, someCert3]); 57 let storedCerts = certStorage.findCertsBySubject( 58 stringToArray("some common subject") 59 ); 60 let storedCertsAsStrings = storedCerts.map(arrayToString); 61 let expectedCerts = [ 62 "some certificate bytes 1", 63 "some certificate bytes 2", 64 "some certificate bytes 3", 65 ]; 66 Assert.deepEqual( 67 storedCertsAsStrings.sort(), 68 expectedCerts.sort(), 69 "should find expected certs" 70 ); 71 72 await addCerts([ 73 new CertInfo("some other certificate bytes", "some other subject"), 74 ]); 75 storedCerts = certStorage.findCertsBySubject( 76 stringToArray("some common subject") 77 ); 78 storedCertsAsStrings = storedCerts.map(arrayToString); 79 Assert.deepEqual( 80 storedCertsAsStrings.sort(), 81 expectedCerts.sort(), 82 "should still find expected certs" 83 ); 84 85 let storedOtherCerts = certStorage.findCertsBySubject( 86 stringToArray("some other subject") 87 ); 88 let storedOtherCertsAsStrings = storedOtherCerts.map(arrayToString); 89 let expectedOtherCerts = ["some other certificate bytes"]; 90 Assert.deepEqual( 91 storedOtherCertsAsStrings, 92 expectedOtherCerts, 93 "should have other certificate" 94 ); 95 }); 96 97 add_task(async function test_many_entries() { 98 const NUM_CERTS = 500; 99 const CERT_LENGTH = 3000; 100 const SUBJECT_LENGTH = 40; 101 let certs = []; 102 for (let i = 0; i < NUM_CERTS; i++) { 103 certs.push( 104 new CertInfo( 105 getLongString(i, CERT_LENGTH), 106 getLongString(i, SUBJECT_LENGTH) 107 ) 108 ); 109 } 110 await addCerts(certs); 111 for (let i = 0; i < NUM_CERTS; i++) { 112 let subject = stringToArray(getLongString(i, SUBJECT_LENGTH)); 113 let storedCerts = certStorage.findCertsBySubject(subject); 114 Assert.equal( 115 storedCerts.length, 116 1, 117 "should have 1 certificate (lots of data test)" 118 ); 119 let storedCertAsString = arrayToString(storedCerts[0]); 120 Assert.equal( 121 storedCertAsString, 122 getLongString(i, CERT_LENGTH), 123 "certificate should be as expected (lots of data test)" 124 ); 125 } 126 }); 127 128 add_task(async function test_removal() { 129 // As long as cert_storage is given valid base64, attempting to delete some nonexistent 130 // certificate will "succeed" (it'll do nothing). 131 await removeCertsByHashes([btoa("thishashisthewrongsize")]); 132 133 let removalCert1 = new CertInfo( 134 "removal certificate bytes 1", 135 "common subject to remove" 136 ); 137 let removalCert2 = new CertInfo( 138 "removal certificate bytes 2", 139 "common subject to remove" 140 ); 141 let removalCert3 = new CertInfo( 142 "removal certificate bytes 3", 143 "common subject to remove" 144 ); 145 await addCerts([removalCert1, removalCert2, removalCert3]); 146 147 let storedCerts = certStorage.findCertsBySubject( 148 stringToArray("common subject to remove") 149 ); 150 let storedCertsAsStrings = storedCerts.map(arrayToString); 151 let expectedCerts = [ 152 "removal certificate bytes 1", 153 "removal certificate bytes 2", 154 "removal certificate bytes 3", 155 ]; 156 Assert.deepEqual( 157 storedCertsAsStrings.sort(), 158 expectedCerts.sort(), 159 "should find expected certs before removing them" 160 ); 161 162 // echo -n "removal certificate bytes 2" | sha256sum | xxd -r -p | base64 163 await removeCertsByHashes(["2nUPHwl5TVr1mAD1FU9FivLTlTb0BAdnVUhsYgBccN4="]); 164 storedCerts = certStorage.findCertsBySubject( 165 stringToArray("common subject to remove") 166 ); 167 storedCertsAsStrings = storedCerts.map(arrayToString); 168 expectedCerts = [ 169 "removal certificate bytes 1", 170 "removal certificate bytes 3", 171 ]; 172 Assert.deepEqual( 173 storedCertsAsStrings.sort(), 174 expectedCerts.sort(), 175 "should only have first and third certificates now" 176 ); 177 178 // echo -n "removal certificate bytes 1" | sha256sum | xxd -r -p | base64 179 await removeCertsByHashes(["8zoRqHYrklr7Zx6UWpzrPuL+ol8KL1Ml6XHBQmXiaTY="]); 180 storedCerts = certStorage.findCertsBySubject( 181 stringToArray("common subject to remove") 182 ); 183 storedCertsAsStrings = storedCerts.map(arrayToString); 184 expectedCerts = ["removal certificate bytes 3"]; 185 Assert.deepEqual( 186 storedCertsAsStrings.sort(), 187 expectedCerts.sort(), 188 "should only have third certificate now" 189 ); 190 191 // echo -n "removal certificate bytes 3" | sha256sum | xxd -r -p | base64 192 await removeCertsByHashes(["vZn7GwDSabB/AVo0T+N26nUsfSXIIx4NgQtSi7/0p/w="]); 193 storedCerts = certStorage.findCertsBySubject( 194 stringToArray("common subject to remove") 195 ); 196 Assert.equal(storedCerts.length, 0, "shouldn't have any certificates now"); 197 198 // echo -n "removal certificate bytes 3" | sha256sum | xxd -r -p | base64 199 // Again, removing a nonexistent certificate should "succeed". 200 await removeCertsByHashes(["vZn7GwDSabB/AVo0T+N26nUsfSXIIx4NgQtSi7/0p/w="]); 201 }); 202 203 function base64ToArray(base64String) { 204 let binaryString = atob(base64String); 205 return stringToArray(binaryString); 206 } 207 208 add_task(async function test_lookup_by_hash_succeed() { 209 let someCert1 = new CertInfo("some certificate bytes 1", "common subject 1"); 210 let someCert2 = new CertInfo( 211 "some certificate bytes 2", 212 "some common subject 2" 213 ); 214 let someCert3 = new CertInfo( 215 "some certificate bytes 3", 216 "some common subject 3" 217 ); 218 await addCerts([someCert1, someCert2, someCert3]); 219 // echo -n "some certificate bytes 2" | sha256sum | xxd -r -p | base64 220 let foundCert = certStorage.findCertByHash( 221 base64ToArray("j1vIqpiU0HMmx3zPNujlfGs/pY1vFBJCKpJEeVseeW0=") 222 ); 223 224 Assert.deepEqual( 225 arrayToString(foundCert), 226 atob(someCert2.cert), 227 "should find expected cert" 228 ); 229 }); 230 231 add_task(async function test_lookup_by_hash_fail() { 232 let someCert1 = new CertInfo("some certificate bytes 1", "common subject 1"); 233 let someCert2 = new CertInfo( 234 "some certificate bytes 2", 235 "some common subject 2" 236 ); 237 let someCert3 = new CertInfo( 238 "some certificate bytes 3", 239 "some common subject 3" 240 ); 241 await addCerts([someCert1, someCert2, someCert3]); 242 Assert.throws( 243 () => 244 certStorage.findCertByHash( 245 base64ToArray("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=") 246 ), 247 /NS_ERROR_FAILURE/ 248 ); 249 }); 250 251 add_task(async function test_lookup_by_hashes_succeed() { 252 let someCert1 = new CertInfo("some certificate bytes 1", "common subject 1"); 253 let someCert2 = new CertInfo( 254 "some certificate bytes 2", 255 "some common subject 2" 256 ); 257 let someCert3 = new CertInfo( 258 "some certificate bytes 3", 259 "some common subject 3" 260 ); 261 await addCerts([someCert1, someCert2, someCert3]); 262 // echo -n "some certificate bytes 2" | sha256sum | xxd -r -p | base64 263 // echo -n "some certificate bytes 1" | sha256sum | xxd -r -p | base64 264 let foundCerts = certStorage.hasAllCertsByHash([ 265 base64ToArray("j1vIqpiU0HMmx3zPNujlfGs/pY1vFBJCKpJEeVseeW0="), 266 base64ToArray("c0iy21PfFlGAqqLnQYeSYYUoaF/JEc41lICBdZ7VFtk="), 267 ]); 268 Assert.equal(foundCerts, true); 269 }); 270 271 add_task(async function test_lookup_by_hashes_fail() { 272 let someCert1 = new CertInfo("some certificate bytes 1", "common subject 1"); 273 let someCert2 = new CertInfo( 274 "some certificate bytes 2", 275 "some common subject 2" 276 ); 277 let someCert3 = new CertInfo( 278 "some certificate bytes 3", 279 "some common subject 3" 280 ); 281 await addCerts([someCert1, someCert2, someCert3]); 282 // echo -n "some certificate bytes 2" | sha256sum | xxd -r -p | base64 283 // echo -n "some certificate bytes 1" | sha256sum | xxd -r -p | base64 284 let foundCerts = certStorage.hasAllCertsByHash([ 285 base64ToArray("j1vIqpiU0HMmx3zPNujlfGs/pY1vFBJCKpJEeVseeW0="), 286 base64ToArray("c0iy21PfFlGAqqLnQYeSYYUoaF/JEc41lICBdZ7VFtk="), 287 base64ToArray("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa="), 288 ]); 289 Assert.equal(foundCerts, false); 290 }); 291 292 add_task(async function test_batched_removal() { 293 let removalCert1 = new CertInfo( 294 "batch removal certificate bytes 1", 295 "batch subject to remove" 296 ); 297 let removalCert2 = new CertInfo( 298 "batch removal certificate bytes 2", 299 "batch subject to remove" 300 ); 301 let removalCert3 = new CertInfo( 302 "batch removal certificate bytes 3", 303 "batch subject to remove" 304 ); 305 await addCerts([removalCert1, removalCert2, removalCert3]); 306 let storedCerts = certStorage.findCertsBySubject( 307 stringToArray("batch subject to remove") 308 ); 309 let storedCertsAsStrings = storedCerts.map(arrayToString); 310 let expectedCerts = [ 311 "batch removal certificate bytes 1", 312 "batch removal certificate bytes 2", 313 "batch removal certificate bytes 3", 314 ]; 315 Assert.deepEqual( 316 storedCertsAsStrings.sort(), 317 expectedCerts.sort(), 318 "should find expected certs before removing them" 319 ); 320 // echo -n "batch removal certificate bytes 1" | sha256sum | xxd -r -p | base64 321 // echo -n "batch removal certificate bytes 2" | sha256sum | xxd -r -p | base64 322 // echo -n "batch removal certificate bytes 3" | sha256sum | xxd -r -p | base64 323 await removeCertsByHashes([ 324 "EOEEUTuanHZX9NFVCoMKVT22puIJC6g+ZuNPpJgvaa8=", 325 "Xz6h/Kvn35cCLJEZXkjPqk1GG36b56sreLyAXpO+0zg=", 326 "Jr7XdiTT8ZONUL+ogNNMW2oxKxanvYOLQPKBPgH/has=", 327 ]); 328 storedCerts = certStorage.findCertsBySubject( 329 stringToArray("batch subject to remove") 330 ); 331 Assert.equal(storedCerts.length, 0, "shouldn't have any certificates now"); 332 });