1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-26 16:09:27 -05:00

fix(ext/node): add crypto.sign|verify methods (#18765)

This commit is contained in:
Yoshiya Hinosawa 2023-04-19 23:24:26 +09:00 committed by GitHub
parent 5a77bb8844
commit fdebb7e793
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 87 additions and 41 deletions

View file

@ -4,7 +4,7 @@ import {
assert, assert,
assertEquals, assertEquals,
} from "../../../test_util/std/testing/asserts.ts"; } from "../../../test_util/std/testing/asserts.ts";
import { createSign, createVerify } from "node:crypto"; import { createSign, createVerify, sign, verify } from "node:crypto";
import { Buffer } from "node:buffer"; import { Buffer } from "node:buffer";
const rsaPrivatePem = Buffer.from( const rsaPrivatePem = Buffer.from(
@ -41,32 +41,50 @@ const table = [
}, },
]; ];
const data = Buffer.from("some data to sign");
Deno.test({ Deno.test({
name: "crypto.Sign - RSA PEM with SHA224, SHA256, SHA384, SHA512 digests", name:
"crypto.Sign|sign - RSA PEM with SHA224, SHA256, SHA384, SHA512 digests",
fn() { fn() {
for (const testCase of table) { for (const testCase of table) {
for (const algorithm of testCase.algorithms) { for (const algorithm of testCase.algorithms) {
const signature = createSign(algorithm) assertEquals(
.update("some data to sign") createSign(algorithm)
.sign(rsaPrivatePem, "hex"); .update(data)
assertEquals(signature, testCase.signature); .sign(rsaPrivatePem, "hex"),
testCase.signature,
);
assertEquals(
sign(algorithm, data, rsaPrivatePem),
Buffer.from(testCase.signature, "hex"),
);
} }
} }
}, },
}); });
Deno.test({ Deno.test({
name: "crypto.Verify - RSA PEM with SHA224, SHA256, SHA384, SHA512 digests", name:
"crypto.Verify|verify - RSA PEM with SHA224, SHA256, SHA384, SHA512 digests",
fn() { fn() {
for (const testCase of table) { for (const testCase of table) {
for (const algorithm of testCase.algorithms) { for (const algorithm of testCase.algorithms) {
assert( assert(
createVerify(algorithm).update("some data to sign").verify( createVerify(algorithm).update(data).verify(
rsaPublicPem, rsaPublicPem,
testCase.signature, testCase.signature,
"hex", "hex",
), ),
); );
assert(
verify(
algorithm,
data,
rsaPublicPem,
Buffer.from(testCase.signature, "hex"),
),
);
} }
} }
}, },

View file

@ -2,7 +2,10 @@
// Copyright Joyent, Inc. and Node.js contributors. All rights reserved. MIT license. // Copyright Joyent, Inc. and Node.js contributors. All rights reserved. MIT license.
import { notImplemented } from "ext:deno_node/_utils.ts"; import { notImplemented } from "ext:deno_node/_utils.ts";
import { validateString } from "ext:deno_node/internal/validators.mjs"; import {
validateFunction,
validateString,
} from "ext:deno_node/internal/validators.mjs";
import { Buffer } from "ext:deno_node/buffer.ts"; import { Buffer } from "ext:deno_node/buffer.ts";
import type { WritableOptions } from "ext:deno_node/_stream.d.ts"; import type { WritableOptions } from "ext:deno_node/_stream.d.ts";
import Writable from "ext:deno_node/internal/streams/writable.mjs"; import Writable from "ext:deno_node/internal/streams/writable.mjs";
@ -17,6 +20,7 @@ import { KeyObject } from "ext:deno_node/internal/crypto/keys.ts";
import { createHash, Hash } from "ext:deno_node/internal/crypto/hash.ts"; import { createHash, Hash } from "ext:deno_node/internal/crypto/hash.ts";
import { KeyFormat, KeyType } from "ext:deno_node/internal/crypto/types.ts"; import { KeyFormat, KeyType } from "ext:deno_node/internal/crypto/types.ts";
import { isArrayBufferView } from "ext:deno_node/internal/util/types.ts"; import { isArrayBufferView } from "ext:deno_node/internal/util/types.ts";
import { ERR_CRYPTO_SIGN_KEY_REQUIRED } from "ext:deno_node/internal/errors.ts";
const { core } = globalThis.__bootstrap; const { core } = globalThis.__bootstrap;
const { ops } = core; const { ops } = core;
@ -42,7 +46,7 @@ export interface VerifyKeyObjectInput extends SigningOptions {
export type KeyLike = string | Buffer | KeyObject; export type KeyLike = string | Buffer | KeyObject;
export class Sign extends Writable { export class SignImpl extends Writable {
hash: Hash; hash: Hash;
#digestType: string; #digestType: string;
@ -103,7 +107,13 @@ export class Sign extends Writable {
} }
} }
export class Verify extends Writable { export function Sign(algorithm: string, options?: WritableOptions) {
return new SignImpl(algorithm, options);
}
Sign.prototype = SignImpl.prototype;
export class VerifyImpl extends Writable {
hash: Hash; hash: Hash;
#digestType: string; #digestType: string;
@ -165,47 +175,65 @@ export class Verify extends Writable {
} }
} }
export function Verify(algorithm: string, options?: WritableOptions) {
return new VerifyImpl(algorithm, options);
}
Verify.prototype = VerifyImpl.prototype;
export function signOneShot( export function signOneShot(
algorithm: string | null | undefined, algorithm: string | null | undefined,
data: ArrayBufferView, data: ArrayBufferView,
key: KeyLike | SignKeyObjectInput | SignPrivateKeyInput, key: KeyLike | SignKeyObjectInput | SignPrivateKeyInput,
): Buffer; callback?: (error: Error | null, data: Buffer) => void,
export function signOneShot(
algorithm: string | null | undefined,
data: ArrayBufferView,
key: KeyLike | SignKeyObjectInput | SignPrivateKeyInput,
callback: (error: Error | null, data: Buffer) => void,
): void;
export function signOneShot(
_algorithm: string | null | undefined,
_data: ArrayBufferView,
_key: KeyLike | SignKeyObjectInput | SignPrivateKeyInput,
_callback?: (error: Error | null, data: Buffer) => void,
): Buffer | void { ): Buffer | void {
notImplemented("crypto.sign"); if (algorithm != null) {
validateString(algorithm, "algorithm");
}
if (callback !== undefined) {
validateFunction(callback, "callback");
}
if (!key) {
throw new ERR_CRYPTO_SIGN_KEY_REQUIRED();
}
const result = Sign(algorithm!).update(data).sign(key);
if (callback) {
setTimeout(() => callback(null, result));
} else {
return result;
}
} }
export function verifyOneShot( export function verifyOneShot(
algorithm: string | null | undefined, algorithm: string | null | undefined,
data: ArrayBufferView, data: BinaryLike,
key: KeyLike | VerifyKeyObjectInput | VerifyPublicKeyInput, key: KeyLike | VerifyKeyObjectInput | VerifyPublicKeyInput,
signature: ArrayBufferView, signature: BinaryLike,
): boolean; callback?: (error: Error | null, result: boolean) => void,
export function verifyOneShot(
algorithm: string | null | undefined,
data: ArrayBufferView,
key: KeyLike | VerifyKeyObjectInput | VerifyPublicKeyInput,
signature: ArrayBufferView,
callback: (error: Error | null, result: boolean) => void,
): void;
export function verifyOneShot(
_algorithm: string | null | undefined,
_data: ArrayBufferView,
_key: KeyLike | VerifyKeyObjectInput | VerifyPublicKeyInput,
_signature: ArrayBufferView,
_callback?: (error: Error | null, result: boolean) => void,
): boolean | void { ): boolean | void {
notImplemented("crypto.verify"); if (algorithm != null) {
validateString(algorithm, "algorithm");
}
if (callback !== undefined) {
validateFunction(callback, "callback");
}
if (!key) {
throw new ERR_CRYPTO_SIGN_KEY_REQUIRED();
}
const result = Verify(algorithm!).update(data).verify(key, signature);
if (callback) {
setTimeout(() => callback(null, result));
} else {
return result;
}
} }
export default { export default {