diff options
| author | Divy Srivastava <dj.srivastava23@gmail.com> | 2024-03-14 06:30:29 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-14 19:00:29 +0530 |
| commit | cf3c6f9b0812ad487320834399bc4863dadd9655 (patch) | |
| tree | f6d3491716661624d2f6453c63cf102c945d77fe /ext/node/polyfills/internal | |
| parent | cad79af785d2490aadacd935062b1703adef50d2 (diff) | |
fix(ext/node): crypto.getCipherInfo() (#22916)
Stub implementation of getCipherInfo(). Good enough for most cases.
Note: We do not support all OpenSSL ciphers (likely never will)
Fixes https://github.com/denoland/deno/issues/21805
Diffstat (limited to 'ext/node/polyfills/internal')
| -rw-r--r-- | ext/node/polyfills/internal/crypto/cipher.ts | 41 | ||||
| -rw-r--r-- | ext/node/polyfills/internal/crypto/util.ts | 84 |
2 files changed, 84 insertions, 41 deletions
diff --git a/ext/node/polyfills/internal/crypto/cipher.ts b/ext/node/polyfills/internal/crypto/cipher.ts index 20971a8c7..f8a46896d 100644 --- a/ext/node/polyfills/internal/crypto/cipher.ts +++ b/ext/node/polyfills/internal/crypto/cipher.ts @@ -22,11 +22,6 @@ import { op_node_public_encrypt, } from "ext:core/ops"; -import { ERR_INVALID_ARG_TYPE } from "ext:deno_node/internal/errors.ts"; -import { - validateInt32, - validateObject, -} from "ext:deno_node/internal/validators.mjs"; import { Buffer } from "node:buffer"; import { notImplemented } from "ext:deno_node/_utils.ts"; import type { TransformOptions } from "ext:deno_node/_stream.d.ts"; @@ -405,41 +400,6 @@ export class Decipheriv extends Transform implements Cipher { } } -export function getCipherInfo( - nameOrNid: string | number, - options?: { keyLength?: number; ivLength?: number }, -) { - if (typeof nameOrNid !== "string" && typeof nameOrNid !== "number") { - throw new ERR_INVALID_ARG_TYPE( - "nameOrNid", - ["string", "number"], - nameOrNid, - ); - } - - if (typeof nameOrNid === "number") { - validateInt32(nameOrNid, "nameOrNid"); - } - - let keyLength, ivLength; - - if (options !== undefined) { - validateObject(options, "options"); - - ({ keyLength, ivLength } = options); - - if (keyLength !== undefined) { - validateInt32(keyLength, "options.keyLength"); - } - - if (ivLength !== undefined) { - validateInt32(ivLength, "options.ivLength"); - } - } - - notImplemented("crypto.getCipherInfo"); -} - export function privateEncrypt( privateKey: ArrayBufferView | string | KeyObject, buffer: ArrayBufferView | string | KeyObject, @@ -503,5 +463,4 @@ export default { Cipheriv, Decipheriv, prepareKey, - getCipherInfo, }; diff --git a/ext/node/polyfills/internal/crypto/util.ts b/ext/node/polyfills/internal/crypto/util.ts index 91e2c92a2..a68ac3682 100644 --- a/ext/node/polyfills/internal/crypto/util.ts +++ b/ext/node/polyfills/internal/crypto/util.ts @@ -83,6 +83,89 @@ export function getCiphers(): string[] { return supportedCiphers; } +export function getCipherInfo( + nameOrNid: string | number, + options?: { keyLength?: number; ivLength?: number }, +) { + if (typeof nameOrNid !== "string" && typeof nameOrNid !== "number") { + throw new ERR_INVALID_ARG_TYPE( + "nameOrNid", + ["string", "number"], + nameOrNid, + ); + } + + if (typeof nameOrNid === "number") { + validateInt32(nameOrNid, "nameOrNid"); + } + + let keyLength, ivLength; + + if (options !== undefined) { + validateObject(options, "options"); + + ({ keyLength, ivLength } = options); + + if (keyLength !== undefined) { + validateInt32(keyLength, "options.keyLength"); + } + + if (ivLength !== undefined) { + validateInt32(ivLength, "options.ivLength"); + } + } + + // This API is heavily based on OpenSSL's EVP_get_cipherbyname(3) and + // EVP_get_cipherbynid(3) functions. + // + // TODO(@littledivy): write proper cipher info utility in Rust + // in future refactors + const cipher = supportedCiphers.find((c) => c === nameOrNid); + if (cipher === undefined) { + return undefined; + } + + const match = cipher.match(/^(aes)-(\d+)-(\w+)$/); + if (match) { + const [, name, keyLength, mode] = match; + return { + name: `${name}-${keyLength}-${mode}`, + keyLength: parseInt(keyLength) / 8, + mode, + ivLength: 16, + }; + } + + if (cipher === "aes128") { + return { + name: "aes-128-cbc", + keyLength: 16, + mode: "cbc", + ivLength: 16, + }; + } + + if (cipher === "aes192") { + return { + name: "aes-192-cbc", + keyLength: 24, + mode: "cbc", + ivLength: 16, + }; + } + + if (cipher === "aes256") { + return { + name: "aes-256-cbc", + keyLength: 32, + mode: "cbc", + ivLength: 16, + }; + } + + return undefined; +} + let defaultEncoding = "buffer"; export function setDefaultEncoding(val: string) { @@ -150,6 +233,7 @@ export default { getDefaultEncoding, setDefaultEncoding, getCiphers, + getCipherInfo, getCurves, secureHeapUsed, setEngine, |
