From d388dce0c6ceb6cbab66a83cf75461150878dd38 Mon Sep 17 00:00:00 2001 From: keroxp Date: Fri, 4 Jan 2019 03:33:49 +0900 Subject: [PATCH 1/4] feat: crypto.digest --- BUILD.gn | 1 + js/globals.ts | 4 ++++ js/webcrypto.ts | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ src/msg.fbs | 13 +++++++++++- src/ops.rs | 38 +++++++++++++++++++++++++++++++++++ 5 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 js/webcrypto.ts diff --git a/BUILD.gn b/BUILD.gn index f5a5f30dda9139..4fc0c28b7b7380 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -98,6 +98,7 @@ ts_sources = [ "js/url.ts", "js/url_search_params.ts", "js/util.ts", + "js/webcrypto.ts", "js/write_file.ts", "tsconfig.json", diff --git a/js/globals.ts b/js/globals.ts index efa377e9bf87ad..1d1fdd0a3b2df6 100644 --- a/js/globals.ts +++ b/js/globals.ts @@ -17,6 +17,7 @@ import * as textEncoding from "./text_encoding"; import * as timers from "./timers"; import * as url from "./url"; import * as urlSearchParams from "./url_search_params"; +import * as webcrypto from "./webcrypto"; // These imports are not exposed and therefore are fine to just import the // symbols required. @@ -78,3 +79,6 @@ window.TextEncoder = textEncoding.TextEncoder; export type TextEncoder = textEncoding.TextEncoder; window.TextDecoder = textEncoding.TextDecoder; export type TextDecoder = textEncoding.TextDecoder; + +window.SubtleCrypto = webcrypto.SubtleCrypto; +window.crypto = webcrypto.crypto; diff --git a/js/webcrypto.ts b/js/webcrypto.ts new file mode 100644 index 00000000000000..d37bf507edd1cc --- /dev/null +++ b/js/webcrypto.ts @@ -0,0 +1,53 @@ +import * as msg from "gen/msg_generated"; +import * as flatbuffers from "./flatbuffers"; +import {assert} from "./util"; +import {sendAsync} from "./dispatch"; + +function req( + algorithm: string, + data: Uint8Array +): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { + const builder = flatbuffers.createBuilder(); + const algoLoc = builder.createString(algorithm); + const dataLoc = msg.WebCryptoDigest.createDataVector(builder, data); + msg.WebCryptoDigest.startWebCryptoDigest(builder); + msg.WebCryptoDigest.addAlgorithm(builder, algoLoc); + msg.WebCryptoDigest.addData(builder, dataLoc); + const inner = msg.WebCryptoDigest.endWebCryptoDigest(builder); + return [builder, msg.Any.WebCryptoDigest, inner]; +} + +function res( + baseRes: null | msg.Base +): Uint8Array | null { + assert(baseRes !== null); + assert(msg.Any.WebCryptoDigestRes === baseRes!.innerType()); + const res = new msg.WebCryptoDigestRes(); + assert(baseRes!.inner(res) !== null); + const result = res.resultArray(); + if (result !== null) { + return result; + } + return null; +} + +async function digest( + algorithm: string, + data: Uint8Array +) { + return res(await sendAsync(...req(algorithm, data))); +} + +export class SubtleCrypto { + digest(algorithm: string | { name: string }, data: Uint8Array) { + if (typeof algorithm === "string") { + return digest(algorithm, data); + } else { + return digest(algorithm.name, data); + } + } +} + +export const crypto = { + subtle: new SubtleCrypto() +}; diff --git a/src/msg.fbs b/src/msg.fbs index b576d0f23dd943..e874cfbee8edec 100644 --- a/src/msg.fbs +++ b/src/msg.fbs @@ -56,7 +56,9 @@ union Any { Run, RunRes, RunStatus, - RunStatusRes + RunStatusRes, + WebCryptoDigest, + WebCryptoDigestRes } enum ErrorKind: byte { @@ -451,4 +453,13 @@ table RunStatusRes { exit_signal: int; } +table WebCryptoDigest { + algorithm: string; + data: [ubyte]; +} + +table WebCryptoDigestRes { + result: [ubyte]; +} + root_type Base; diff --git a/src/ops.rs b/src/ops.rs index 5b2598728ef8a2..84d175d201ce50 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -22,6 +22,7 @@ use hyper::rt::Future; use remove_dir_all::remove_dir_all; use repl; use resources::table_entries; +use ring::{digest}; use std; use std::convert::From; use std::fs; @@ -115,6 +116,7 @@ pub fn dispatch( msg::Any::Truncate => op_truncate, msg::Any::WriteFile => op_write_file, msg::Any::Write => op_write, + msg::Any::WebCryptoDigest => op_webcrypto_digest, _ => panic!(format!( "Unhandled message {}", msg::enum_name_any(inner_type) @@ -1529,3 +1531,39 @@ fn op_run_status( }); Box::new(future) } + +fn op_webcrypto_digest( + _state: &IsolateState, + base: &msg::Base, + data: libdeno::deno_buf, +) -> Box { + assert_eq!(data.len(), 0); + let inner = base.inner_as_web_crypto_digest().unwrap(); + let cmd_id = base.cmd_id(); + let algorithm = inner.algorithm().unwrap(); + let data = inner.data().unwrap(); + let builder = &mut FlatBufferBuilder::new(); + let hash = match algorithm { + "SHA-1" => digest::digest(&digest::SHA1, data), + "SHA-256" => digest::digest(&digest::SHA256, data), + "SHA-384" => digest::digest(&digest::SHA384, data), + "SHA-512" => digest::digest(&digest::SHA512, data), + _ => panic!("unsupported hash function"), + }; + let result = builder.create_vector(hash.as_ref()); + let inner = msg::WebCryptoDigestRes::create( + builder, + &msg::WebCryptoDigestResArgs { + result: Some(result), + } + ); + ok_future(serialize_response( + cmd_id, + builder, + msg::BaseArgs { + inner: Some(inner.as_union_value()), + inner_type: msg::Any::WebCryptoDigestRes, + ..Default::default() + } + )) +} \ No newline at end of file From 28d873aa528a4cc40da0b8db3a26474910e08428 Mon Sep 17 00:00:00 2001 From: Yusuke Sakurai Date: Fri, 4 Jan 2019 17:26:02 +0900 Subject: [PATCH 2/4] test: add test for webcrypto --- js/unit_tests.ts | 1 + js/webcrypto_test.ts | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 js/webcrypto_test.ts diff --git a/js/unit_tests.ts b/js/unit_tests.ts index b24a156d549310..910636709a5d8a 100644 --- a/js/unit_tests.ts +++ b/js/unit_tests.ts @@ -38,6 +38,7 @@ import "./timers_test.ts"; import "./truncate_test.ts"; import "./url_test.ts"; import "./url_search_params_test.ts"; +import "./webcrypto_test.ts"; import "./write_file_test.ts"; // TODO import "../website/app_test.js"; diff --git a/js/webcrypto_test.ts b/js/webcrypto_test.ts new file mode 100644 index 00000000000000..d858a6b07e399e --- /dev/null +++ b/js/webcrypto_test.ts @@ -0,0 +1,19 @@ +import { test, assertEqual } from "./test_util.ts"; +import * as deno from "deno"; + +const encoder = new TextEncoder; +const decoder = new TextDecoder; +test(async function testSha1() { + const bytes = encoder.encode("abcde") + const res = await crypto.subtle.digest("SHA-1", bytes); + const hash = decoder.decode(res); + console.log(res,hash) + assertEqual(hash, "03de6c570bfe24bfc328ccd7ca46b76eadaf4334") +}) + +test(async function testSha256() { + const bytes = encoder.encode("hello, world"); + const res = await crypto.subtle.digest("SHA-256", bytes); + const hash = decoder.decode(res); + assertEqual(hash, "09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b") +}) \ No newline at end of file From 3754dfa1590eda949a10285c5e76f6ef23bb1a13 Mon Sep 17 00:00:00 2001 From: Yusuke Sakurai Date: Fri, 4 Jan 2019 19:18:27 +0900 Subject: [PATCH 3/4] fix: tests, interfaces --- js/webcrypto.ts | 62 +++++++++++++++++++++++++++++++++++++++++--- js/webcrypto_test.ts | 45 +++++++++++++++++++++++++++----- 2 files changed, 97 insertions(+), 10 deletions(-) diff --git a/js/webcrypto.ts b/js/webcrypto.ts index d37bf507edd1cc..108dd2debce958 100644 --- a/js/webcrypto.ts +++ b/js/webcrypto.ts @@ -19,7 +19,7 @@ function req( function res( baseRes: null | msg.Base -): Uint8Array | null { +): ArrayBuffer | null { assert(baseRes !== null); assert(msg.Any.WebCryptoDigestRes === baseRes!.innerType()); const res = new msg.WebCryptoDigestRes(); @@ -31,15 +31,71 @@ function res( return null; } +const kHashFuncs = ["SHA-1", "SHA-256", "SHA-384", "SHA-512"] +type BinaryArray = Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer +function binaryArrayToBytes(bin: BinaryArray): Uint8Array { + const buf = new ArrayBuffer(bin.byteLength); + let view = new DataView(buf); + if (bin instanceof Int8Array) { + for (let i = 0; i< bin.byteLength; i++) { + view.setInt8(i, bin[i]); + } + } else if (bin instanceof Int16Array) { + for (let i = 0; i< bin.byteLength; i++) { + view.setInt16(i*2, bin[i]); + } + } else if (bin instanceof Int32Array) { + for (let i = 0; i< bin.byteLength; i++) { + view.setInt32(i*4, bin[i]); + } + } else if (bin instanceof Uint8Array) { + for (let i = 0; i< bin.byteLength; i++) { + view.setUint8(i, bin[i]); + } + } else if (bin instanceof Uint16Array) { + for (let i = 0; i< bin.byteLength; i++) { + view.setUint16(i*2, bin[i]); + } + } else if (bin instanceof Uint32Array) { + for (let i = 0; i< bin.byteLength; i++) { + view.setUint32(i*4, bin[i]); + } + } else if (bin instanceof Uint8ClampedArray) { + for (let i = 0; i< bin.byteLength; i++) { + view.setUint8(i, bin[i]); + } + } else if (bin instanceof Float32Array) { + for (let i = 0; i< bin.byteLength; i++) { + view.setFloat32(i*4, bin[i]); + } + } else if (bin instanceof Float64Array) { + for (let i = 0; i< bin.byteLength; i++) { + view.setFloat64(i*8, bin[i]); + } + } else if (bin instanceof ArrayBuffer) { + view = new DataView(bin); + } else if (bin instanceof DataView) { + view = bin; + } + const ret = new Uint8Array(view.byteLength); + for (let i = 0; i < view.byteLength; i++) { + ret[i] = view.getUint8(i); + } + return ret; +} async function digest( algorithm: string, - data: Uint8Array + bin: BinaryArray ) { + if (kHashFuncs.indexOf(algorithm) < 0) { + throw new Error(`Unsupported hash function: ${algorithm}`); + } + const data = binaryArrayToBytes(bin); return res(await sendAsync(...req(algorithm, data))); } export class SubtleCrypto { - digest(algorithm: string | { name: string }, data: Uint8Array) { + digest(algorithm: string | { name: string }, data: BinaryArray) { if (typeof algorithm === "string") { return digest(algorithm, data); } else { diff --git a/js/webcrypto_test.ts b/js/webcrypto_test.ts index d858a6b07e399e..67bf7fe9c90ee2 100644 --- a/js/webcrypto_test.ts +++ b/js/webcrypto_test.ts @@ -1,19 +1,50 @@ -import { test, assertEqual } from "./test_util.ts"; +import { test, assert, assertEqual } from "./test_util.ts"; import * as deno from "deno"; const encoder = new TextEncoder; -const decoder = new TextDecoder; +function bytesToHex(bytes: Uint8Array|ArrayBuffer) { + let hex = ""; + for (let i = 0; i< bytes.byteLength; i++) { + let h = (bytes[i] & 0xff).toString(16); + if (h.length === 1) h = "0"+h; + hex += h + } + return hex; +} test(async function testSha1() { const bytes = encoder.encode("abcde") const res = await crypto.subtle.digest("SHA-1", bytes); - const hash = decoder.decode(res); - console.log(res,hash) + let hash = bytesToHex(res) assertEqual(hash, "03de6c570bfe24bfc328ccd7ca46b76eadaf4334") }) test(async function testSha256() { - const bytes = encoder.encode("hello, world"); + const bytes = encoder.encode("abcde"); const res = await crypto.subtle.digest("SHA-256", bytes); - const hash = decoder.decode(res); - assertEqual(hash, "09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b") + const hash = bytesToHex(res); + assertEqual(hash, "36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0c44ca42c") +}) + +test(async function testSha384() { + const bytes = encoder.encode("abcde"); + const res = await crypto.subtle.digest("SHA-384", bytes); + const hash = bytesToHex(res); + assertEqual(hash, "4c525cbeac729eaf4b4665815bc5db0c84fe6300068a727cf74e2813521565abc0ec57a37ee4d8be89d097c0d2ad52f0") +}) + +test(async function testSha512() { + const bytes = encoder.encode("abcde"); + const res = await crypto.subtle.digest("SHA-512", bytes); + const hash = bytesToHex(res); + assertEqual(hash, "878ae65a92e86cac011a570d4c30a7eaec442b85ce8eca0c2952b5e3cc0628c2e79d889ad4d5c7c626986d452dd86374b6ffaa7cd8b67665bef2289a5c70b0a1") +}) + +test(async function testUnsupportedHashFunc() { + let err; + try { + await crypto.subtle.digest("SHA-52", new Uint8Array([0,1,2])); + } catch (e) { + err = e; + } + assert(err !== void 0); }) \ No newline at end of file From 6888c90fb5a300edf4a02ff63dafc23ebeb10082 Mon Sep 17 00:00:00 2001 From: Yusuke Sakurai Date: Fri, 4 Jan 2019 19:22:00 +0900 Subject: [PATCH 4/4] fmt: reformat --- js/webcrypto.ts | 182 ++++++++++++++++++++++--------------------- js/webcrypto_test.ts | 89 +++++++++++---------- src/ops.rs | 8 +- 3 files changed, 147 insertions(+), 132 deletions(-) diff --git a/js/webcrypto.ts b/js/webcrypto.ts index 108dd2debce958..9da84958e397cc 100644 --- a/js/webcrypto.ts +++ b/js/webcrypto.ts @@ -1,109 +1,115 @@ import * as msg from "gen/msg_generated"; import * as flatbuffers from "./flatbuffers"; -import {assert} from "./util"; -import {sendAsync} from "./dispatch"; +import { assert } from "./util"; +import { sendAsync } from "./dispatch"; function req( - algorithm: string, - data: Uint8Array + algorithm: string, + data: Uint8Array ): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { - const builder = flatbuffers.createBuilder(); - const algoLoc = builder.createString(algorithm); - const dataLoc = msg.WebCryptoDigest.createDataVector(builder, data); - msg.WebCryptoDigest.startWebCryptoDigest(builder); - msg.WebCryptoDigest.addAlgorithm(builder, algoLoc); - msg.WebCryptoDigest.addData(builder, dataLoc); - const inner = msg.WebCryptoDigest.endWebCryptoDigest(builder); - return [builder, msg.Any.WebCryptoDigest, inner]; + const builder = flatbuffers.createBuilder(); + const algoLoc = builder.createString(algorithm); + const dataLoc = msg.WebCryptoDigest.createDataVector(builder, data); + msg.WebCryptoDigest.startWebCryptoDigest(builder); + msg.WebCryptoDigest.addAlgorithm(builder, algoLoc); + msg.WebCryptoDigest.addData(builder, dataLoc); + const inner = msg.WebCryptoDigest.endWebCryptoDigest(builder); + return [builder, msg.Any.WebCryptoDigest, inner]; } -function res( - baseRes: null | msg.Base -): ArrayBuffer | null { - assert(baseRes !== null); - assert(msg.Any.WebCryptoDigestRes === baseRes!.innerType()); - const res = new msg.WebCryptoDigestRes(); - assert(baseRes!.inner(res) !== null); - const result = res.resultArray(); - if (result !== null) { - return result; - } - return null; +function res(baseRes: null | msg.Base): ArrayBuffer | null { + assert(baseRes !== null); + assert(msg.Any.WebCryptoDigestRes === baseRes!.innerType()); + const res = new msg.WebCryptoDigestRes(); + assert(baseRes!.inner(res) !== null); + const result = res.resultArray(); + if (result !== null) { + return result; + } + return null; } -const kHashFuncs = ["SHA-1", "SHA-256", "SHA-384", "SHA-512"] -type BinaryArray = Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer +const kHashFuncs = ["SHA-1", "SHA-256", "SHA-384", "SHA-512"]; +type BinaryArray = + | Int8Array + | Int16Array + | Int32Array + | Uint8Array + | Uint16Array + | Uint32Array + | Uint8ClampedArray + | Float32Array + | Float64Array + | DataView + | ArrayBuffer; function binaryArrayToBytes(bin: BinaryArray): Uint8Array { - const buf = new ArrayBuffer(bin.byteLength); - let view = new DataView(buf); - if (bin instanceof Int8Array) { - for (let i = 0; i< bin.byteLength; i++) { - view.setInt8(i, bin[i]); - } - } else if (bin instanceof Int16Array) { - for (let i = 0; i< bin.byteLength; i++) { - view.setInt16(i*2, bin[i]); - } - } else if (bin instanceof Int32Array) { - for (let i = 0; i< bin.byteLength; i++) { - view.setInt32(i*4, bin[i]); - } - } else if (bin instanceof Uint8Array) { - for (let i = 0; i< bin.byteLength; i++) { - view.setUint8(i, bin[i]); - } - } else if (bin instanceof Uint16Array) { - for (let i = 0; i< bin.byteLength; i++) { - view.setUint16(i*2, bin[i]); - } - } else if (bin instanceof Uint32Array) { - for (let i = 0; i< bin.byteLength; i++) { - view.setUint32(i*4, bin[i]); - } - } else if (bin instanceof Uint8ClampedArray) { - for (let i = 0; i< bin.byteLength; i++) { - view.setUint8(i, bin[i]); - } - } else if (bin instanceof Float32Array) { - for (let i = 0; i< bin.byteLength; i++) { - view.setFloat32(i*4, bin[i]); - } - } else if (bin instanceof Float64Array) { - for (let i = 0; i< bin.byteLength; i++) { - view.setFloat64(i*8, bin[i]); - } - } else if (bin instanceof ArrayBuffer) { - view = new DataView(bin); - } else if (bin instanceof DataView) { - view = bin; + const buf = new ArrayBuffer(bin.byteLength); + let view = new DataView(buf); + if (bin instanceof Int8Array) { + for (let i = 0; i < bin.byteLength; i++) { + view.setInt8(i, bin[i]); } - const ret = new Uint8Array(view.byteLength); - for (let i = 0; i < view.byteLength; i++) { - ret[i] = view.getUint8(i); + } else if (bin instanceof Int16Array) { + for (let i = 0; i < bin.byteLength; i++) { + view.setInt16(i * 2, bin[i]); } - return ret; -} -async function digest( - algorithm: string, - bin: BinaryArray -) { - if (kHashFuncs.indexOf(algorithm) < 0) { - throw new Error(`Unsupported hash function: ${algorithm}`); + } else if (bin instanceof Int32Array) { + for (let i = 0; i < bin.byteLength; i++) { + view.setInt32(i * 4, bin[i]); + } + } else if (bin instanceof Uint8Array) { + for (let i = 0; i < bin.byteLength; i++) { + view.setUint8(i, bin[i]); + } + } else if (bin instanceof Uint16Array) { + for (let i = 0; i < bin.byteLength; i++) { + view.setUint16(i * 2, bin[i]); + } + } else if (bin instanceof Uint32Array) { + for (let i = 0; i < bin.byteLength; i++) { + view.setUint32(i * 4, bin[i]); } - const data = binaryArrayToBytes(bin); - return res(await sendAsync(...req(algorithm, data))); + } else if (bin instanceof Uint8ClampedArray) { + for (let i = 0; i < bin.byteLength; i++) { + view.setUint8(i, bin[i]); + } + } else if (bin instanceof Float32Array) { + for (let i = 0; i < bin.byteLength; i++) { + view.setFloat32(i * 4, bin[i]); + } + } else if (bin instanceof Float64Array) { + for (let i = 0; i < bin.byteLength; i++) { + view.setFloat64(i * 8, bin[i]); + } + } else if (bin instanceof ArrayBuffer) { + view = new DataView(bin); + } else if (bin instanceof DataView) { + view = bin; + } + const ret = new Uint8Array(view.byteLength); + for (let i = 0; i < view.byteLength; i++) { + ret[i] = view.getUint8(i); + } + return ret; +} +async function digest(algorithm: string, bin: BinaryArray) { + if (kHashFuncs.indexOf(algorithm) < 0) { + throw new Error(`Unsupported hash function: ${algorithm}`); + } + const data = binaryArrayToBytes(bin); + return res(await sendAsync(...req(algorithm, data))); } export class SubtleCrypto { - digest(algorithm: string | { name: string }, data: BinaryArray) { - if (typeof algorithm === "string") { - return digest(algorithm, data); - } else { - return digest(algorithm.name, data); - } + digest(algorithm: string | { name: string }, data: BinaryArray) { + if (typeof algorithm === "string") { + return digest(algorithm, data); + } else { + return digest(algorithm.name, data); } + } } export const crypto = { - subtle: new SubtleCrypto() + subtle: new SubtleCrypto() }; diff --git a/js/webcrypto_test.ts b/js/webcrypto_test.ts index 67bf7fe9c90ee2..703d9ec739af11 100644 --- a/js/webcrypto_test.ts +++ b/js/webcrypto_test.ts @@ -1,50 +1,59 @@ import { test, assert, assertEqual } from "./test_util.ts"; import * as deno from "deno"; -const encoder = new TextEncoder; -function bytesToHex(bytes: Uint8Array|ArrayBuffer) { - let hex = ""; - for (let i = 0; i< bytes.byteLength; i++) { - let h = (bytes[i] & 0xff).toString(16); - if (h.length === 1) h = "0"+h; - hex += h - } - return hex; +const encoder = new TextEncoder(); +function bytesToHex(bytes: Uint8Array | ArrayBuffer) { + let hex = ""; + for (let i = 0; i < bytes.byteLength; i++) { + let h = (bytes[i] & 0xff).toString(16); + if (h.length === 1) h = "0" + h; + hex += h; + } + return hex; } test(async function testSha1() { - const bytes = encoder.encode("abcde") - const res = await crypto.subtle.digest("SHA-1", bytes); - let hash = bytesToHex(res) - assertEqual(hash, "03de6c570bfe24bfc328ccd7ca46b76eadaf4334") -}) + const bytes = encoder.encode("abcde"); + const res = await crypto.subtle.digest("SHA-1", bytes); + let hash = bytesToHex(res); + assertEqual(hash, "03de6c570bfe24bfc328ccd7ca46b76eadaf4334"); +}); -test(async function testSha256() { - const bytes = encoder.encode("abcde"); - const res = await crypto.subtle.digest("SHA-256", bytes); - const hash = bytesToHex(res); - assertEqual(hash, "36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0c44ca42c") -}) +test(async function testSha256() { + const bytes = encoder.encode("abcde"); + const res = await crypto.subtle.digest("SHA-256", bytes); + const hash = bytesToHex(res); + assertEqual( + hash, + "36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0c44ca42c" + ); +}); -test(async function testSha384() { - const bytes = encoder.encode("abcde"); - const res = await crypto.subtle.digest("SHA-384", bytes); - const hash = bytesToHex(res); - assertEqual(hash, "4c525cbeac729eaf4b4665815bc5db0c84fe6300068a727cf74e2813521565abc0ec57a37ee4d8be89d097c0d2ad52f0") -}) +test(async function testSha384() { + const bytes = encoder.encode("abcde"); + const res = await crypto.subtle.digest("SHA-384", bytes); + const hash = bytesToHex(res); + assertEqual( + hash, + "4c525cbeac729eaf4b4665815bc5db0c84fe6300068a727cf74e2813521565abc0ec57a37ee4d8be89d097c0d2ad52f0" + ); +}); -test(async function testSha512() { - const bytes = encoder.encode("abcde"); - const res = await crypto.subtle.digest("SHA-512", bytes); - const hash = bytesToHex(res); - assertEqual(hash, "878ae65a92e86cac011a570d4c30a7eaec442b85ce8eca0c2952b5e3cc0628c2e79d889ad4d5c7c626986d452dd86374b6ffaa7cd8b67665bef2289a5c70b0a1") -}) +test(async function testSha512() { + const bytes = encoder.encode("abcde"); + const res = await crypto.subtle.digest("SHA-512", bytes); + const hash = bytesToHex(res); + assertEqual( + hash, + "878ae65a92e86cac011a570d4c30a7eaec442b85ce8eca0c2952b5e3cc0628c2e79d889ad4d5c7c626986d452dd86374b6ffaa7cd8b67665bef2289a5c70b0a1" + ); +}); test(async function testUnsupportedHashFunc() { - let err; - try { - await crypto.subtle.digest("SHA-52", new Uint8Array([0,1,2])); - } catch (e) { - err = e; - } - assert(err !== void 0); -}) \ No newline at end of file + let err; + try { + await crypto.subtle.digest("SHA-52", new Uint8Array([0, 1, 2])); + } catch (e) { + err = e; + } + assert(err !== void 0); +}); diff --git a/src/ops.rs b/src/ops.rs index 84d175d201ce50..b9b9c865470bb4 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -22,7 +22,7 @@ use hyper::rt::Future; use remove_dir_all::remove_dir_all; use repl; use resources::table_entries; -use ring::{digest}; +use ring::digest; use std; use std::convert::From; use std::fs; @@ -1555,7 +1555,7 @@ fn op_webcrypto_digest( builder, &msg::WebCryptoDigestResArgs { result: Some(result), - } + }, ); ok_future(serialize_response( cmd_id, @@ -1564,6 +1564,6 @@ fn op_webcrypto_digest( inner: Some(inner.as_union_value()), inner_type: msg::Any::WebCryptoDigestRes, ..Default::default() - } + }, )) -} \ No newline at end of file +}