diff options
author | Yoshiya Hinosawa <stibium121@gmail.com> | 2023-03-28 21:46:48 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-28 21:46:48 +0900 |
commit | 4358ab2d848cc6ba363f42e5f5b5b898b656db05 (patch) | |
tree | d4dc7dc75cbed3fdb794b508450cc6903d120c8f /ext/node/polyfills/internal/crypto/sig.ts | |
parent | e5b2815b3943cd39038bba00da462082c6988e6e (diff) |
fix(ext/node): implement crypto.Sign (RSA/PEM/SHA{224,256,384,512}) (#18471)
Diffstat (limited to 'ext/node/polyfills/internal/crypto/sig.ts')
-rw-r--r-- | ext/node/polyfills/internal/crypto/sig.ts | 66 |
1 files changed, 52 insertions, 14 deletions
diff --git a/ext/node/polyfills/internal/crypto/sig.ts b/ext/node/polyfills/internal/crypto/sig.ts index d61f82b0e..e49128b1e 100644 --- a/ext/node/polyfills/internal/crypto/sig.ts +++ b/ext/node/polyfills/internal/crypto/sig.ts @@ -14,6 +14,12 @@ import type { PublicKeyInput, } from "ext:deno_node/internal/crypto/types.ts"; import { 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"; + +const { core } = globalThis.__bootstrap; +const { ops } = core; export type DSAEncoding = "der" | "ieee-p1363"; @@ -37,30 +43,62 @@ export interface VerifyKeyObjectInput extends SigningOptions { export type KeyLike = string | Buffer | KeyObject; export class Sign extends Writable { + hash: Hash; + #digestType: string; + constructor(algorithm: string, _options?: WritableOptions) { validateString(algorithm, "algorithm"); - super(); - - notImplemented("crypto.Sign"); + super({ + write(chunk, enc, callback) { + this.update(chunk, enc); + callback(); + }, + }); + + algorithm = algorithm.toLowerCase(); + + if (algorithm.startsWith("rsa-")) { + // Allows RSA-[digest_algorithm] as a valid algorithm + algorithm = algorithm.slice(4); + } + this.#digestType = algorithm; + this.hash = createHash(this.#digestType); } - sign(privateKey: KeyLike | SignKeyObjectInput | SignPrivateKeyInput): Buffer; sign( privateKey: KeyLike | SignKeyObjectInput | SignPrivateKeyInput, - outputFormat: BinaryToTextEncoding, - ): string; - sign( - _privateKey: KeyLike | SignKeyObjectInput | SignPrivateKeyInput, - _outputEncoding?: BinaryToTextEncoding, + encoding?: BinaryToTextEncoding, ): Buffer | string { - notImplemented("crypto.Sign.prototype.sign"); + let keyData: Uint8Array; + let keyType: KeyType; + let keyFormat: KeyFormat; + if (typeof privateKey === "string" || isArrayBufferView(privateKey)) { + // if the key is BinaryLike, interpret it as a PEM encoded RSA key + keyData = privateKey; + 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"); + } + const ret = Buffer.from(ops.op_node_sign( + this.hash.digest(), + this.#digestType, + keyData!, + keyType, + keyFormat, + )); + return encoding ? ret.toString(encoding) : ret; } - update(data: BinaryLike): this; - update(data: string, inputEncoding: Encoding): this; - update(_data: BinaryLike | string, _inputEncoding?: Encoding): this { - notImplemented("crypto.Sign.prototype.update"); + update( + data: BinaryLike | string, + encoding?: Encoding, + ): this { + this.hash.update(data, encoding); + return this; } } |