summaryrefslogtreecommitdiff
path: root/ext/node/polyfills/internal/crypto
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2023-11-09 09:56:59 -0800
committerGitHub <noreply@github.com>2023-11-09 23:26:59 +0530
commitc4029f6af22b373bf22383453cb4e2159f3b5b72 (patch)
tree588594d5d5eb98689101565fb76c6a546cc9e78a /ext/node/polyfills/internal/crypto
parentee7fd0a2127e6a435023bf9a43de60130117697d (diff)
fix(node): implement createPrivateKey (#20981)
Towards #18455
Diffstat (limited to 'ext/node/polyfills/internal/crypto')
-rw-r--r--ext/node/polyfills/internal/crypto/cipher.ts5
-rw-r--r--ext/node/polyfills/internal/crypto/keys.ts75
-rw-r--r--ext/node/polyfills/internal/crypto/sig.ts11
3 files changed, 69 insertions, 22 deletions
diff --git a/ext/node/polyfills/internal/crypto/cipher.ts b/ext/node/polyfills/internal/crypto/cipher.ts
index cf1641326..5fec98ff0 100644
--- a/ext/node/polyfills/internal/crypto/cipher.ts
+++ b/ext/node/polyfills/internal/crypto/cipher.ts
@@ -28,7 +28,7 @@ import {
isArrayBufferView,
} from "ext:deno_node/internal/util/types.ts";
-function isStringOrBuffer(val) {
+export function isStringOrBuffer(val) {
return typeof val === "string" ||
isArrayBufferView(val) ||
isAnyArrayBuffer(val);
@@ -456,7 +456,7 @@ export function publicEncrypt(
return ops.op_node_public_encrypt(data, buffer, padding);
}
-function prepareKey(key) {
+export function prepareKey(key) {
// TODO(@littledivy): handle these cases
// - node KeyObject
// - web CryptoKey
@@ -485,5 +485,6 @@ export default {
publicEncrypt,
Cipheriv,
Decipheriv,
+ prepareKey,
getCipherInfo,
};
diff --git a/ext/node/polyfills/internal/crypto/keys.ts b/ext/node/polyfills/internal/crypto/keys.ts
index be85b44a3..e0c44cbf9 100644
--- a/ext/node/polyfills/internal/crypto/keys.ts
+++ b/ext/node/polyfills/internal/crypto/keys.ts
@@ -8,6 +8,7 @@ import {
kHandle,
kKeyObject,
} from "ext:deno_node/internal/crypto/constants.ts";
+import { isStringOrBuffer } from "ext:deno_node/internal/crypto/cipher.ts";
import {
ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE,
ERR_INVALID_ARG_TYPE,
@@ -16,7 +17,6 @@ import {
import { notImplemented } from "ext:deno_node/_utils.ts";
import type {
KeyFormat,
- KeyType,
PrivateKeyInput,
PublicKeyInput,
} from "ext:deno_node/internal/crypto/types.ts";
@@ -39,6 +39,9 @@ import {
forgivingBase64UrlEncode as encodeToBase64Url,
} from "ext:deno_web/00_infra.js";
+const { core } = globalThis.__bootstrap;
+const { ops } = core;
+
export const getArrayBufferOrView = hideStackFrames(
(
buffer,
@@ -168,18 +171,6 @@ export class KeyObject {
return this[kKeyType];
}
- get asymmetricKeyDetails(): AsymmetricKeyDetails | undefined {
- notImplemented("crypto.KeyObject.prototype.asymmetricKeyDetails");
-
- return undefined;
- }
-
- get asymmetricKeyType(): KeyType | undefined {
- notImplemented("crypto.KeyObject.prototype.asymmetricKeyType");
-
- return undefined;
- }
-
get symmetricKeySize(): number | undefined {
notImplemented("crypto.KeyObject.prototype.symmetricKeySize");
@@ -219,10 +210,33 @@ export interface JsonWebKeyInput {
format: "jwk";
}
+function prepareAsymmetricKey(key) {
+ if (isStringOrBuffer(key)) {
+ return { format: "pem", data: getArrayBufferOrView(key, "key") };
+ } else if (typeof key == "object") {
+ const { key: data, encoding, format, type } = key;
+ if (!isStringOrBuffer(data)) {
+ throw new TypeError("Invalid key type");
+ }
+
+ return {
+ data: getArrayBufferOrView(data, "key", encoding),
+ format: format ?? "pem",
+ encoding,
+ type,
+ };
+ }
+
+ throw new TypeError("Invalid key type");
+}
+
export function createPrivateKey(
- _key: PrivateKeyInput | string | Buffer | JsonWebKeyInput,
-): KeyObject {
- notImplemented("crypto.createPrivateKey");
+ key: PrivateKeyInput | string | Buffer | JsonWebKeyInput,
+): PrivateKeyObject {
+ const { data, format, type } = prepareAsymmetricKey(key);
+ const details = ops.op_node_create_private_key(data, format, type);
+ const handle = setOwnedKey(copyBuffer(data));
+ return new PrivateKeyObject(handle, details);
}
export function createPublicKey(
@@ -316,6 +330,35 @@ export class SecretKeyObject extends KeyObject {
}
}
+const kAsymmetricKeyType = Symbol("kAsymmetricKeyType");
+const kAsymmetricKeyDetails = Symbol("kAsymmetricKeyDetails");
+
+class AsymmetricKeyObject extends KeyObject {
+ constructor(type: KeyObjectType, handle: unknown, details: unknown) {
+ super(type, handle);
+ this[kAsymmetricKeyType] = details.type;
+ this[kAsymmetricKeyDetails] = { ...details };
+ }
+
+ get asymmetricKeyType() {
+ return this[kAsymmetricKeyType];
+ }
+
+ get asymmetricKeyDetails() {
+ return this[kAsymmetricKeyDetails];
+ }
+}
+
+class PrivateKeyObject extends AsymmetricKeyObject {
+ constructor(handle: unknown, details: unknown) {
+ super("private", handle, details);
+ }
+
+ export(_options: unknown) {
+ notImplemented("crypto.PrivateKeyObject.prototype.export");
+ }
+}
+
export function setOwnedKey(key: Uint8Array): unknown {
const handle = {};
KEY_STORE.set(handle, key);
diff --git a/ext/node/polyfills/internal/crypto/sig.ts b/ext/node/polyfills/internal/crypto/sig.ts
index ebbd11dc6..c5eb34fae 100644
--- a/ext/node/polyfills/internal/crypto/sig.ts
+++ b/ext/node/polyfills/internal/crypto/sig.ts
@@ -19,7 +19,10 @@ import type {
PrivateKeyInput,
PublicKeyInput,
} from "ext:deno_node/internal/crypto/types.ts";
-import { KeyObject } from "ext:deno_node/internal/crypto/keys.ts";
+import {
+ getKeyMaterial,
+ KeyObject,
+} from "ext:deno_node/internal/crypto/keys.ts";
import { createHash, Hash } from "ext:deno_node/internal/crypto/hash.ts";
import { KeyFormat, KeyType } from "ext:deno_node/internal/crypto/types.ts";
import { isArrayBufferView } from "ext:deno_node/internal/util/types.ts";
@@ -87,9 +90,9 @@ export class SignImpl extends Writable {
keyType = "rsa";
keyFormat = "pem";
} else {
- // TODO(kt3k): Add support for the case when privateKey is a KeyObject,
- // CryptoKey, etc
- notImplemented("crypto.Sign.prototype.sign with non BinaryLike input");
+ keyData = getKeyMaterial(privateKey);
+ keyType = "rsa";
+ keyFormat = "pem";
}
const ret = Buffer.from(ops.op_node_sign(
this.hash.digest(),