| 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 |