// Test importKey and exportKey for non-PKC algorithms. Only "happy paths" are // currently tested - those where the operation should succeed. function run_test() { var subtle = crypto.subtle; // keying material for algorithms that can use any bit string. var rawKeyData = [ new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]), new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]), new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]) ]; // combinations of algorithms, usages, parameters, and formats to test var testVectors = [ {name: "AES-CTR", legalUsages: ["encrypt", "decrypt"], extractable: [true, false], formats: ["raw", "jwk"]}, {name: "AES-CBC", legalUsages: ["encrypt", "decrypt"], extractable: [true, false], formats: ["raw", "jwk"]}, {name: "AES-GCM", legalUsages: ["encrypt", "decrypt"], extractable: [true, false], formats: ["raw", "jwk"]}, {name: "AES-KW", legalUsages: ["wrapKey", "unwrapKey"], extractable: [true, false], formats: ["raw", "jwk"]}, {name: "HMAC", hash: "SHA-1", legalUsages: ["sign", "verify"], extractable: [false], formats: ["raw", "jwk"]}, {name: "HMAC", hash: "SHA-256", legalUsages: ["sign", "verify"], extractable: [false], formats: ["raw", "jwk"]}, {name: "HMAC", hash: "SHA-384", legalUsages: ["sign", "verify"], extractable: [false], formats: ["raw", "jwk"]}, {name: "HMAC", hash: "SHA-512", legalUsages: ["sign", "verify"], extractable: [false], formats: ["raw", "jwk"]}, {name: "HKDF", legalUsages: ["deriveBits", "deriveKey"], extractable: [false], formats: ["raw"]}, {name: "PBKDF2", legalUsages: ["deriveBits", "deriveKey"], extractable: [false], formats: ["raw"]} ]; // TESTS ARE HERE: // Test every test vector, along with all available key data testVectors.forEach(function(vector) { var algorithm = {name: vector.name}; if ("hash" in vector) { algorithm.hash = vector.hash; } rawKeyData.forEach(function(keyData) { // Generate all combinations of valid usages for testing allValidUsages(vector.legalUsages, []).forEach(function(usages) { // Try each legal value of the extractable parameter vector.extractable.forEach(function(extractable) { vector.formats.forEach(function(format) { var data = keyData; if (format === "jwk") { data = jwkData(keyData, algorithm); } testFormat(format, algorithm, data, keyData.length * 8, usages, extractable); }); }); }); }); }); // Test importKey with a given key format and other parameters. If // extrable is true, export the key and verify that it matches the input. function testFormat(format, algorithm, keyData, keySize, usages, extractable) { promise_test(function(test) { return subtle.importKey(format, keyData, algorithm, extractable, usages). then(function(key) { assert_equals(key.constructor, CryptoKey, "Imported a CryptoKey object"); if (!extractable) { return; } return subtle.exportKey(format, key). then(function(result) { if (format !== "jwk") { assert_true(equalBuffers(keyData, result), "Round trip works"); } else { assert_true(equalJwk(keyData, result), "Round trip works"); } }, function(err) { assert_unreached("Threw an unexpected error: " + err.toString()); }); }, function(err) { assert_unreached("Threw an unexpected error: " + err.toString()); }); }, "Good parameters: " + keySize.toString() + " bits " + parameterString(format, keyData, algorithm, extractable, usages)); } // Helper methods follow: // Are two array buffers the same? function equalBuffers(a, b) { if (a.byteLength !== b.byteLength) { return false; } var aBytes = new Uint8Array(a); var bBytes = new Uint8Array(b); for (var i=0; i 0) { allNonemptySubsetsOf(remainingElements).forEach(function(combination) { combination.push(firstElement); results.push(combination); }); } } return results; } // Return a list of all valid usage combinations, given the possible ones // and the ones that are required for a particular operation. function allValidUsages(possibleUsages, requiredUsages) { var allUsages = []; allNonemptySubsetsOf(possibleUsages).forEach(function(usage) { for (var i=0; i