Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 053cef7

Browse filesBrowse files
panvaaduh95
authored andcommitted
crypto: add optional callback to crypto.diffieHellman
PR-URL: #57274 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
1 parent 2a5fcb2 commit 053cef7
Copy full SHA for 053cef7

File tree

Expand file treeCollapse file tree

5 files changed

+337
-59
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

5 files changed

+337
-59
lines changed
Open diff view settings
Collapse file

‎doc/api/crypto.md‎

Copy file name to clipboardExpand all lines: doc/api/crypto.md
+11-2Lines changed: 11 additions & 2 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -3527,23 +3527,32 @@ the corresponding digest algorithm. This does not work for all signature
35273527
algorithms, such as `'ecdsa-with-SHA256'`, so it is best to always use digest
35283528
algorithm names.
35293529

3530-
### `crypto.diffieHellman(options)`
3530+
### `crypto.diffieHellman(options[, callback])`
35313531

35323532
<!-- YAML
35333533
added:
35343534
- v13.9.0
35353535
- v12.17.0
3536+
changes:
3537+
- version: REPLACEME
3538+
pr-url: https://github.com/nodejs/node/pull/57274
3539+
description: Optional callback argument added.
35363540
-->
35373541

35383542
* `options`: {Object}
35393543
* `privateKey`: {KeyObject}
35403544
* `publicKey`: {KeyObject}
3541-
* Returns: {Buffer}
3545+
* `callback` {Function}
3546+
* `err` {Error}
3547+
* `secret` {Buffer}
3548+
* Returns: {Buffer} if the `callback` function is not provided.
35423549

35433550
Computes the Diffie-Hellman secret based on a `privateKey` and a `publicKey`.
35443551
Both keys must have the same `asymmetricKeyType`, which must be one of `'dh'`
35453552
(for Diffie-Hellman), `'ec'`, `'x448'`, or `'x25519'` (for ECDH).
35463553

3554+
If the `callback` function is provided this function uses libuv's threadpool.
3555+
35473556
### `crypto.fips`
35483557

35493558
<!-- YAML
Collapse file

‎lib/internal/crypto/diffiehellman.js‎

Copy file name to clipboardExpand all lines: lib/internal/crypto/diffiehellman.js
+26-3Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
const {
44
ArrayBufferPrototypeSlice,
5+
FunctionPrototypeCall,
56
MathCeil,
67
ObjectDefineProperty,
78
SafeSet,
@@ -11,13 +12,14 @@ const {
1112
const { Buffer } = require('buffer');
1213

1314
const {
15+
DHBitsJob,
1416
DiffieHellman: _DiffieHellman,
1517
DiffieHellmanGroup: _DiffieHellmanGroup,
1618
ECDH: _ECDH,
1719
ECDHBitsJob,
1820
ECDHConvertKey: _ECDHConvertKey,
19-
statelessDH,
2021
kCryptoJobAsync,
22+
kCryptoJobSync,
2123
} = internalBinding('crypto');
2224

2325
const {
@@ -32,6 +34,7 @@ const {
3234
} = require('internal/errors');
3335

3436
const {
37+
validateFunction,
3538
validateInt32,
3639
validateObject,
3740
validateString,
@@ -268,9 +271,12 @@ function getFormat(format) {
268271

269272
const dhEnabledKeyTypes = new SafeSet(['dh', 'ec', 'x448', 'x25519']);
270273

271-
function diffieHellman(options) {
274+
function diffieHellman(options, callback) {
272275
validateObject(options, 'options');
273276

277+
if (callback !== undefined)
278+
validateFunction(callback, 'callback');
279+
274280
const { privateKey, publicKey } = options;
275281
if (!(privateKey instanceof KeyObject))
276282
throw new ERR_INVALID_ARG_VALUE('options.privateKey', privateKey);
@@ -293,7 +299,24 @@ function diffieHellman(options) {
293299
`${privateType} and ${publicType}`);
294300
}
295301

296-
return statelessDH(privateKey[kHandle], publicKey[kHandle]);
302+
const job = new DHBitsJob(
303+
callback ? kCryptoJobAsync : kCryptoJobSync,
304+
publicKey[kHandle],
305+
privateKey[kHandle]);
306+
307+
if (!callback) {
308+
const { 0: err, 1: secret } = job.run();
309+
if (err !== undefined)
310+
throw err;
311+
312+
return Buffer.from(secret);
313+
}
314+
315+
job.ondone = (error, secret) => {
316+
if (error) return FunctionPrototypeCall(callback, job, error);
317+
FunctionPrototypeCall(callback, job, null, Buffer.from(secret));
318+
};
319+
job.run();
297320
}
298321

299322
let masks;
Collapse file

‎src/crypto/crypto_dh.cc‎

Copy file name to clipboardExpand all lines: src/crypto/crypto_dh.cc
+16-47Lines changed: 16 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -483,49 +483,11 @@ WebCryptoKeyExportStatus DHKeyExportTraits::DoExport(
483483
}
484484
}
485485

486-
namespace {
487-
ByteSource StatelessDiffieHellmanThreadsafe(const EVPKeyPointer& our_key,
488-
const EVPKeyPointer& their_key) {
489-
auto dp = DHPointer::stateless(our_key, their_key);
490-
if (!dp) return {};
491-
DCHECK(!dp.isSecure());
492-
493-
return ByteSource::Allocated(dp.release());
494-
}
495-
496-
void Stateless(const FunctionCallbackInfo<Value>& args) {
497-
Environment* env = Environment::GetCurrent(args);
498-
499-
CHECK(args[0]->IsObject() && args[1]->IsObject());
500-
KeyObjectHandle* our_key_object;
501-
ASSIGN_OR_RETURN_UNWRAP(&our_key_object, args[0].As<Object>());
502-
CHECK_EQ(our_key_object->Data().GetKeyType(), kKeyTypePrivate);
503-
KeyObjectHandle* their_key_object;
504-
ASSIGN_OR_RETURN_UNWRAP(&their_key_object, args[1].As<Object>());
505-
CHECK_NE(their_key_object->Data().GetKeyType(), kKeyTypeSecret);
506-
507-
const auto& our_key = our_key_object->Data().GetAsymmetricKey();
508-
const auto& their_key = their_key_object->Data().GetAsymmetricKey();
509-
510-
Local<Value> out;
511-
if (!StatelessDiffieHellmanThreadsafe(our_key, their_key)
512-
.ToBuffer(env)
513-
.ToLocal(&out)) return;
514-
515-
if (Buffer::Length(out) == 0)
516-
return ThrowCryptoError(env, ERR_get_error(), "diffieHellman failed");
517-
518-
args.GetReturnValue().Set(out);
519-
}
520-
} // namespace
521-
522486
Maybe<void> DHBitsTraits::AdditionalConfig(
523487
CryptoJobMode mode,
524488
const FunctionCallbackInfo<Value>& args,
525489
unsigned int offset,
526490
DHBitsConfig* params) {
527-
Environment* env = Environment::GetCurrent(args);
528-
529491
CHECK(args[offset]->IsObject()); // public key
530492
CHECK(args[offset + 1]->IsObject()); // private key
531493

@@ -535,11 +497,8 @@ Maybe<void> DHBitsTraits::AdditionalConfig(
535497
ASSIGN_OR_RETURN_UNWRAP(&public_key, args[offset], Nothing<void>());
536498
ASSIGN_OR_RETURN_UNWRAP(&private_key, args[offset + 1], Nothing<void>());
537499

538-
if (private_key->Data().GetKeyType() != kKeyTypePrivate ||
539-
public_key->Data().GetKeyType() != kKeyTypePublic) {
540-
THROW_ERR_CRYPTO_INVALID_KEYTYPE(env);
541-
return Nothing<void>();
542-
}
500+
CHECK(private_key->Data().GetKeyType() == kKeyTypePrivate);
501+
CHECK(public_key->Data().GetKeyType() != kKeyTypeSecret);
543502

544503
params->public_key = public_key->Data().addRef();
545504
params->private_key = private_key->Data().addRef();
@@ -557,8 +516,20 @@ bool DHBitsTraits::DeriveBits(
557516
Environment* env,
558517
const DHBitsConfig& params,
559518
ByteSource* out) {
560-
*out = StatelessDiffieHellmanThreadsafe(params.private_key.GetAsymmetricKey(),
561-
params.public_key.GetAsymmetricKey());
519+
auto dp = DHPointer::stateless(params.private_key.GetAsymmetricKey(),
520+
params.public_key.GetAsymmetricKey());
521+
if (!dp) {
522+
bool can_throw =
523+
per_process::v8_initialized && Isolate::TryGetCurrent() != nullptr;
524+
if (can_throw) {
525+
unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
526+
if (err) ThrowCryptoError(env, err, "diffieHellman failed");
527+
}
528+
return false;
529+
}
530+
531+
*out = ByteSource::Allocated(dp.release());
532+
CHECK(!out->empty());
562533
return true;
563534
}
564535

@@ -611,7 +582,6 @@ void DiffieHellman::Initialize(Environment* env, Local<Object> target) {
611582
make(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellmanGroup"),
612583
DiffieHellmanGroup);
613584

614-
SetMethodNoSideEffect(context, target, "statelessDH", Stateless);
615585
DHKeyPairGenJob::Initialize(env, target);
616586
DHKeyExportJob::Initialize(env, target);
617587
DHBitsJob::Initialize(env, target);
@@ -632,7 +602,6 @@ void DiffieHellman::RegisterExternalReferences(
632602
registry->Register(SetPrivateKey);
633603

634604
registry->Register(Check);
635-
registry->Register(Stateless);
636605

637606
DHKeyPairGenJob::RegisterExternalReferences(registry);
638607
DHKeyExportJob::RegisterExternalReferences(registry);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.