diff options
Diffstat (limited to 'extensions/crypto')
-rw-r--r-- | extensions/crypto/01_crypto.js | 50 | ||||
-rw-r--r-- | extensions/crypto/Cargo.toml | 19 | ||||
-rw-r--r-- | extensions/crypto/README.md | 5 | ||||
-rw-r--r-- | extensions/crypto/lib.deno_crypto.d.ts | 26 | ||||
-rw-r--r-- | extensions/crypto/lib.rs | 56 |
5 files changed, 156 insertions, 0 deletions
diff --git a/extensions/crypto/01_crypto.js b/extensions/crypto/01_crypto.js new file mode 100644 index 000000000..dba6b0091 --- /dev/null +++ b/extensions/crypto/01_crypto.js @@ -0,0 +1,50 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. +"use strict"; + +((window) => { + const core = window.Deno.core; + + function getRandomValues(arrayBufferView) { + if (!ArrayBuffer.isView(arrayBufferView)) { + throw new TypeError( + "Argument 1 does not implement interface ArrayBufferView", + ); + } + 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", + ); + } + if (arrayBufferView.byteLength > 65536) { + throw new DOMException( + `The ArrayBufferView's byte length (${arrayBufferView.byteLength}) exceeds the number of bytes of entropy available via this API (65536)`, + "QuotaExceededError", + ); + } + const ui8 = new Uint8Array( + arrayBufferView.buffer, + arrayBufferView.byteOffset, + arrayBufferView.byteLength, + ); + core.opSync("op_crypto_get_random_values", null, ui8); + return arrayBufferView; + } + + window.crypto = { + getRandomValues, + }; + window.__bootstrap.crypto = { + getRandomValues, + }; +})(this); diff --git a/extensions/crypto/Cargo.toml b/extensions/crypto/Cargo.toml new file mode 100644 index 000000000..91f60aa9c --- /dev/null +++ b/extensions/crypto/Cargo.toml @@ -0,0 +1,19 @@ +# Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. + +[package] +name = "deno_crypto" +version = "0.19.0" +edition = "2018" +description = "Web Cryptography API implementation for Deno" +authors = ["the Deno authors"] +license = "MIT" +readme = "README.md" +repository = "https://github.com/denoland/deno" + +[lib] +path = "lib.rs" + +[dependencies] +deno_core = { version = "0.86.0", path = "../../core" } +rand = "0.8.3" + diff --git a/extensions/crypto/README.md b/extensions/crypto/README.md new file mode 100644 index 000000000..be0724458 --- /dev/null +++ b/extensions/crypto/README.md @@ -0,0 +1,5 @@ +# deno_crypto + +This crate implements the Web Cryptography API. + +Spec: https://www.w3.org/TR/WebCryptoAPI/ diff --git a/extensions/crypto/lib.deno_crypto.d.ts b/extensions/crypto/lib.deno_crypto.d.ts new file mode 100644 index 000000000..a00757e71 --- /dev/null +++ b/extensions/crypto/lib.deno_crypto.d.ts @@ -0,0 +1,26 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. + +/// <reference no-default-lib="true" /> +/// <reference lib="esnext" /> + +declare var crypto: Crypto; + +declare interface Crypto { + readonly subtle: null; + getRandomValues< + T extends + | Int8Array + | Int16Array + | Int32Array + | Uint8Array + | Uint16Array + | Uint32Array + | Uint8ClampedArray + | Float32Array + | Float64Array + | DataView + | null, + >( + array: T, + ): T; +} diff --git a/extensions/crypto/lib.rs b/extensions/crypto/lib.rs new file mode 100644 index 000000000..45473f4d5 --- /dev/null +++ b/extensions/crypto/lib.rs @@ -0,0 +1,56 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. + +use deno_core::error::null_opbuf; +use deno_core::error::AnyError; +use deno_core::include_js_files; +use deno_core::op_sync; +use deno_core::Extension; +use deno_core::OpState; +use deno_core::ZeroCopyBuf; +use rand::rngs::StdRng; +use rand::thread_rng; +use rand::Rng; +use rand::SeedableRng; +use std::path::PathBuf; + +pub use rand; // Re-export rand + +pub fn init(maybe_seed: Option<u64>) -> Extension { + Extension::builder() + .js(include_js_files!( + prefix "deno:extensions/crypto", + "01_crypto.js", + )) + .ops(vec![( + "op_crypto_get_random_values", + op_sync(op_crypto_get_random_values), + )]) + .state(move |state| { + if let Some(seed) = maybe_seed { + state.put(StdRng::seed_from_u64(seed)); + } + Ok(()) + }) + .build() +} + +pub fn op_crypto_get_random_values( + state: &mut OpState, + _args: (), + zero_copy: Option<ZeroCopyBuf>, +) -> Result<(), AnyError> { + let mut zero_copy = zero_copy.ok_or_else(null_opbuf)?; + let maybe_seeded_rng = state.try_borrow_mut::<StdRng>(); + if let Some(seeded_rng) = maybe_seeded_rng { + seeded_rng.fill(&mut *zero_copy); + } else { + let mut rng = thread_rng(); + rng.fill(&mut *zero_copy); + } + + Ok(()) +} + +pub fn get_declaration() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_crypto.d.ts") +} |