| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 // Must be packed to ../enterprise_platform_keys.crx using the private key | 5 // Must be packed to ../enterprise_platform_keys.crx using the private key |
| 6 // ../enterprise_platform_keys.pem . | 6 // ../enterprise_platform_keys.pem . |
| 7 | 7 |
| 8 'use strict'; |
| 9 |
| 8 var assertEq = chrome.test.assertEq; | 10 var assertEq = chrome.test.assertEq; |
| 9 var assertTrue = chrome.test.assertTrue; | 11 var assertTrue = chrome.test.assertTrue; |
| 10 var assertThrows = chrome.test.assertThrows; | 12 var assertThrows = chrome.test.assertThrows; |
| 11 var fail = chrome.test.fail; | 13 var fail = chrome.test.fail; |
| 12 var succeed = chrome.test.succeed; | 14 var succeed = chrome.test.succeed; |
| 13 var callbackPass = chrome.test.callbackPass; | 15 var callbackPass = chrome.test.callbackPass; |
| 14 var callbackFail= chrome.test.callbackFail; | 16 var callbackFail= chrome.test.callbackFail; |
| 15 | 17 |
| 16 // openssl req -new -x509 -key privkey.pem \ | 18 // openssl req -new -x509 -key privkey.pem \ |
| 17 // -outform der -out cert.der -days 36500 | 19 // -outform der -out cert.der -days 36500 |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 assertTrue(!!chrome.enterprise.platformKeys, "No platformKeys namespace."); | 245 assertTrue(!!chrome.enterprise.platformKeys, "No platformKeys namespace."); |
| 244 assertTrue(!!chrome.enterprise.platformKeys.getTokens, | 246 assertTrue(!!chrome.enterprise.platformKeys.getTokens, |
| 245 "No getTokens function."); | 247 "No getTokens function."); |
| 246 assertTrue(!!chrome.enterprise.platformKeys.importCertificate, | 248 assertTrue(!!chrome.enterprise.platformKeys.importCertificate, |
| 247 "No importCertificate function."); | 249 "No importCertificate function."); |
| 248 assertTrue(!!chrome.enterprise.platformKeys.removeCertificate, | 250 assertTrue(!!chrome.enterprise.platformKeys.removeCertificate, |
| 249 "No removeCertificate function."); | 251 "No removeCertificate function."); |
| 250 | 252 |
| 251 getUserToken(function(userToken) { | 253 getUserToken(function(userToken) { |
| 252 if (!userToken) | 254 if (!userToken) |
| 253 chrome.test.fail('no user token'); | 255 fail('no user token'); |
| 254 if (userToken.id != 'user') | 256 if (userToken.id != 'user') |
| 255 chrome.test.fail('token is not named "user".'); | 257 fail('token is not named "user".'); |
| 256 | 258 |
| 257 callback(userToken); | 259 callback(userToken); |
| 258 }); | 260 }); |
| 259 } | 261 } |
| 260 | 262 |
| 263 function checkKeyPairCommonFormat(keyPair) { |
| 264 function checkReadOnly(object, key) { |
| 265 var original = object[key]; |
| 266 try { |
| 267 object[key] = {}; |
| 268 fail('Expected that the property is read only and an exception to ' + |
| 269 'be thrown'); |
| 270 } catch (error) { |
| 271 assertTrue(object[key] === original); |
| 272 } |
| 273 } |
| 274 |
| 275 checkReadOnly(keyPair, 'privateKey'); |
| 276 var privateKey = keyPair.privateKey; |
| 277 assertEq('private', privateKey.type); |
| 278 assertEq(false, privateKey.extractable); |
| 279 checkReadOnly(privateKey, 'algorithm'); |
| 280 checkReadOnly(privateKey.algorithm, 'hash'); |
| 281 checkReadOnly(privateKey.algorithm, 'modulusLength'); |
| 282 checkReadOnly(privateKey.algorithm, 'name'); |
| 283 |
| 284 checkReadOnly(keyPair, 'publicKey'); |
| 285 var publicKey = keyPair.publicKey; |
| 286 assertEq('public', publicKey.type); |
| 287 assertEq(true, publicKey.extractable); |
| 288 checkReadOnly(publicKey, 'algorithm'); |
| 289 checkReadOnly(publicKey.algorithm, 'hash'); |
| 290 checkReadOnly(publicKey.algorithm, 'modulusLength'); |
| 291 checkReadOnly(publicKey.algorithm, 'name'); |
| 292 } |
| 293 |
| 261 function runTests(userToken) { | 294 function runTests(userToken) { |
| 262 chrome.test.runTests([ | 295 chrome.test.runTests([ |
| 263 function hasSubtleCryptoMethods() { | 296 function hasSubtleCryptoMethods() { |
| 264 assertTrue(!!userToken.subtleCrypto.generateKey, | 297 assertTrue(!!userToken.subtleCrypto.generateKey, |
| 265 "user token has no generateKey method"); | 298 "user token has no generateKey method"); |
| 266 assertTrue(!!userToken.subtleCrypto.sign, | 299 assertTrue(!!userToken.subtleCrypto.sign, |
| 267 "user token has no sign method"); | 300 "user token has no sign method"); |
| 268 assertTrue(!!userToken.subtleCrypto.exportKey, | 301 assertTrue(!!userToken.subtleCrypto.exportKey, |
| 269 "user token has no exportKey method"); | 302 "user token has no exportKey method"); |
| 270 succeed(); | 303 succeed(); |
| 271 }, | 304 }, |
| 272 function initiallyNoCerts() { assertCertsStored(userToken, []); }, | 305 function initiallyNoCerts() { assertCertsStored(userToken, []); }, |
| 273 | 306 |
| 274 // Generates a key and sign some data with it. Verifies the signature using | 307 // Generates a key and sign some data with it. Verifies the signature using |
| 275 // WebCrypto. | 308 // WebCrypto. |
| 276 function generateKeyAndSign() { | 309 function generateKeyAndSign() { |
| 277 var algorithm = { | 310 var algorithm = { |
| 278 name: "RSASSA-PKCS1-v1_5", | 311 name: "RSASSA-PKCS1-v1_5", |
| 279 // RsaHashedKeyGenParams | 312 // RsaHashedKeyGenParams |
| 280 modulusLength: 512, | 313 modulusLength: 512, |
| 281 publicExponent: | 314 // Equivalent to 65537 |
| 282 new Uint8Array([0x01, 0x00, 0x01]), // Equivalent to 65537 | 315 publicExponent: new Uint8Array([0x01, 0x00, 0x01]), |
| 283 hash: { | 316 hash: { |
| 284 name: "SHA-1", | 317 name: "SHA-1", |
| 285 } | 318 } |
| 286 }; | 319 }; |
| 287 // Some random data to sign. | 320 // Some random data to sign. |
| 288 var data = new Uint8Array([0, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6]); | 321 var data = new Uint8Array([0, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6]); |
| 289 var cachedKeyPair; | 322 var cachedKeyPair; |
| 290 var cachedSpki; | 323 var cachedSpki; |
| 291 var cachedSignature; | 324 var cachedSignature; |
| 292 userToken.subtleCrypto.generateKey(algorithm, false, ["sign"]) | 325 userToken.subtleCrypto.generateKey(algorithm, false, ["sign"]) |
| 293 .then(callbackPass(function(keyPair) { | 326 .then(callbackPass(function(keyPair) { |
| 294 assertTrue(!!keyPair, "No key pair."); | 327 assertTrue(!!keyPair, "No key pair."); |
| 295 cachedKeyPair = keyPair; | 328 cachedKeyPair = keyPair; |
| 296 return userToken.subtleCrypto.exportKey('spki', | 329 return userToken.subtleCrypto.exportKey('spki', |
| 297 keyPair.publicKey); | 330 keyPair.publicKey); |
| 298 }), | 331 }), |
| 299 function(error) { | 332 function(error) { fail("GenerateKey failed: " + error); }) |
| 300 assertTrue(false, "GenerateKey failed: " + error); | |
| 301 }) | |
| 302 .then(callbackPass(function(publicKeySpki) { | 333 .then(callbackPass(function(publicKeySpki) { |
| 334 // Ensure that the returned key pair has the expected format. |
| 335 // Some parameter independent checks: |
| 336 checkKeyPairCommonFormat(cachedKeyPair); |
| 337 |
| 338 // Checks depending on the generateKey arguments: |
| 339 var privateKey = cachedKeyPair.privateKey; |
| 340 assertEq(['sign'], privateKey.usages); |
| 341 assertEq(algorithm, privateKey.algorithm); |
| 342 |
| 343 var publicKey = cachedKeyPair.publicKey; |
| 344 assertEq([], publicKey.usages); |
| 345 assertEq(algorithm, publicKey.algorithm); |
| 346 |
| 303 cachedSpki = publicKeySpki; | 347 cachedSpki = publicKeySpki; |
| 304 var signParams = {name: 'RSASSA-PKCS1-v1_5'}; | 348 var signParams = {name: 'RSASSA-PKCS1-v1_5'}; |
| 305 return userToken.subtleCrypto.sign( | 349 return userToken.subtleCrypto.sign( |
| 306 signParams, cachedKeyPair.privateKey, data); | 350 signParams, privateKey, data); |
| 307 }), | 351 }), |
| 308 function(error) { | 352 function(error) { fail("Export failed: " + error); }) |
| 309 assertTrue(false, "Export failed: " + error); | |
| 310 }) | |
| 311 .then(callbackPass(function(signature) { | 353 .then(callbackPass(function(signature) { |
| 312 var importParams = { | 354 var importParams = { |
| 313 name: algorithm.name, | 355 name: algorithm.name, |
| 314 // RsaHashedImportParams | 356 // RsaHashedImportParams |
| 315 hash: { | 357 hash: { |
| 316 name: "SHA-1", | 358 name: "SHA-1", |
| 317 } | 359 } |
| 318 }; | 360 }; |
| 319 assertTrue(!!signature, "No signature."); | 361 assertTrue(!!signature, "No signature."); |
| 320 assertTrue(signature.length != 0, "Signature is empty."); | 362 assertTrue(signature.length != 0, "Signature is empty."); |
| 321 cachedSignature = signature; | 363 cachedSignature = signature; |
| 322 return window.crypto.subtle.importKey( | 364 return window.crypto.subtle.importKey( |
| 323 "spki", cachedSpki, importParams, false, ["verify"]); | 365 "spki", cachedSpki, importParams, false, ["verify"]); |
| 324 }), | 366 }), |
| 325 function(error) { assertTrue(false, "Sign failed: " + error); }) | 367 function(error) { fail("Sign failed: " + error); }) |
| 326 .then(callbackPass(function(webCryptoPublicKey) { | 368 .then(callbackPass(function(webCryptoPublicKey) { |
| 327 assertTrue(!!webCryptoPublicKey); | 369 assertTrue(!!webCryptoPublicKey); |
| 328 assertEq(algorithm.modulusLength, | 370 assertEq(algorithm.modulusLength, |
| 329 webCryptoPublicKey.algorithm.modulusLength); | 371 webCryptoPublicKey.algorithm.modulusLength); |
| 330 assertEq(algorithm.publicExponent, | 372 assertEq(algorithm.publicExponent, |
| 331 webCryptoPublicKey.algorithm.publicExponent); | 373 webCryptoPublicKey.algorithm.publicExponent); |
| 332 return window.crypto.subtle.verify( | 374 return window.crypto.subtle.verify( |
| 333 algorithm, webCryptoPublicKey, cachedSignature, data); | 375 algorithm, webCryptoPublicKey, cachedSignature, data); |
| 334 }), | 376 }), |
| 335 function(error) { | 377 function(error) { fail("Import failed: " + error); }) |
| 336 assertTrue(false, "Import failed: " + error); | |
| 337 }) | |
| 338 .then(callbackPass(function(success) { | 378 .then(callbackPass(function(success) { |
| 339 assertEq(true, success, "Signature invalid."); | 379 assertEq(true, success, "Signature invalid."); |
| 340 }), | 380 }), |
| 341 function(error) { | 381 function(error) { fail("Verification failed: " + error); }); |
| 342 assertTrue(false, "Verification failed: " + error); | |
| 343 }); | |
| 344 }, | 382 }, |
| 345 | 383 |
| 346 // Imports and removes certificates for privateKeyPkcs8, which was imported | 384 // Imports and removes certificates for privateKeyPkcs8, which was imported |
| 347 // by on C++'s side. | 385 // by on C++'s side. |
| 348 // Note: After this test, privateKeyPkcs8 is not stored anymore! | 386 // Note: After this test, privateKeyPkcs8 is not stored anymore! |
| 349 function importAndRemoveCerts() { | 387 function importAndRemoveCerts() { |
| 350 runAsyncSequence([ | 388 runAsyncSequence([ |
| 351 chrome.enterprise.platformKeys.importCertificate.bind( | 389 chrome.enterprise.platformKeys.importCertificate.bind( |
| 352 null, userToken.id, cert1a.buffer), | 390 null, userToken.id, cert1a.buffer), |
| 353 assertCertsStored.bind(null, userToken, [cert1a]), | 391 assertCertsStored.bind(null, userToken, [cert1a]), |
| (...skipping 19 matching lines...) Expand all Loading... |
| 373 function algorithmParameterMissingModulusLength() { | 411 function algorithmParameterMissingModulusLength() { |
| 374 var algorithm = { | 412 var algorithm = { |
| 375 name: "RSASSA-PKCS1-v1_5", | 413 name: "RSASSA-PKCS1-v1_5", |
| 376 // Equivalent to 65537 | 414 // Equivalent to 65537 |
| 377 publicExponent: new Uint8Array([0x01, 0x00, 0x01]), | 415 publicExponent: new Uint8Array([0x01, 0x00, 0x01]), |
| 378 hash: { | 416 hash: { |
| 379 name: "SHA-1", | 417 name: "SHA-1", |
| 380 } | 418 } |
| 381 }; | 419 }; |
| 382 userToken.subtleCrypto.generateKey(algorithm, false, ['sign']).then( | 420 userToken.subtleCrypto.generateKey(algorithm, false, ['sign']).then( |
| 383 function(keyPair) { | 421 function(keyPair) { fail('generateKey was expected to fail'); }, |
| 384 assertTrue(false, 'generateKey was expected to fail'); | |
| 385 }, | |
| 386 callbackPass(function(error) { | 422 callbackPass(function(error) { |
| 387 assertTrue(error instanceof Error); | 423 assertTrue(error instanceof Error); |
| 388 assertEq('A required parameter was missing or out-of-range', | 424 assertEq('A required parameter was missing or out-of-range', |
| 389 error.message); | 425 error.message); |
| 390 })); | 426 })); |
| 391 }, | 427 }, |
| 392 | 428 |
| 393 // Call generate key with invalid algorithm parameter, missing hash. | 429 // Call generate key with invalid algorithm parameter, missing hash. |
| 394 function algorithmParameterMissingHash() { | 430 function algorithmParameterMissingHash() { |
| 395 var algorithm = { | 431 var algorithm = { |
| 396 name: 'RSASSA-PKCS1-v1_5', | 432 name: 'RSASSA-PKCS1-v1_5', |
| 397 modulusLength: 512, | 433 modulusLength: 512, |
| 398 // Equivalent to 65537 | 434 // Equivalent to 65537 |
| 399 publicExponent: new Uint8Array([0x01, 0x00, 0x01]), | 435 publicExponent: new Uint8Array([0x01, 0x00, 0x01]), |
| 400 }; | 436 }; |
| 401 userToken.subtleCrypto.generateKey(algorithm, false, ['sign']).then( | 437 userToken.subtleCrypto.generateKey(algorithm, false, ['sign']).then( |
| 402 function(keyPair) { | 438 function(keyPair) { fail('generateKey was expected to fail'); }, |
| 403 assertTrue(false, 'generateKey was expected to fail'); | |
| 404 }, | |
| 405 callbackPass(function(error) { | 439 callbackPass(function(error) { |
| 406 assertEq( | 440 assertEq( |
| 407 new Error('Error: A required parameter was missing our out-of-range'), | 441 new Error('Error: A required parameter was missing our out-of-range'), |
| 408 error); | 442 error); |
| 409 })); | 443 })); |
| 410 }, | 444 }, |
| 411 | 445 |
| 412 // Call generate key with invalid algorithm parameter, unsupported public | 446 // Call generate key with invalid algorithm parameter, unsupported public |
| 413 // exponent. | 447 // exponent. |
| 414 function algorithmParameterUnsupportedPublicExponent() { | 448 function algorithmParameterUnsupportedPublicExponent() { |
| 415 var algorithm = { | 449 var algorithm = { |
| 416 name: 'RSASSA-PKCS1-v1_5', | 450 name: 'RSASSA-PKCS1-v1_5', |
| 417 modulusLength: 512, | 451 modulusLength: 512, |
| 418 // Different from 65537. | 452 // Different from 65537. |
| 419 publicExponent: new Uint8Array([0x01, 0x01]), | 453 publicExponent: new Uint8Array([0x01, 0x01]), |
| 420 }; | 454 }; |
| 421 userToken.subtleCrypto.generateKey(algorithm, false, ['sign']).then( | 455 userToken.subtleCrypto.generateKey(algorithm, false, ['sign']).then( |
| 422 function(keyPair) { | 456 function(keyPair) { fail('generateKey was expected to fail'); }, |
| 423 assertTrue(false, 'generateKey was expected to fail'); | |
| 424 }, | |
| 425 callbackPass(function(error) { | 457 callbackPass(function(error) { |
| 426 assertTrue(error instanceof Error); | 458 assertTrue(error instanceof Error); |
| 427 assertEq('A required parameter was missing or out-of-range', | 459 assertEq('A required parameter was missing or out-of-range', |
| 428 error.message); | 460 error.message); |
| 429 })); | 461 })); |
| 430 }, | 462 }, |
| 431 | 463 |
| 432 // Imports a certificate for which now private key was imported/generated | 464 // Imports a certificate for which now private key was imported/generated |
| 433 // before. | 465 // before. |
| 434 function missingPrivateKey() { | 466 function missingPrivateKey() { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 456 callbackFail('Certificate is not a valid X.509 certificate.')); | 488 callbackFail('Certificate is not a valid X.509 certificate.')); |
| 457 }, | 489 }, |
| 458 function getCertsInvalidToken() { | 490 function getCertsInvalidToken() { |
| 459 chrome.enterprise.platformKeys.getCertificates( | 491 chrome.enterprise.platformKeys.getCertificates( |
| 460 'invalid token id', callbackFail('The token is not valid.')); | 492 'invalid token id', callbackFail('The token is not valid.')); |
| 461 } | 493 } |
| 462 ]); | 494 ]); |
| 463 } | 495 } |
| 464 | 496 |
| 465 beforeTests(runTests); | 497 beforeTests(runTests); |
| OLD | NEW |