| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4142,23 +4142,32 @@ added: | |||
| 4142 | 4142 | - v13.9.0 | |
| 4143 | 4143 | - v12.17.0 | |
| 4144 | 4144 | changes: | |
| 4145 | + - version: REPLACEME | ||
| 4146 | + pr-url: https://github.com/nodejs/node/pull/62527 | ||
| 4147 | + description: Accept key data in addition to KeyObject instances. | ||
| 4145 | 4148 | - version: v23.11.0 | |
| 4146 | 4149 | pr-url: https://github.com/nodejs/node/pull/57274 | |
| 4147 | 4150 | description: Optional callback argument added. | |
| 4148 | 4151 | --> | |
| 4149 | 4152 | ||
| 4150 | 4153 | * `options` {Object} | |
| 4151 | - * `privateKey` {KeyObject} | ||
| 4152 | - * `publicKey` {KeyObject} | ||
| 4154 | + * `privateKey` {Object|string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject} | ||
| 4155 | + * `publicKey` {Object|string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject} | ||
| 4153 | 4156 | * `callback` {Function} | |
| 4154 | 4157 | * `err` {Error} | |
| 4155 | 4158 | * `secret` {Buffer} | |
| 4156 | 4159 | * Returns: {Buffer} if the `callback` function is not provided. | |
| 4157 | 4160 | ||
| 4158 | 4161 | Computes the Diffie-Hellman shared secret based on a `privateKey` and a `publicKey`. | |
| 4159 | - Both keys must have the same `asymmetricKeyType` and must support either the DH or | ||
| 4162 | + Both keys must represent the same asymmetric key type and must support either the DH or | ||
| 4160 | 4163 | ECDH operation. | |
| 4161 | 4164 | ||
| 4165 | + If `options.privateKey` is not a [`KeyObject`][], this function behaves as if | ||
| 4166 | + `options.privateKey` had been passed to [`crypto.createPrivateKey()`][]. | ||
| 4167 | + | ||
| 4168 | + If `options.publicKey` is not a [`KeyObject`][], this function behaves as if | ||
| 4169 | + `options.publicKey` had been passed to [`crypto.createPublicKey()`][]. | ||
| 4170 | + | ||
| 4162 | 4171 | If the `callback` function is provided this function uses libuv's threadpool. | |
| 4163 | 4172 | ||
| 4164 | 4173 | ### `crypto.encapsulate(key[, callback])` | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,7 +17,6 @@ const { | |||
| 17 | 17 | DiffieHellman: _DiffieHellman, | |
| 18 | 18 | DiffieHellmanGroup: _DiffieHellmanGroup, | |
| 19 | 19 | ECDH: _ECDH, | |
| 20 | - ECDHBitsJob, | ||
| 21 | 20 | ECDHConvertKey: _ECDHConvertKey, | |
| 22 | 21 | kCryptoJobAsync, | |
| 23 | 22 | kCryptoJobSync, | |
@@ -52,9 +51,11 @@ const { | |||
| 52 | 51 | } = require('internal/util'); | |
| 53 | 52 | ||
| 54 | 53 | const { | |
| 55 | - KeyObject, | ||
| 54 | + isKeyObject, | ||
| 56 | 55 | kAlgorithm, | |
| 57 | 56 | kKeyType, | |
| 57 | + preparePrivateKey, | ||
| 58 | + preparePublicOrPrivateKey, | ||
| 58 | 59 | } = require('internal/crypto/keys'); | |
| 59 | 60 | ||
| 60 | 61 | const { | |
@@ -284,31 +285,65 @@ function diffieHellman(options, callback) { | |||
| 284 | 285 | validateFunction(callback, 'callback'); | |
| 285 | 286 | ||
| 286 | 287 | const { privateKey, publicKey } = options; | |
| 287 | - if (!(privateKey instanceof KeyObject)) | ||
| 288 | + | ||
| 289 | + // TODO(@panva): remove these non-semver-major error code preserving measures | ||
| 290 | + // in a semver-major followup, the final state is just preparePublicOrPrivateKey | ||
| 291 | + // and preparePrivateKey | ||
| 292 | + if (privateKey == null) | ||
| 288 | 293 | throw new ERR_INVALID_ARG_VALUE('options.privateKey', privateKey); | |
| 289 | 294 | ||
| 290 | - if (!(publicKey instanceof KeyObject)) | ||
| 295 | + if (publicKey == null) | ||
| 291 | 296 | throw new ERR_INVALID_ARG_VALUE('options.publicKey', publicKey); | |
| 292 | 297 | ||
| 293 | - if (privateKey.type !== 'private') | ||
| 294 | - throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE(privateKey.type, 'private'); | ||
| 298 | + if (isKeyObject(privateKey)) { | ||
| 299 | + if (privateKey.type !== 'private') | ||
| 300 | + throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE(privateKey.type, 'private'); | ||
| 301 | + } | ||
| 295 | 302 | ||
| 296 | - if (publicKey.type !== 'public' && publicKey.type !== 'private') { | ||
| 297 | - throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE(publicKey.type, | ||
| 298 | - 'private or public'); | ||
| 303 | + if (isKeyObject(publicKey)) { | ||
| 304 | + if (publicKey.type !== 'public' && publicKey.type !== 'private') { | ||
| 305 | + throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE(publicKey.type, | ||
| 306 | + 'private or public'); | ||
| 307 | + } | ||
| 299 | 308 | } | |
| 300 | 309 | ||
| 301 | - const privateType = privateKey.asymmetricKeyType; | ||
| 302 | - const publicType = publicKey.asymmetricKeyType; | ||
| 303 | - if (privateType !== publicType || !dhEnabledKeyTypes.has(privateType)) { | ||
| 304 | - throw new ERR_CRYPTO_INCOMPATIBLE_KEY('key types for Diffie-Hellman', | ||
| 305 | - `${privateType} and ${publicType}`); | ||
| 310 | + if (isKeyObject(privateKey) && isKeyObject(publicKey)) { | ||
| 311 | + const privateType = privateKey.asymmetricKeyType; | ||
| 312 | + const publicType = publicKey.asymmetricKeyType; | ||
| 313 | + if (privateType !== publicType || !dhEnabledKeyTypes.has(privateType)) { | ||
| 314 | + throw new ERR_CRYPTO_INCOMPATIBLE_KEY('key types for Diffie-Hellman', | ||
| 315 | + `${privateType} and ${publicType}`); | ||
| 316 | + } | ||
| 306 | 317 | } | |
| 307 | 318 | ||
| 319 | + const { | ||
| 320 | + data: pubData, | ||
| 321 | + format: pubFormat, | ||
| 322 | + type: pubType, | ||
| 323 | + passphrase: pubPassphrase, | ||
| 324 | + namedCurve: pubNamedCurve, | ||
| 325 | + } = preparePublicOrPrivateKey(publicKey, 'options.publicKey'); | ||
| 326 | + | ||
| 327 | + const { | ||
| 328 | + data: privData, | ||
| 329 | + format: privFormat, | ||
| 330 | + type: privType, | ||
| 331 | + passphrase: privPassphrase, | ||
| 332 | + namedCurve: privNamedCurve, | ||
| 333 | + } = preparePrivateKey(privateKey, 'options.privateKey'); | ||
| 334 | + | ||
| 308 | 335 | const job = new DHBitsJob( | |
| 309 | 336 | callback ? kCryptoJobAsync : kCryptoJobSync, | |
| 310 | - publicKey[kHandle], | ||
| 311 | - privateKey[kHandle]); | ||
| 337 | + pubData, | ||
| 338 | + pubFormat, | ||
| 339 | + pubType, | ||
| 340 | + pubPassphrase, | ||
| 341 | + pubNamedCurve, | ||
| 342 | + privData, | ||
| 343 | + privFormat, | ||
| 344 | + privType, | ||
| 345 | + privPassphrase, | ||
| 346 | + privNamedCurve); | ||
| 312 | 347 | ||
| 313 | 348 | if (!callback) { | |
| 314 | 349 | const { 0: err, 1: secret } = job.run(); | |
@@ -349,10 +384,18 @@ async function ecdhDeriveBits(algorithm, baseKey, length) { | |||
| 349 | 384 | throw lazyDOMException('Named curve mismatch', 'InvalidAccessError'); | |
| 350 | 385 | } | |
| 351 | 386 | ||
| 352 | - const bits = await jobPromise(() => new ECDHBitsJob( | ||
| 387 | + const bits = await jobPromise(() => new DHBitsJob( | ||
| 353 | 388 | kCryptoJobAsync, | |
| 354 | 389 | key[kKeyObject][kHandle], | |
| 355 | - baseKey[kKeyObject][kHandle])); | ||
| 390 | + undefined, | ||
| 391 | + undefined, | ||
| 392 | + undefined, | ||
| 393 | + undefined, | ||
| 394 | + baseKey[kKeyObject][kHandle], | ||
| 395 | + undefined, | ||
| 396 | + undefined, | ||
| 397 | + undefined, | ||
| 398 | + undefined)); | ||
| 356 | 399 | ||
| 357 | 400 | // If a length is not specified, return the full derived secret | |
| 358 | 401 | if (length === null) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -628,7 +628,7 @@ function getKeyTypes(allowKeyObject, bufferOnly = false) { | |||
| 628 | 628 | } | |
| 629 | 629 | ||
| 630 | 630 | ||
| 631 | - function prepareAsymmetricKey(key, ctx) { | ||
| 631 | + function prepareAsymmetricKey(key, ctx, name = 'key') { | ||
| 632 | 632 | if (isKeyObject(key)) { | |
| 633 | 633 | // Best case: A key object, as simple as that. | |
| 634 | 634 | return { data: getKeyObjectHandle(key, ctx) }; | |
@@ -639,7 +639,7 @@ function prepareAsymmetricKey(key, ctx) { | |||
| 639 | 639 | } | |
| 640 | 640 | if (isStringOrBuffer(key)) { | |
| 641 | 641 | // Expect PEM by default, mostly for backward compatibility. | |
| 642 | - return { format: kKeyFormatPEM, data: getArrayBufferOrView(key, 'key') }; | ||
| 642 | + return { format: kKeyFormatPEM, data: getArrayBufferOrView(key, name) }; | ||
| 643 | 643 | } | |
| 644 | 644 | if (typeof key === 'object') { | |
| 645 | 645 | const { key: data, encoding, format } = key; | |
@@ -654,23 +654,23 @@ function prepareAsymmetricKey(key, ctx) { | |||
| 654 | 654 | return { data: getKeyObjectHandle(data[kKeyObject], ctx) }; | |
| 655 | 655 | } | |
| 656 | 656 | if (format === 'jwk') { | |
| 657 | - validateObject(data, 'key.key'); | ||
| 657 | + validateObject(data, `${name}.key`); | ||
| 658 | 658 | return { data, format: kKeyFormatJWK }; | |
| 659 | 659 | } else if (format === 'raw-public' || format === 'raw-private' || | |
| 660 | 660 | format === 'raw-seed') { | |
| 661 | 661 | if (!isStringOrBuffer(data)) { | |
| 662 | 662 | throw new ERR_INVALID_ARG_TYPE( | |
| 663 | - 'key.key', | ||
| 663 | + `${name}.key`, | ||
| 664 | 664 | ['ArrayBuffer', 'Buffer', 'TypedArray', 'DataView'], | |
| 665 | 665 | data); | |
| 666 | 666 | } | |
| 667 | - validateString(key.asymmetricKeyType, 'key.asymmetricKeyType'); | ||
| 667 | + validateString(key.asymmetricKeyType, `${name}.asymmetricKeyType`); | ||
| 668 | 668 | if (key.asymmetricKeyType === 'ec') { | |
| 669 | - validateString(key.namedCurve, 'key.namedCurve'); | ||
| 669 | + validateString(key.namedCurve, `${name}.namedCurve`); | ||
| 670 | 670 | } | |
| 671 | 671 | const rawFormat = parseKeyFormat(format, undefined, 'options.format'); | |
| 672 | 672 | return { | |
| 673 | - data: getArrayBufferOrView(data, 'key.key'), | ||
| 673 | + data: getArrayBufferOrView(data, `${name}.key`), | ||
| 674 | 674 | format: rawFormat, | |
| 675 | 675 | type: key.asymmetricKeyType, | |
| 676 | 676 | namedCurve: key.namedCurve ?? null, | |
@@ -680,31 +680,31 @@ function prepareAsymmetricKey(key, ctx) { | |||
| 680 | 680 | // Either PEM or DER using PKCS#1 or SPKI. | |
| 681 | 681 | if (!isStringOrBuffer(data)) { | |
| 682 | 682 | throw new ERR_INVALID_ARG_TYPE( | |
| 683 | - 'key.key', | ||
| 683 | + `${name}.key`, | ||
| 684 | 684 | getKeyTypes(ctx !== kCreatePrivate), | |
| 685 | 685 | data); | |
| 686 | 686 | } | |
| 687 | 687 | ||
| 688 | 688 | const isPublic = | |
| 689 | 689 | (ctx === kConsumePrivate || ctx === kCreatePrivate) ? false : undefined; | |
| 690 | 690 | return { | |
| 691 | - data: getArrayBufferOrView(data, 'key', encoding), | ||
| 691 | + data: getArrayBufferOrView(data, `${name}.key`, encoding), | ||
| 692 | 692 | ...parseKeyEncoding(key, undefined, isPublic), | |
| 693 | 693 | }; | |
| 694 | 694 | } | |
| 695 | 695 | ||
| 696 | 696 | throw new ERR_INVALID_ARG_TYPE( | |
| 697 | - 'key', | ||
| 697 | + name, | ||
| 698 | 698 | getKeyTypes(ctx !== kCreatePrivate), | |
| 699 | 699 | key); | |
| 700 | 700 | } | |
| 701 | 701 | ||
| 702 | - function preparePrivateKey(key) { | ||
| 703 | - return prepareAsymmetricKey(key, kConsumePrivate); | ||
| 702 | + function preparePrivateKey(key, name) { | ||
| 703 | + return prepareAsymmetricKey(key, kConsumePrivate, name); | ||
| 704 | 704 | } | |
| 705 | 705 | ||
| 706 | - function preparePublicOrPrivateKey(key) { | ||
| 707 | - return prepareAsymmetricKey(key, kConsumePublic); | ||
| 706 | + function preparePublicOrPrivateKey(key, name) { | ||
| 707 | + return prepareAsymmetricKey(key, kConsumePublic, name); | ||
| 708 | 708 | } | |
| 709 | 709 | ||
| 710 | 710 | function prepareSecretKey(key, encoding, bufferOnly = false) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -135,7 +135,7 @@ Sign.prototype.sign = function sign(options, encoding) { | |||
| 135 | 135 | throw new ERR_CRYPTO_SIGN_KEY_REQUIRED(); | |
| 136 | 136 | ||
| 137 | 137 | const { data, format, type, passphrase, namedCurve } = | |
| 138 | - preparePrivateKey(options, true); | ||
| 138 | + preparePrivateKey(options); | ||
| 139 | 139 | ||
| 140 | 140 | // Options specific to RSA | |
| 141 | 141 | const rsaPadding = getPadding(options); | |
@@ -239,7 +239,7 @@ Verify.prototype.verify = function verify(options, signature, sigEncoding) { | |||
| 239 | 239 | type, | |
| 240 | 240 | passphrase, | |
| 241 | 241 | namedCurve, | |
| 242 | - } = preparePublicOrPrivateKey(options, true); | ||
| 242 | + } = preparePublicOrPrivateKey(options); | ||
| 243 | 243 | ||
| 244 | 244 | // Options specific to RSA | |
| 245 | 245 | const rsaPadding = getPadding(options); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -477,20 +477,16 @@ Maybe<void> DHBitsTraits::AdditionalConfig( | |||
| 477 | 477 | const FunctionCallbackInfo<Value>& args, | |
| 478 | 478 | unsigned int offset, | |
| 479 | 479 | DHBitsConfig* params) { | |
| 480 | - CHECK(args[offset]->IsObject()); // public key | ||
| 481 | - CHECK(args[offset + 1]->IsObject()); // private key | ||
| 480 | + auto public_key = KeyObjectData::GetPublicOrPrivateKeyFromJs(args, &offset); | ||
| 481 | + if (!public_key) [[unlikely]] | ||
| 482 | + return Nothing<void>(); | ||
| 482 | 483 | ||
| 483 | - KeyObjectHandle* private_key; | ||
| 484 | - KeyObjectHandle* public_key; | ||
| 484 | + auto private_key = KeyObjectData::GetPrivateKeyFromJs(args, &offset, true); | ||
| 485 | + if (!private_key) [[unlikely]] | ||
| 486 | + return Nothing<void>(); | ||
| 485 | 487 | ||
| 486 | - ASSIGN_OR_RETURN_UNWRAP(&public_key, args[offset], Nothing<void>()); | ||
| 487 | - ASSIGN_OR_RETURN_UNWRAP(&private_key, args[offset + 1], Nothing<void>()); | ||
| 488 | - | ||
| 489 | - CHECK(private_key->Data().GetKeyType() == kKeyTypePrivate); | ||
| 490 | - CHECK(public_key->Data().GetKeyType() != kKeyTypeSecret); | ||
| 491 | - | ||
| 492 | - params->public_key = public_key->Data().addRef(); | ||
| 493 | - params->private_key = private_key->Data().addRef(); | ||
| 488 | + params->public_key = std::move(public_key); | ||
| 489 | + params->private_key = std::move(private_key); | ||
| 494 | 490 | ||
| 495 | 491 | return JustVoid(); | |
| 496 | 492 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments