mirror of
https://github.com/denoland/deno.git
synced 2024-11-01 09:24:20 -04:00
169 lines
4.4 KiB
JavaScript
169 lines
4.4 KiB
JavaScript
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
|
"use strict";
|
|
|
|
((window) => {
|
|
const core = window.Deno.core;
|
|
const webidl = window.__bootstrap.webidl;
|
|
const { DOMException } = window.__bootstrap.domException;
|
|
|
|
const supportedAlgorithms = {
|
|
"digest": {
|
|
"SHA-1": {},
|
|
"SHA-256": {},
|
|
"SHA-384": {},
|
|
"SHA-512": {},
|
|
},
|
|
};
|
|
|
|
function normalizeAlgorithm(algorithm, op) {
|
|
if (typeof algorithm == "string") {
|
|
return normalizeAlgorithm({ name: algorithm }, op);
|
|
}
|
|
|
|
const initialAlgorithm = webidl.converters["Algorithm"](algorithm, {
|
|
context: "Argument 1",
|
|
});
|
|
|
|
const registeredAlgorithms = supportedAlgorithms[op];
|
|
const algorithmName = Object.keys(registeredAlgorithms)
|
|
.find((key) => key.toLowerCase() == initialAlgorithm.name.toLowerCase());
|
|
|
|
if (algorithmName === undefined) {
|
|
throw new DOMException(
|
|
"Unrecognized algorithm name",
|
|
"NotSupportedError",
|
|
);
|
|
}
|
|
|
|
// TODO(caspervonb) Step 6 (create from webidl definition), when the need arises.
|
|
// See https://www.w3.org/TR/WebCryptoAPI/#dfn-normalize-an-algorithm
|
|
const normalizedAlgorithm = {};
|
|
normalizedAlgorithm.name = algorithmName;
|
|
|
|
// TODO(caspervonb) Step 9 and 10, when the need arises.
|
|
// See https://www.w3.org/TR/WebCryptoAPI/#dfn-normalize-an-algorithm
|
|
return normalizedAlgorithm;
|
|
}
|
|
|
|
// Should match op_crypto_subtle_digest() in extensions/crypto/lib.rs
|
|
function digestToId(name) {
|
|
switch (name) {
|
|
case "SHA-1":
|
|
return 0;
|
|
case "SHA-256":
|
|
return 1;
|
|
case "SHA-384":
|
|
return 2;
|
|
case "SHA-512":
|
|
return 3;
|
|
}
|
|
}
|
|
|
|
class SubtleCrypto {
|
|
constructor() {
|
|
webidl.illegalConstructor();
|
|
}
|
|
|
|
async digest(algorithm, data) {
|
|
const prefix = "Failed to execute 'digest' on 'SubtleCrypto'";
|
|
|
|
webidl.assertBranded(this, SubtleCrypto);
|
|
webidl.requiredArguments(arguments.length, 2);
|
|
|
|
algorithm = webidl.converters.AlgorithmIdentifier(algorithm, {
|
|
prefix,
|
|
context: "Argument 1",
|
|
});
|
|
|
|
data = webidl.converters.BufferSource(data, {
|
|
prefix,
|
|
context: "Argument 2",
|
|
});
|
|
|
|
if (ArrayBuffer.isView(data)) {
|
|
data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
} else {
|
|
data = new Uint8Array(data);
|
|
}
|
|
|
|
data = data.slice();
|
|
|
|
algorithm = normalizeAlgorithm(algorithm, "digest");
|
|
|
|
const result = await core.opAsync(
|
|
"op_crypto_subtle_digest",
|
|
digestToId(algorithm.name),
|
|
data,
|
|
);
|
|
|
|
return result.buffer;
|
|
}
|
|
}
|
|
|
|
const subtle = webidl.createBranded(SubtleCrypto);
|
|
|
|
class Crypto {
|
|
constructor() {
|
|
webidl.illegalConstructor();
|
|
}
|
|
|
|
getRandomValues(arrayBufferView) {
|
|
webidl.assertBranded(this, Crypto);
|
|
const prefix = "Failed to execute 'getRandomValues' on 'Crypto'";
|
|
webidl.requiredArguments(arguments.length, 1, { prefix });
|
|
arrayBufferView = webidl.converters.ArrayBufferView(arrayBufferView, {
|
|
prefix,
|
|
context: "Argument 1",
|
|
});
|
|
if (
|
|
!(
|
|
arrayBufferView instanceof Int8Array ||
|
|
arrayBufferView instanceof Uint8Array ||
|
|
arrayBufferView instanceof Int16Array ||
|
|
arrayBufferView instanceof Uint16Array ||
|
|
arrayBufferView instanceof Int32Array ||
|
|
arrayBufferView instanceof Uint32Array ||
|
|
arrayBufferView instanceof Uint8ClampedArray
|
|
)
|
|
) {
|
|
throw new DOMException(
|
|
"The provided ArrayBufferView is not an integer array type",
|
|
"TypeMismatchError",
|
|
);
|
|
}
|
|
const ui8 = new Uint8Array(
|
|
arrayBufferView.buffer,
|
|
arrayBufferView.byteOffset,
|
|
arrayBufferView.byteLength,
|
|
);
|
|
core.opSync("op_crypto_get_random_values", ui8);
|
|
return arrayBufferView;
|
|
}
|
|
|
|
randomUUID() {
|
|
webidl.assertBranded(this, Crypto);
|
|
return core.opSync("op_crypto_random_uuid");
|
|
}
|
|
|
|
get subtle() {
|
|
webidl.assertBranded(this, Crypto);
|
|
return subtle;
|
|
}
|
|
|
|
get [Symbol.toStringTag]() {
|
|
return "Crypto";
|
|
}
|
|
|
|
[Symbol.for("Deno.customInspect")](inspect) {
|
|
return `${this.constructor.name} ${inspect({})}`;
|
|
}
|
|
}
|
|
|
|
webidl.configurePrototype(Crypto);
|
|
|
|
window.__bootstrap.crypto = {
|
|
SubtleCrypto,
|
|
crypto: webidl.createBranded(Crypto),
|
|
Crypto,
|
|
};
|
|
})(this);
|