summaryrefslogtreecommitdiff
path: root/ext/node/polyfills/internal/crypto/sig.ts
diff options
context:
space:
mode:
authorYoshiya Hinosawa <stibium121@gmail.com>2023-03-28 21:46:48 +0900
committerGitHub <noreply@github.com>2023-03-28 21:46:48 +0900
commit4358ab2d848cc6ba363f42e5f5b5b898b656db05 (patch)
treed4dc7dc75cbed3fdb794b508450cc6903d120c8f /ext/node/polyfills/internal/crypto/sig.ts
parente5b2815b3943cd39038bba00da462082c6988e6e (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.ts66
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;
}
}