зеркало из https://github.com/mozilla/gecko-dev.git
376 строки
11 KiB
HTML
376 строки
11 KiB
HTML
<!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(
|
|
"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(
|
|
"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 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("utf-8").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>
|