Skip to content

Implement node:crypto sign and verify APIs #3603

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 1 commit into from
Feb 28, 2025

Conversation

jasnell
Copy link
Collaborator

@jasnell jasnell commented Feb 25, 2025

Implements the node:crypto createSign(...)/createVerify(...)/crypto.sign(...)/crypto.verify(...) APIs. RSA and ed25519 are currently test to work, other key types aren't verified yet. DSA likely does not work, for instance. Will be working on expanding tests next but this ought to be able to land.

Reviewers: some familiarity with the Node.js implementation is likely necessary to review this for correctness.

@jasnell jasnell requested a review from anonrig February 25, 2025 19:07
@jasnell jasnell requested review from a team as code owners February 25, 2025 19:07
@jasnell jasnell requested a review from mar-cf February 25, 2025 19:07
@vicb
Copy link
Contributor

vicb commented Feb 25, 2025

@jasnell it would be great to open docs PR whenever new API are implemented.

I don't see #3463 documented at https://developers.cloudflare.com/workers/runtime-apis/nodejs/crypto/

It's probably even more important if only some algos are tested/supported.

Also what "does not work" mean in:

RSA and ed25519 are currently test to work, other key types aren't verified yet. DSA likely does not work, for instance.

Does it throws or could it return incorrect results? (if the later maybe we should throw for all that is not tested?)

Thanks

@jasnell jasnell force-pushed the jasnell/node-crypto-sign-verify branch from 9c88d77 to 857943e Compare February 25, 2025 19:28
// USE OR OTHER DEALINGS IN THE SOFTWARE.

/* TODO: the following is adopted code, enabling linting one day */
/* eslint-disable */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/* eslint-disable */

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going to keep this until I'm sure it's all working correctly.

return this;
};

function getIntOption(name: string, options: any): number | undefined {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
function getIntOption(name: string, options: any): number | undefined {
function getIntOption(name: string, options: Record<string, unknown>): number | undefined {

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not a Record<string, unknown>. It might be a KeyObject, and CryptoKey, etc.

return undefined;
}

function getDSASignatureEncoding(options: any) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
function getDSASignatureEncoding(options: any) {
function getDSASignatureEncoding(options: unknown): number {

return 0;
}

function getPrivateKey(options: any): CryptoKey {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
function getPrivateKey(options: any): CryptoKey {
function getPrivateKey(options: unknown): CryptoKey {


Sign.prototype.sign = function (
this: Sign,
options: any,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you replace all any with options please?

Verify.prototype._write = function _write(
chunk: string | ArrayBufferView,
encoding: string | undefined | null,
callback: (err?: any) => void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
callback: (err?: any) => void
callback: (err?: unknown) => void

// Derived from DefinitelyTyped https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/stream.d.ts#L1060

/* TODO: the following is adopted code, enabling linting one day */
/* eslint-disable */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/* eslint-disable */

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going to keep this until I'm sure things are working correctly

@jasnell
Copy link
Collaborator Author

jasnell commented Feb 25, 2025

I don't see #3463 documented at developers.cloudflare.com/workers/runtime-apis/nodejs/crypto

Yep. Haven't gotten to that yet. It hadn't yet been deployed to production until some time last week while I was at TC-39. Opening the PR to add the docs is on my todo list for this week.

Also what "does not work" mean in:

Likely throws because I don't think the key types are supported. It should not return incorrect results. It should error noisily.


import { EventEmitter } from 'node:events';

interface WritableOptions {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to define this here. We can just use types/node

Ref: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/stream.d.ts#L991

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it was needed to make this compile ;-) ... Likely need to rework the streams types definitions separately. For now let's leave this.

@anonrig
Copy link
Member

anonrig commented Feb 27, 2025

@jasnell There are conflicts. Can you resolve them?

@jasnell jasnell force-pushed the jasnell/node-crypto-sign-verify branch 2 times, most recently from 5378117 to 6135f49 Compare February 27, 2025 18:51
Copy link
Member

@anonrig anonrig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than the typescript issues and eslint disables, LGTM

@jasnell jasnell force-pushed the jasnell/node-crypto-sign-verify branch from 6135f49 to 14d2a3e Compare February 27, 2025 23:21
@jasnell
Copy link
Collaborator Author

jasnell commented Feb 27, 2025

@irvinebroque @mikenomitch ... just a heads up, I'm going to start labeling workerd PRs that should be highlighted in the changelog using the changelog label.

@jasnell jasnell merged commit f2045a3 into main Feb 28, 2025
17 of 18 checks passed
@jasnell jasnell deleted the jasnell/node-crypto-sign-verify branch February 28, 2025 00:03
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants