summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2023-04-06 18:39:25 +0530
committerGitHub <noreply@github.com>2023-04-06 18:39:25 +0530
commit3b62a58818f83e32fc2644f44e75a5c8465b2003 (patch)
treecf8f0a6d7995fa0c632247f2679295b8ceea4460 /ext
parent339165bd9565806374fa842dfc217dcc5ebabac5 (diff)
fix(ext/node): add symmetric keygen (#18609)
Towards #18455
Diffstat (limited to 'ext')
-rw-r--r--ext/node/crypto/mod.rs17
-rw-r--r--ext/node/lib.rs2
-rw-r--r--ext/node/polyfills/internal/crypto/keygen.ts79
-rw-r--r--ext/node/polyfills/internal/crypto/keys.ts6
-rw-r--r--ext/node/polyfills/internal/crypto/util.ts5
5 files changed, 93 insertions, 16 deletions
diff --git a/ext/node/crypto/mod.rs b/ext/node/crypto/mod.rs
index 3529a3aa4..499e99fea 100644
--- a/ext/node/crypto/mod.rs
+++ b/ext/node/crypto/mod.rs
@@ -8,6 +8,7 @@ use deno_core::ResourceId;
use deno_core::StringOrBuffer;
use deno_core::ZeroCopyBuf;
use num_bigint::BigInt;
+use rand::Rng;
use std::future::Future;
use std::rc::Rc;
@@ -402,3 +403,19 @@ pub async fn op_node_pbkdf2_async(
})
.await?
}
+
+#[op]
+pub fn op_node_generate_secret(buf: &mut [u8]) {
+ rand::thread_rng().fill(buf);
+}
+
+#[op]
+pub async fn op_node_generate_secret_async(len: i32) -> ZeroCopyBuf {
+ tokio::task::spawn_blocking(move || {
+ let mut buf = vec![0u8; len as usize];
+ rand::thread_rng().fill(&mut buf[..]);
+ buf.into()
+ })
+ .await
+ .unwrap()
+}
diff --git a/ext/node/lib.rs b/ext/node/lib.rs
index 04fd07cab..ec3e7ab25 100644
--- a/ext/node/lib.rs
+++ b/ext/node/lib.rs
@@ -170,6 +170,8 @@ deno_core::extension!(deno_node,
crypto::op_node_check_prime_bytes_async,
crypto::op_node_pbkdf2,
crypto::op_node_pbkdf2_async,
+ crypto::op_node_generate_secret,
+ crypto::op_node_generate_secret_async,
crypto::op_node_sign,
winerror::op_node_sys_to_uv_error,
v8::op_v8_cached_data_version_tag,
diff --git a/ext/node/polyfills/internal/crypto/keygen.ts b/ext/node/polyfills/internal/crypto/keygen.ts
index dadc9c198..b490cedd7 100644
--- a/ext/node/polyfills/internal/crypto/keygen.ts
+++ b/ext/node/polyfills/internal/crypto/keygen.ts
@@ -2,18 +2,80 @@
// Copyright Joyent, Inc. and Node.js contributors. All rights reserved. MIT license.
import { KeyObject } from "ext:deno_node/internal/crypto/keys.ts";
+import { kAesKeyLengths } from "ext:deno_node/internal/crypto/util.ts";
+import {
+ SecretKeyObject,
+ setOwnedKey,
+} from "ext:deno_node/internal/crypto/keys.ts";
import { notImplemented } from "ext:deno_node/_utils.ts";
+import { ERR_INVALID_ARG_VALUE } from "ext:deno_node/internal/errors.ts";
+import {
+ validateFunction,
+ validateInteger,
+ validateObject,
+ validateOneOf,
+ validateString,
+} from "ext:deno_node/internal/validators.mjs";
import { Buffer } from "ext:deno_node/buffer.ts";
import { KeyFormat, KeyType } from "ext:deno_node/internal/crypto/types.ts";
+const { core } = globalThis.__bootstrap;
+const { ops } = core;
+
+function validateGenerateKey(
+ type: "hmac" | "aes",
+ options: { length: number },
+) {
+ validateString(type, "type");
+ validateObject(options, "options");
+ const { length } = options;
+ switch (type) {
+ case "hmac":
+ validateInteger(length, "options.length", 8, 2 ** 31 - 1);
+ break;
+ case "aes":
+ validateOneOf(length, "options.length", kAesKeyLengths);
+ break;
+ default:
+ throw new ERR_INVALID_ARG_VALUE(
+ "type",
+ type,
+ "must be a supported key type",
+ );
+ }
+}
+
+export function generateKeySync(
+ type: "hmac" | "aes",
+ options: {
+ length: number;
+ },
+): KeyObject {
+ validateGenerateKey(type, options);
+ const { length } = options;
+
+ const key = new Uint8Array(Math.floor(length / 8));
+ ops.op_node_generate_secret(key);
+
+ return new SecretKeyObject(setOwnedKey(key));
+}
+
export function generateKey(
- _type: "hmac" | "aes",
- _options: {
+ type: "hmac" | "aes",
+ options: {
length: number;
},
- _callback: (err: Error | null, key: KeyObject) => void,
+ callback: (err: Error | null, key: KeyObject) => void,
) {
- notImplemented("crypto.generateKey");
+ validateGenerateKey(type, options);
+ validateFunction(callback, "callback");
+ const { length } = options;
+
+ core.opAsync("op_node_generate_secret_async", Math.floor(length / 8)).then(
+ (key) => {
+ callback(null, new SecretKeyObject(setOwnedKey(key)));
+ },
+ );
}
export interface BasePrivateKeyEncodingOptions<T extends KeyFormat> {
@@ -662,15 +724,6 @@ export function generateKeyPairSync(
notImplemented("crypto.generateKeyPairSync");
}
-export function generateKeySync(
- _type: "hmac" | "aes",
- _options: {
- length: number;
- },
-): KeyObject {
- notImplemented("crypto.generateKeySync");
-}
-
export default {
generateKey,
generateKeySync,
diff --git a/ext/node/polyfills/internal/crypto/keys.ts b/ext/node/polyfills/internal/crypto/keys.ts
index eb7990b06..ef2aba737 100644
--- a/ext/node/polyfills/internal/crypto/keys.ts
+++ b/ext/node/polyfills/internal/crypto/keys.ts
@@ -279,7 +279,7 @@ export function prepareSecretKey(
return getArrayBufferOrView(key, "key", encoding);
}
-class SecretKeyObject extends KeyObject {
+export class SecretKeyObject extends KeyObject {
constructor(handle: unknown) {
super("secret", handle);
}
@@ -313,7 +313,7 @@ class SecretKeyObject extends KeyObject {
}
}
-function setOwnedKey(key: Uint8Array): unknown {
+export function setOwnedKey(key: Uint8Array): unknown {
const handle = {};
KEY_STORE.set(handle, key);
return handle;
@@ -345,4 +345,6 @@ export default {
isCryptoKey,
KeyObject,
prepareSecretKey,
+ setOwnedKey,
+ SecretKeyObject,
};
diff --git a/ext/node/polyfills/internal/crypto/util.ts b/ext/node/polyfills/internal/crypto/util.ts
index 317c1d503..ccb772631 100644
--- a/ext/node/polyfills/internal/crypto/util.ts
+++ b/ext/node/polyfills/internal/crypto/util.ts
@@ -133,7 +133,9 @@ export function setEngine(_engine: string, _flags: typeof constants) {
notImplemented("crypto.setEngine");
}
-export { kHandle, kKeyObject };
+const kAesKeyLengths = [128, 192, 256];
+
+export { kAesKeyLengths, kHandle, kKeyObject };
export default {
getDefaultEncoding,
@@ -147,4 +149,5 @@ export default {
toBuf,
kHandle,
kKeyObject,
+ kAesKeyLengths,
};