summaryrefslogtreecommitdiffstats
path: root/dom/crypto/test/test_WebCrypto_Wrap_Unwrap.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/crypto/test/test_WebCrypto_Wrap_Unwrap.html')
-rw-r--r--dom/crypto/test/test_WebCrypto_Wrap_Unwrap.html443
1 files changed, 443 insertions, 0 deletions
diff --git a/dom/crypto/test/test_WebCrypto_Wrap_Unwrap.html b/dom/crypto/test/test_WebCrypto_Wrap_Unwrap.html
new file mode 100644
index 0000000000..dcd040643d
--- /dev/null
+++ b/dom/crypto/test/test_WebCrypto_Wrap_Unwrap.html
@@ -0,0 +1,443 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+<title>WebCrypto Test Suite</title>
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+<link rel="stylesheet" href="./test_WebCrypto.css"/>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+
+<!-- Utilities for manipulating ABVs -->
+<script src="util.js"></script>
+
+<!-- A simple wrapper around IndexedDB -->
+<script src="simpledb.js"></script>
+
+<!-- Test vectors drawn from the literature -->
+<script src="./test-vectors.js"></script>
+
+<!-- General testing framework -->
+<script src="./test-array.js"></script>
+
+<script>/* <![CDATA[*/
+"use strict";
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "Key wrap known answer, using AES-GCM",
+ function() {
+ var that = this;
+ var alg = {
+ name: "AES-GCM",
+ iv: tv.key_wrap_known_answer.wrapping_iv,
+ tagLength: 128,
+ };
+ var key, wrappingKey;
+
+ function doImport(k) {
+ wrappingKey = k;
+ return crypto.subtle.importKey("raw", tv.key_wrap_known_answer.key,
+ alg, true, ["encrypt", "decrypt"]);
+ }
+ function doWrap(k) {
+ key = k;
+ return crypto.subtle.wrapKey("raw", key, wrappingKey, alg);
+ }
+
+ crypto.subtle.importKey("raw", tv.key_wrap_known_answer.wrapping_key,
+ alg, false, ["wrapKey"])
+ .then(doImport, error(that))
+ .then(doWrap, error(that))
+ .then(
+ memcmp_complete(that, tv.key_wrap_known_answer.wrapped_key),
+ error(that)
+ );
+ }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "Key wrap failing on non-extractable key",
+ function() {
+ var that = this;
+ var alg = {
+ name: "AES-GCM",
+ iv: tv.key_wrap_known_answer.wrapping_iv,
+ tagLength: 128,
+ };
+ var key, wrappingKey;
+
+ function doImport(k) {
+ wrappingKey = k;
+ return crypto.subtle.importKey("raw", tv.key_wrap_known_answer.key,
+ alg, false, ["encrypt", "decrypt"]);
+ }
+ function doWrap(k) {
+ key = k;
+ return crypto.subtle.wrapKey("raw", key, wrappingKey, alg);
+ }
+
+ crypto.subtle.importKey("raw", tv.key_wrap_known_answer.wrapping_key,
+ alg, false, ["wrapKey"])
+ .then(doImport, error(that))
+ .then(doWrap, error(that))
+ .then(
+ error(that),
+ complete(that)
+ );
+ }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "Key unwrap known answer, using AES-GCM",
+ function() {
+ var that = this;
+ var alg = {
+ name: "AES-GCM",
+ iv: tv.key_wrap_known_answer.wrapping_iv,
+ tagLength: 128,
+ };
+ var wrappingKey;
+
+ function doUnwrap(k) {
+ wrappingKey = k;
+ return crypto.subtle.unwrapKey(
+ "raw", tv.key_wrap_known_answer.wrapped_key,
+ wrappingKey, alg,
+ "AES-GCM", true, ["encrypt", "decrypt"]
+ );
+ }
+ function doExport(k) {
+ return crypto.subtle.exportKey("raw", k);
+ }
+
+ crypto.subtle.importKey("raw", tv.key_wrap_known_answer.wrapping_key,
+ alg, false, ["unwrapKey"])
+ .then(doUnwrap, error(that))
+ .then(doExport, error(that))
+ .then(
+ memcmp_complete(that, tv.key_wrap_known_answer.key),
+ error(that)
+ );
+ }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "Key wrap/unwrap round-trip, using RSA-OAEP",
+ function() {
+ var that = this;
+ var oaep = {
+ name: "RSA-OAEP",
+ hash: "SHA-256",
+ };
+ var gcm = {
+ name: "AES-GCM",
+ iv: tv.aes_gcm_enc.iv,
+ additionalData: tv.aes_gcm_enc.adata,
+ tagLength: 128,
+ };
+ var unwrapKey;
+
+ function doWrap(keys) {
+ var originalKey = keys[0];
+ var wrapKey = keys[1];
+ unwrapKey = keys[2];
+ return crypto.subtle.wrapKey("raw", originalKey, wrapKey, oaep);
+ }
+ function doUnwrap(wrappedKey) {
+ return crypto.subtle.unwrapKey("raw", wrappedKey, unwrapKey, oaep,
+ gcm, false, ["encrypt"]);
+ }
+ function doEncrypt(aesKey) {
+ return crypto.subtle.encrypt(gcm, aesKey, tv.aes_gcm_enc.data);
+ }
+
+ // 1.Import:
+ // -> HMAC key
+ // -> OAEP wrap key (public)
+ // -> OAEP unwrap key (private)
+ // 2. Wrap the HMAC key
+ // 3. Unwrap it
+ // 4. Compute HMAC
+ // 5. Check HMAC value
+ Promise.all([
+ crypto.subtle.importKey("raw", tv.aes_gcm_enc.key, gcm, true, ["encrypt"]),
+ crypto.subtle.importKey("spki", tv.rsaoaep.spki, oaep, true, ["wrapKey"]),
+ crypto.subtle.importKey("pkcs8", tv.rsaoaep.pkcs8, oaep, false, ["unwrapKey"]),
+ ])
+ .then(doWrap, error(that))
+ .then(doUnwrap, error(that))
+ .then(doEncrypt, error(that))
+ .then(
+ memcmp_complete(that, tv.aes_gcm_enc.result),
+ error(that)
+ );
+ }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "HMAC JWK wrap/unwrap round-trip, with AES-GCM",
+ function() {
+ var that = this;
+ var genAlg = { name: "HMAC", hash: "SHA-384", length: 512 };
+ var wrapAlg = { name: "AES-GCM", iv: tv.aes_gcm_enc.iv };
+ var wrapKey, originalKey, originalKeyJwk;
+
+ function doExport(k) {
+ return crypto.subtle.exportKey("jwk", k);
+ }
+ function doWrap() {
+ return crypto.subtle.wrapKey("jwk", originalKey, wrapKey, wrapAlg);
+ }
+ function doUnwrap(wrappedKey) {
+ return crypto.subtle.unwrapKey("jwk", wrappedKey, wrapKey, wrapAlg,
+ { name: "HMAC", hash: "SHA-384"},
+ true, ["sign", "verify"]);
+ }
+
+ Promise.all([
+ crypto.subtle.importKey("jwk", tv.aes_gcm_enc.key_jwk,
+ "AES-GCM", false, ["wrapKey", "unwrapKey"])
+ .then(function(x) { wrapKey = x; }),
+ crypto.subtle.generateKey(genAlg, true, ["sign", "verify"])
+ .then(function(x) { originalKey = x; return x; })
+ .then(doExport)
+ .then(function(x) { originalKeyJwk = x; }),
+ ])
+ .then(doWrap)
+ .then(doUnwrap)
+ .then(doExport)
+ .then(
+ complete(that, function(x) {
+ return exists(x.k) && x.k == originalKeyJwk.k;
+ }),
+ error(that)
+ );
+ }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "ECDSA private JWK wrap/unwrap round-trip, with AES-GCM",
+ function() {
+ var that = this;
+ var genAlg = { name: "ECDSA", namedCurve: "P-256" };
+ var wrapAlg = { name: "AES-GCM", iv: tv.aes_gcm_enc.iv };
+ var wrapKey, originalKey, originalKeyJwk;
+
+ function doExport(k) {
+ return crypto.subtle.exportKey("jwk", k);
+ }
+ function doWrap() {
+ return crypto.subtle.wrapKey("jwk", originalKey, wrapKey, wrapAlg);
+ }
+ function doUnwrap(wrappedKey) {
+ return crypto.subtle.unwrapKey("jwk", wrappedKey, wrapKey, wrapAlg,
+ genAlg, true, ["sign"]);
+ }
+
+ Promise.all([
+ crypto.subtle.importKey("jwk", tv.aes_gcm_enc.key_jwk,
+ "AES-GCM", false, ["wrapKey", "unwrapKey"])
+ .then(function(x) { wrapKey = x; }),
+ crypto.subtle.generateKey(genAlg, true, ["sign", "verify"])
+ .then(function(x) { originalKey = x.privateKey; return x.privateKey; })
+ .then(doExport)
+ .then(function(x) { originalKeyJwk = x; }),
+ ])
+ .then(doWrap)
+ .then(doUnwrap)
+ .then(doExport)
+ .then(
+ complete(that, function(x) {
+ return (x.kty == originalKeyJwk.kty) &&
+ (x.crv == originalKeyJwk.crv) &&
+ (x.d == originalKeyJwk.d) &&
+ (x.x == originalKeyJwk.x) &&
+ (x.y == originalKeyJwk.y);
+ }),
+ error(that)
+ );
+ }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "AES-KW known answer",
+ function() {
+ var that = this;
+
+ function doWrap(keys) {
+ var wrapKey = keys[0];
+ var originalKey = keys[1];
+ return crypto.subtle.wrapKey("raw", originalKey, wrapKey, "AES-KW");
+ }
+
+ Promise.all([
+ crypto.subtle.importKey("jwk", tv.aes_kw.wrapping_key,
+ "AES-KW", false, ["wrapKey"]),
+ crypto.subtle.importKey("jwk", tv.aes_kw.key,
+ "AES-GCM", true, ["encrypt"]),
+ ])
+ .then(doWrap)
+ .then(
+ memcmp_complete(that, tv.aes_kw.wrapped_key),
+ error(that)
+ );
+ }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "AES-KW unwrap failure on tampered key data",
+ function() {
+ var that = this;
+ var tamperedWrappedKey = new Uint8Array(tv.aes_kw.wrapped_key);
+ tamperedWrappedKey[5] ^= 0xFF;
+
+ function doUnwrap(wrapKey) {
+ return crypto.subtle.unwrapKey("raw", tamperedWrappedKey, wrapKey,
+ "AES-KW", "AES-GCM",
+ true, ["encrypt", "decrypt"]);
+ }
+
+ crypto.subtle.importKey("jwk", tv.aes_kw.wrapping_key,
+ "AES-KW", false, ["unwrapKey"])
+ .then(doUnwrap)
+ .then(error(that), complete(that));
+ }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "AES-KW unwrap AES-KW key data",
+ function() {
+ var that = this;
+ var wrappedKey = new Uint8Array(tv.aes_kw.wrapped_key);
+
+ function doUnwrap(wrapKey) {
+ return crypto.subtle.unwrapKey("raw", wrappedKey, wrapKey,
+ "AES-KW", "AES-KW",
+ true, ["wrapKey", "unwrapKey"]);
+ }
+
+ crypto.subtle.importKey("jwk", tv.aes_kw.wrapping_key,
+ "AES-KW", false, ["unwrapKey"])
+ .then(doUnwrap)
+ .then(
+ memcmp_complete(that, tv.aes_kw.key),
+ error(that)
+ );
+ }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "AES-KW wrap/unwrap round-trip",
+ function() {
+ var that = this;
+ var genAlg = { name: "HMAC", hash: "SHA-384", length: 512 };
+ var wrapKey, originalKey, originalKeyJwk;
+
+ function doExport(k) {
+ return crypto.subtle.exportKey("jwk", k);
+ }
+ function doWrap() {
+ return crypto.subtle.wrapKey("raw", originalKey, wrapKey, "AES-KW");
+ }
+ function doUnwrap(wrappedKey) {
+ return crypto.subtle.unwrapKey("raw", wrappedKey, wrapKey,
+ "AES-KW", { name: "HMAC", hash: "SHA-384"},
+ true, ["sign", "verify"]);
+ }
+
+ Promise.all([
+ crypto.subtle.importKey("jwk", tv.aes_kw.wrapping_key,
+ "AES-KW", false, ["wrapKey", "unwrapKey"])
+ .then(function(x) { wrapKey = x; }),
+ crypto.subtle.generateKey(genAlg, true, ["sign"])
+ .then(function(x) { originalKey = x; return x; })
+ .then(doExport)
+ .then(function(x) { originalKeyJwk = x; }),
+ ])
+ .then(doWrap)
+ .then(doUnwrap)
+ .then(doExport)
+ .then(
+ complete(that, function(x) {
+ return exists(x.k) && x.k == originalKeyJwk.k;
+ }),
+ error(that)
+ );
+ }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "JWK unwrap attempt on bogus data should error out",
+ function() {
+ // Largely cribbed from the "JWK wrap/unwrap round-trip, with AES-GCM" test
+ var that = this;
+ var wrapAlg = { name: "AES-GCM", iv: tv.aes_gcm_enc.iv };
+ var wrapKey;
+
+ function doBogusWrap() {
+ var abv = new TextEncoder().encode("I am so not JSON");
+ return crypto.subtle.encrypt(wrapAlg, wrapKey, abv);
+ }
+ function doUnwrap(wrappedKey) {
+ return crypto.subtle.unwrapKey("jwk", wrappedKey, wrapKey, wrapAlg,
+ {name: "HMAC", hash: "SHA-384"},
+ true, ["sign", "verify"]);
+ }
+
+ crypto.subtle.importKey("jwk", tv.aes_gcm_enc.key_jwk,
+ "AES-GCM", false, ["encrypt", "unwrapKey"])
+ .then(function(x) { wrapKey = x; })
+ .then(doBogusWrap, error(that))
+ .then(doUnwrap, error(that))
+ .then(
+ error(that),
+ complete(that)
+ );
+ }
+);
+
+/* ]]>*/</script>
+</head>
+
+<body>
+
+<div id="content">
+ <div id="head">
+ <b>Web</b>Crypto<br>
+ </div>
+
+ <div id="start" onclick="start();">RUN ALL</div>
+
+ <div id="resultDiv" class="content">
+ Summary:
+ <span class="pass"><span id="passN">0</span> passed, </span>
+ <span class="fail"><span id="failN">0</span> failed, </span>
+ <span class="pending"><span id="pendingN">0</span> pending.</span>
+ <br/>
+ <br/>
+
+ <table id="results">
+ <tr>
+ <th>Test</th>
+ <th>Result</th>
+ <th>Time</th>
+ </tr>
+ </table>
+
+ </div>
+
+ <div id="foot"></div>
+</div>
+
+</body>
+</html>