summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/WebCryptoAPI/wrapKey_unwrapKey
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /testing/web-platform/tests/WebCryptoAPI/wrapKey_unwrapKey
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'testing/web-platform/tests/WebCryptoAPI/wrapKey_unwrapKey')
-rw-r--r--testing/web-platform/tests/WebCryptoAPI/wrapKey_unwrapKey/test_wrapKey_unwrapKey.html17
-rw-r--r--testing/web-platform/tests/WebCryptoAPI/wrapKey_unwrapKey/wrapKey_unwrapKey.js266
-rw-r--r--testing/web-platform/tests/WebCryptoAPI/wrapKey_unwrapKey/wrapKey_unwrapKey.worker.js5
3 files changed, 288 insertions, 0 deletions
diff --git a/testing/web-platform/tests/WebCryptoAPI/wrapKey_unwrapKey/test_wrapKey_unwrapKey.html b/testing/web-platform/tests/WebCryptoAPI/wrapKey_unwrapKey/test_wrapKey_unwrapKey.html
new file mode 100644
index 000000000..337e0780e
--- /dev/null
+++ b/testing/web-platform/tests/WebCryptoAPI/wrapKey_unwrapKey/test_wrapKey_unwrapKey.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>WebCryptoAPI: wrapKey() and unwrapKey()</title>
+<link rel="author" title="Charles Engelke" href="mailto:w3c@engelke.com">
+<link rel="help" href="https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-wrapKey">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script src="wrapKey_unwrapKey.js"></script>
+
+<h1>wrapKey and unwrapKey Tests</h1>
+
+<div id="log"></div>
+<script>
+run_test();
+</script>
diff --git a/testing/web-platform/tests/WebCryptoAPI/wrapKey_unwrapKey/wrapKey_unwrapKey.js b/testing/web-platform/tests/WebCryptoAPI/wrapKey_unwrapKey/wrapKey_unwrapKey.js
new file mode 100644
index 000000000..12bd696a7
--- /dev/null
+++ b/testing/web-platform/tests/WebCryptoAPI/wrapKey_unwrapKey/wrapKey_unwrapKey.js
@@ -0,0 +1,266 @@
+// Tests for wrapKey and unwrapKey round tripping
+
+function run_test() {
+ var subtle = self.crypto.subtle;
+
+ var wrappers = []; // Things we wrap (and upwrap) keys with
+ var keys = []; // Things to wrap and unwrap
+
+ // Generate all the keys needed, then iterate over all combinations
+ // to test wrapping and unwrapping.
+ Promise.all([generateWrappingKeys(), generateKeysToWrap()])
+ .then(function(results) {
+ wrappers.forEach(function(wrapper) {
+ keys.forEach(function(key) {
+ testWrapping(wrapper, key);
+ })
+ });
+ }, function(err) {
+ promise_test(function(test) {
+ assert_unreached("A key failed to generate: " + err.name + ": " + err.message)
+ }, "Could not run all tests")
+ })
+ .then(function() {
+ done();
+ }, function(error) {
+ promise_test(function(test) {
+ assert_unreached("A test failed to run: " + err.name + ": " + err.message)
+ }, "Could not run all tests")
+ });
+
+
+ function generateWrappingKeys() {
+ // There are five algorithms that can be used for wrapKey/unwrapKey.
+ // Generate one key with typical parameters for each kind.
+ //
+ // Note: we don't need cryptographically strong parameters for things
+ // like IV - just any legal value will do.
+ var parameters = [
+ {
+ name: "RSA-OAEP",
+ generateParameters: {name: "RSA-OAEP", modulusLength: 4096, publicExponent: new Uint8Array([1,0,1]), hash: "SHA-256"},
+ wrapParameters: {name: "RSA-OAEP", label: new Uint8Array(8)}
+ },
+ {
+ name: "AES-CTR",
+ generateParameters: {name: "AES-CTR", length: 128},
+ wrapParameters: {name: "AES-CTR", counter: new Uint8Array(16), length: 64}
+ },
+ {
+ name: "AES-CBC",
+ generateParameters: {name: "AES-CBC", length: 128},
+ wrapParameters: {name: "AES-CBC", iv: new Uint8Array(16)}
+ },
+ {
+ name: "AES-GCM",
+ generateParameters: {name: "AES-GCM", length: 128},
+ wrapParameters: {name: "AES-GCM", iv: new Uint8Array(16), additionalData: new Uint8Array(16), tagLength: 64}
+ },
+ {
+ name: "AES-KW",
+ generateParameters: {name: "AES-KW", length: 128},
+ wrapParameters: {name: "AES-KW"}
+ }
+ ];
+
+ return Promise.all(parameters.map(function(params) {
+ return subtle.generateKey(params.generateParameters, true, ["wrapKey", "unwrapKey"])
+ .then(function(key) {
+ var wrapper;
+ if (params.name === "RSA-OAEP") { // we have a key pair, not just a key
+ wrapper = {wrappingKey: key.publicKey, unwrappingKey: key.privateKey, parameters: params};
+ } else {
+ wrapper = {wrappingKey: key, unwrappingKey: key, parameters: params};
+ }
+ wrappers.push(wrapper);
+ return true;
+ })
+ }));
+ }
+
+
+ function generateKeysToWrap() {
+ var parameters = [
+ {algorithm: {name: "RSASSA-PKCS1-v1_5", modulusLength: 1024, publicExponent: new Uint8Array([1,0,1]), hash: "SHA-256"}, privateUsages: ["sign"], publicUsages: ["verify"]},
+ {algorithm: {name: "RSA-PSS", modulusLength: 1024, publicExponent: new Uint8Array([1,0,1]), hash: "SHA-256"}, privateUsages: ["sign"], publicUsages: ["verify"]},
+ {algorithm: {name: "RSA-OAEP", modulusLength: 1024, publicExponent: new Uint8Array([1,0,1]), hash: "SHA-256"}, privateUsages: ["decrypt"], publicUsages: ["encrypt"]},
+ {algorithm: {name: "ECDSA", namedCurve: "P-256"}, privateUsages: ["sign"], publicUsages: ["verify"]},
+ {algorithm: {name: "ECDH", namedCurve: "P-256"}, privateUsages: ["deriveBits"], publicUsages: []},
+ {algorithm: {name: "AES-CTR", length: 128}, usages: ["encrypt", "decrypt"]},
+ {algorithm: {name: "AES-CBC", length: 128}, usages: ["encrypt", "decrypt"]},
+ {algorithm: {name: "AES-GCM", length: 128}, usages: ["encrypt", "decrypt"]},
+ {algorithm: {name: "AES-KW", length: 128}, usages: ["wrapKey", "unwrapKey"]},
+ {algorithm: {name: "HMAC", length: 128, hash: "SHA-256"}, usages: ["sign", "verify"]}
+ ];
+
+ return Promise.all(parameters.map(function(params) {
+ var usages;
+ if ("usages" in params) {
+ usages = params.usages;
+ } else {
+ usages = params.publicUsages.concat(params.privateUsages);
+ }
+
+ return subtle.generateKey(params.algorithm, true, usages)
+ .then(function(result) {
+ if (result.constructor === CryptoKey) {
+ keys.push({name: params.algorithm.name, algorithm: params.algorithm, usages: params.usages, key: result});
+ } else {
+ keys.push({name: params.algorithm.name + " public key", algorithm: params.algorithm, usages: params.publicUsages, key: result.publicKey});
+ keys.push({name: params.algorithm.name + " private key", algorithm: params.algorithm, usages: params.privateUsages, key: result.privateKey});
+ }
+ return true;
+ });
+ }));
+ }
+
+
+ // Can we successfully "round-trip" (wrap, then unwrap, a key)?
+ function testWrapping(wrapper, toWrap) {
+ var formats;
+
+ if (toWrap.name.includes("private")) {
+ formats = ["pkcs8", "jwk"];
+ } else if (toWrap.name.includes("public")) {
+ formats = ["spki", "jwk"]
+ } else {
+ formats = ["raw", "jwk"]
+ }
+
+ formats.forEach(function(fmt) {
+ var originalExport;
+
+ promise_test(function(test) {
+ return subtle.exportKey(fmt, toWrap.key)
+ .then(function(exportedKey) {
+ originalExport = exportedKey;
+ return exportedKey;
+ }).then(function(exportedKey) {
+ return subtle.wrapKey(fmt, toWrap.key, wrapper.wrappingKey, wrapper.parameters.wrapParameters);
+ }).then(function(wrappedResult) {
+ return subtle.unwrapKey(fmt, wrappedResult, wrapper.unwrappingKey, wrapper.parameters.wrapParameters, toWrap.algorithm, true, toWrap.usages)
+ }).then(function(unwrappedResult) {
+ return subtle.exportKey(fmt, unwrappedResult)
+ }).then(function(roundTripExport) {
+ if ("byteLength" in originalExport) {
+ assert_true(equalBuffers(originalExport, roundTripExport), "Post-wrap export matches original export");
+ } else {
+ assert_true(equalJwk(originalExport, roundTripExport), "Post-wrap export matches original export.");
+ }
+ }, function(err) {
+ if (wrappingIsPossible(originalExport, wrapper.parameters.name)) {
+ assert_unreached("Round trip threw an error - " + err.name + ': "' + err.message + '"');
+ } else {
+ assert_true(true, "Skipped test due to key length restrictions");
+ }
+ })
+ }, "Can wrap and unwrap " + toWrap.name + " keys using " + fmt + " and " + wrapper.parameters.name);
+
+ });
+
+ }
+
+
+ // RSA-OAEP can only wrap relatively small payloads. AES-KW can only
+ // wrap payloads a multiple of 8 bytes long.
+ //
+ // Note that JWK payloads will be converted to ArrayBuffer for wrapping,
+ // and should automatically be padded if needed for AES-KW.
+ function wrappingIsPossible(exportedKey, algorithmName) {
+ if ("byteLength" in exportedKey && algorithmName === "AES-KW") {
+ return exportedKey.byteLength % 8 === 0;
+ }
+
+ if ("byteLength" in exportedKey && algorithmName === "RSA-OAEP") {
+ // RSA-OAEP can only encrypt payloads with lengths shorter
+ // than modulusLength - 2*hashLength - 1 bytes long. For
+ // a 4096 bit modulus and SHA-256, that comes to
+ // 4096/8 - 2*(256/8) - 1 = 512 - 2*32 - 1 = 447 bytes.
+ return exportedKey.byteLength <= 446;
+ }
+
+ if ("kty" in exportedKey && algorithmName === "RSA-OAEP") {
+ return JSON.stringify(exportedKey).length <= 478;
+ }
+
+ return true;
+ }
+
+
+ // 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<a.byteLength; i++) {
+ if (aBytes[i] !== bBytes[i]) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ // Are two Jwk objects "the same"? That is, does the object returned include
+ // matching values for each property that was expected? It's okay if the
+ // returned object has extra methods; they aren't checked.
+ function equalJwk(expected, got) {
+ var fields = Object.keys(expected);
+ var fieldName;
+
+ for(var i=0; i<fields.length; i++) {
+ fieldName = fields[i];
+ if (!(fieldName in got)) {
+ return false;
+ }
+ if (objectToString(expected[fieldName]) !== objectToString(got[fieldName])) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ // Character representation of any object we may use as a parameter.
+ function objectToString(obj) {
+ var keyValuePairs = [];
+
+ if (Array.isArray(obj)) {
+ return "[" + obj.map(function(elem){return objectToString(elem);}).join(", ") + "]";
+ } else if (typeof obj === "object") {
+ Object.keys(obj).sort().forEach(function(keyName) {
+ keyValuePairs.push(keyName + ": " + objectToString(obj[keyName]));
+ });
+ return "{" + keyValuePairs.join(", ") + "}";
+ } else if (typeof obj === "undefined") {
+ return "undefined";
+ } else {
+ return obj.toString();
+ }
+
+ var keyValuePairs = [];
+
+ Object.keys(obj).sort().forEach(function(keyName) {
+ var value = obj[keyName];
+ if (typeof value === "object") {
+ value = objectToString(value);
+ } else if (typeof value === "array") {
+ value = "[" + value.map(function(elem){return objectToString(elem);}).join(", ") + "]";
+ } else {
+ value = value.toString();
+ }
+
+ keyValuePairs.push(keyName + ": " + value);
+ });
+
+ return "{" + keyValuePairs.join(", ") + "}";
+ }
+
+
+}
diff --git a/testing/web-platform/tests/WebCryptoAPI/wrapKey_unwrapKey/wrapKey_unwrapKey.worker.js b/testing/web-platform/tests/WebCryptoAPI/wrapKey_unwrapKey/wrapKey_unwrapKey.worker.js
new file mode 100644
index 000000000..5d1c5486f
--- /dev/null
+++ b/testing/web-platform/tests/WebCryptoAPI/wrapKey_unwrapKey/wrapKey_unwrapKey.worker.js
@@ -0,0 +1,5 @@
+// <meta> timeout=long
+importScripts("/resources/testharness.js");
+importScripts("wrapKey_unwrapKey.js");
+
+run_test();