OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 'use strict'; | 5 'use strict'; |
6 | 6 |
7 var systemTokenEnabled = (location.href.indexOf("systemTokenEnabled") != -1); | 7 var systemTokenEnabled = (location.search.indexOf("systemTokenEnabled") != -1); |
| 8 var selectedTestSuite = location.hash.slice(1); |
| 9 console.log('[SELECTED TEST SUITE] ' + selectedTestSuite + |
| 10 ', systemTokenEnable ' + systemTokenEnabled); |
8 | 11 |
9 var assertEq = chrome.test.assertEq; | 12 var assertEq = chrome.test.assertEq; |
10 var assertTrue = chrome.test.assertTrue; | 13 var assertTrue = chrome.test.assertTrue; |
11 var assertThrows = chrome.test.assertThrows; | |
12 var fail = chrome.test.fail; | 14 var fail = chrome.test.fail; |
13 var succeed = chrome.test.succeed; | 15 var succeed = chrome.test.succeed; |
14 var callbackPass = chrome.test.callbackPass; | 16 var callbackPass = chrome.test.callbackPass; |
15 var callbackFail= chrome.test.callbackFail; | 17 var callbackFail= chrome.test.callbackFail; |
16 | 18 |
17 // Each value is the path to a file in this extension's folder that will be | 19 // Each value is the path to a file in this extension's folder that will be |
18 // loaded and replaced by a Uint8Array in the setUp() function below. | 20 // loaded and replaced by a Uint8Array in the setUp() function below. |
19 var data = { | 21 var data = { |
20 // X.509 client certificates in DER encoding. | 22 // X.509 client certificates in DER encoding. |
21 // openssl x509 -in net/data/ssl/certificates/client_1.pem -outform DER -out | 23 // openssl x509 -in net/data/ssl/certificates/client_1.pem -outform DER -out |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 } | 107 } |
106 | 108 |
107 /** | 109 /** |
108 * @param {ArrayBufferView[]} certs | 110 * @param {ArrayBufferView[]} certs |
109 * @return {ArrayBufferView[]} |certs| sorted in some order. | 111 * @return {ArrayBufferView[]} |certs| sorted in some order. |
110 */ | 112 */ |
111 function sortCerts(certs) { | 113 function sortCerts(certs) { |
112 return certs.sort(compareArrays); | 114 return certs.sort(compareArrays); |
113 } | 115 } |
114 | 116 |
115 function assertCertsSelected(request, expectedCerts, callback) { | 117 function assertCertsSelected(details, expectedCerts, callback) { |
116 chrome.platformKeys.selectClientCertificates( | 118 chrome.platformKeys.selectClientCertificates( |
117 {interactive: false, request: request}, | 119 details, callbackPass(function(actualMatches) { |
118 callbackPass(function(actualMatches) { | |
119 assertEq(expectedCerts.length, actualMatches.length, | 120 assertEq(expectedCerts.length, actualMatches.length, |
120 'Number of stored certs not as expected'); | 121 'Number of stored certs not as expected'); |
121 if (expectedCerts.length == actualMatches.length) { | 122 if (expectedCerts.length == actualMatches.length) { |
122 var actualCerts = actualMatches.map(function(match) { | 123 var actualCerts = actualMatches.map(function(match) { |
123 return new Uint8Array(match.certificate); | 124 return new Uint8Array(match.certificate); |
124 }); | 125 }); |
125 actualCerts = sortCerts(actualCerts); | 126 actualCerts = sortCerts(actualCerts); |
126 expectedCerts = sortCerts(expectedCerts); | 127 expectedCerts = sortCerts(expectedCerts); |
127 for (var i = 0; i < expectedCerts.length; i++) { | 128 for (var i = 0; i < expectedCerts.length; i++) { |
128 assertEq(expectedCerts[i], actualCerts[i], | 129 assertEq(expectedCerts[i], actualCerts[i], |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 } | 184 } |
184 | 185 |
185 function testHasSubtleCryptoMethods(token) { | 186 function testHasSubtleCryptoMethods(token) { |
186 assertTrue(!!token.subtleCrypto.generateKey, | 187 assertTrue(!!token.subtleCrypto.generateKey, |
187 "token has no generateKey method"); | 188 "token has no generateKey method"); |
188 assertTrue(!!token.subtleCrypto.sign, "token has no sign method"); | 189 assertTrue(!!token.subtleCrypto.sign, "token has no sign method"); |
189 assertTrue(!!token.subtleCrypto.exportKey, "token has no exportKey method"); | 190 assertTrue(!!token.subtleCrypto.exportKey, "token has no exportKey method"); |
190 succeed(); | 191 succeed(); |
191 } | 192 } |
192 | 193 |
| 194 var requestAll = { |
| 195 certificateTypes: [], |
| 196 certificateAuthorities: [] |
| 197 }; |
| 198 |
| 199 // Depends on |data|, thus it cannot be created immediately. |
| 200 function requestCA1() { |
| 201 return { |
| 202 certificateTypes: [], |
| 203 certificateAuthorities: [data.client_1_issuer_dn.buffer] |
| 204 }; |
| 205 } |
| 206 |
193 function testSelectAllCerts() { | 207 function testSelectAllCerts() { |
194 var requestAll = { | |
195 certificateTypes: [], | |
196 certificateAuthorities: [] | |
197 }; | |
198 var expectedCerts = [data.client_1]; | 208 var expectedCerts = [data.client_1]; |
199 if (systemTokenEnabled) | 209 if (systemTokenEnabled) |
200 expectedCerts.push(data.client_2); | 210 expectedCerts.push(data.client_2); |
201 assertCertsSelected(requestAll, expectedCerts); | 211 assertCertsSelected({interactive: false, request: requestAll}, expectedCerts); |
202 } | 212 } |
203 | 213 |
204 function testSelectCA1Certs() { | 214 function testSelectCA1Certs() { |
205 var requestCA1 = { | 215 assertCertsSelected({interactive: false, request: requestCA1()}, |
206 certificateTypes: [], | 216 [data.client_1]); |
207 certificateAuthorities: [data.client_1_issuer_dn.buffer] | 217 } |
208 }; | 218 |
209 assertCertsSelected(requestCA1, [data.client_1]); | 219 function testSelectAllReturnsNoCerts() { |
| 220 assertCertsSelected({interactive: false, request: requestAll}, |
| 221 [] /* no certs selected */); |
| 222 } |
| 223 |
| 224 function testSelectAllReturnsClient1() { |
| 225 assertCertsSelected({interactive: false, request: requestAll}, |
| 226 [data.client_1]); |
| 227 } |
| 228 |
| 229 function testInteractiveSelectNoCerts() { |
| 230 assertCertsSelected({interactive: true, request: requestAll}, |
| 231 [] /* no certs selected */); |
| 232 } |
| 233 |
| 234 function testInteractiveSelectClient1() { |
| 235 assertCertsSelected({interactive: true, request: requestAll}, |
| 236 [data.client_1]); |
210 } | 237 } |
211 | 238 |
212 function testMatchResult() { | 239 function testMatchResult() { |
213 var requestCA1 = { | |
214 certificateTypes: [], | |
215 certificateAuthorities: [data.client_1_issuer_dn.buffer] | |
216 }; | |
217 chrome.platformKeys.selectClientCertificates( | 240 chrome.platformKeys.selectClientCertificates( |
218 {interactive: false, request: requestCA1}, | 241 {interactive: false, request: requestCA1()}, |
219 callbackPass(function(matches) { | 242 callbackPass(function(matches) { |
220 var expectedAlgorithm = { | 243 var expectedAlgorithm = { |
221 modulusLength: 2048, | 244 modulusLength: 2048, |
222 name: "RSASSA-PKCS1-v1_5", | 245 name: "RSASSA-PKCS1-v1_5", |
223 publicExponent: new Uint8Array([0x01, 0x00, 0x01]) | 246 publicExponent: new Uint8Array([0x01, 0x00, 0x01]) |
224 }; | 247 }; |
225 var actualAlgorithm = matches[0].keyAlgorithm; | 248 var actualAlgorithm = matches[0].keyAlgorithm; |
226 assertEq( | 249 assertEq( |
227 expectedAlgorithm, actualAlgorithm, | 250 expectedAlgorithm, actualAlgorithm, |
228 'Member algorithm of Match does not equal the expected algorithm'); | 251 'Member algorithm of Match does not equal the expected algorithm'); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 .sign(signParams, privateKey, data.raw_data) | 298 .sign(signParams, privateKey, data.raw_data) |
276 .then(callbackPass(function(signature) { | 299 .then(callbackPass(function(signature) { |
277 var actualSignature = new Uint8Array(signature); | 300 var actualSignature = new Uint8Array(signature); |
278 assertTrue(compareArrays(data.signature_nohash_pkcs, | 301 assertTrue(compareArrays(data.signature_nohash_pkcs, |
279 actualSignature) == 0, | 302 actualSignature) == 0, |
280 'Incorrect signature'); | 303 'Incorrect signature'); |
281 })); | 304 })); |
282 })); | 305 })); |
283 } | 306 } |
284 | 307 |
285 function testSignSha1() { | 308 function testSignSha1Client1() { |
286 var keyParams = { | 309 var keyParams = { |
287 // Algorithm names are case-insensitive. | 310 // Algorithm names are case-insensitive. |
288 hash: {name: 'Sha-1'} | 311 hash: {name: 'Sha-1'} |
289 }; | 312 }; |
290 var signParams = { | 313 var signParams = { |
291 // Algorithm names are case-insensitive. | 314 // Algorithm names are case-insensitive. |
292 name: 'RSASSA-Pkcs1-v1_5' | 315 name: 'RSASSA-Pkcs1-v1_5' |
293 }; | 316 }; |
294 chrome.platformKeys.getKeyPair( | 317 chrome.platformKeys.getKeyPair( |
295 data.client_1.buffer, keyParams, | 318 data.client_1.buffer, keyParams, |
296 callbackPass(function(publicKey, privateKey) { | 319 callbackPass(function(publicKey, privateKey) { |
297 chrome.platformKeys.subtleCrypto() | 320 chrome.platformKeys.subtleCrypto() |
298 .sign(signParams, privateKey, data.raw_data) | 321 .sign(signParams, privateKey, data.raw_data) |
299 .then(callbackPass(function(signature) { | 322 .then(callbackPass(function(signature) { |
300 var actualSignature = new Uint8Array(signature); | 323 var actualSignature = new Uint8Array(signature); |
301 assertTrue( | 324 assertTrue( |
302 compareArrays(data.signature_sha1_pkcs, actualSignature) == 0, | 325 compareArrays(data.signature_sha1_pkcs, actualSignature) == 0, |
303 'Incorrect signature'); | 326 'Incorrect signature'); |
304 })); | 327 })); |
305 })); | 328 })); |
306 } | 329 } |
307 | 330 |
308 function runTests() { | 331 // TODO(pneubeck): Test this by verifying that no private key is returned, once |
309 var tests = [ | 332 // that's implemented. |
310 testStaticMethods, | 333 function testSignFails(cert) { |
311 testSelectAllCerts, | 334 var keyParams = { |
312 testSelectCA1Certs, | 335 hash: {name: 'SHA-1'} |
313 testMatchResult, | 336 }; |
314 testGetKeyPair, | 337 var signParams = { |
315 testSignNoHash, | 338 name: 'RSASSA-PKCS1-v1_5' |
316 testSignSha1 | 339 }; |
317 ]; | 340 chrome.platformKeys.getKeyPair( |
318 | 341 cert.buffer, keyParams, callbackPass(function(publicKey, privateKey) { |
319 chrome.test.runTests(tests); | 342 chrome.platformKeys.subtleCrypto() |
| 343 .sign(signParams, privateKey, data.raw_data) |
| 344 .then(function(signature) { fail('sign was expected to fail.'); }, |
| 345 callbackPass(function(error) { |
| 346 assertTrue(error instanceof Error); |
| 347 assertEq( |
| 348 'The operation failed for an operation-specific reason', |
| 349 error.message); |
| 350 })); |
| 351 })); |
320 } | 352 } |
321 | 353 |
322 setUp(runTests); | 354 function testSignClient1Fails() { |
| 355 testSignFails(data.client_1); |
| 356 } |
| 357 |
| 358 function testSignClient2Fails() { |
| 359 testSignFails(data.client_2); |
| 360 } |
| 361 |
| 362 var testSuites = { |
| 363 // These tests assume already granted permissions for client_1 and client_2. |
| 364 // On interactive selectClientCertificates calls, the simulated user does not |
| 365 // select any cert. |
| 366 basicTests: function() { |
| 367 var tests = [ |
| 368 testStaticMethods, |
| 369 testSelectAllCerts, |
| 370 testSelectCA1Certs, |
| 371 testInteractiveSelectNoCerts, |
| 372 testMatchResult, |
| 373 testGetKeyPair, |
| 374 testSignNoHash, |
| 375 testSignSha1Client1, |
| 376 ]; |
| 377 |
| 378 chrome.test.runTests(tests); |
| 379 }, |
| 380 |
| 381 // This test suite starts without any granted permissions. |
| 382 // On interactive selectClientCertificates calls, the simulated user selects |
| 383 // client_1, if matching. |
| 384 permissionTests: function() { |
| 385 var tests = [ |
| 386 // Without permissions both sign attempts fail. |
| 387 testSignClient1Fails, |
| 388 testSignClient2Fails, |
| 389 |
| 390 // Without permissions, non-interactive select calls return no certs. |
| 391 testSelectAllReturnsNoCerts, |
| 392 |
| 393 testInteractiveSelectClient1, |
| 394 // Now that the permission for client_1 is granted. |
| 395 |
| 396 // Verify that signing with client_1 is possible and with client_2 still |
| 397 // fails. |
| 398 testSignSha1Client1, |
| 399 testSignClient2Fails, |
| 400 |
| 401 // Verify that client_1 can still be selected interactively. |
| 402 testInteractiveSelectClient1, |
| 403 |
| 404 // Verify that client_1 but not client_2 is selected in non-interactive |
| 405 // calls. |
| 406 testSelectAllReturnsClient1, |
| 407 ]; |
| 408 |
| 409 chrome.test.runTests(tests); |
| 410 } |
| 411 }; |
| 412 |
| 413 setUp(testSuites[selectedTestSuite]); |
OLD | NEW |