Skip to content

Commit 0db49fe

Browse files
committed
crypto: support Uint8Array prime in createDH
PR-URL: #11983 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]>
1 parent c3efe72 commit 0db49fe

File tree

3 files changed

+76
-46
lines changed

3 files changed

+76
-46
lines changed

doc/api/crypto.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -1237,12 +1237,15 @@ The `key` is the raw key used by the `algorithm` and `iv` is an
12371237
<!-- YAML
12381238
added: v0.11.12
12391239
changes:
1240+
- version: REPLACEME
1241+
pr-url: https://github.com/nodejs/node/pull/11983
1242+
description: The `prime` argument can be a `Uint8Array` now.
12401243
- version: v6.0.0
12411244
pr-url: https://github.com/nodejs/node/pull/5522
12421245
description: The default for the encoding parameters changed
12431246
from `binary` to `utf8`.
12441247
-->
1245-
- `prime` {string | Buffer}
1248+
- `prime` {string | Buffer | Uint8Array}
12461249
- `prime_encoding` {string}
12471250
- `generator` {number | string | Buffer | Uint8Array} Defaults to `2`.
12481251
- `generator_encoding` {string}
@@ -1257,7 +1260,7 @@ The `prime_encoding` and `generator_encoding` arguments can be `'latin1'`,
12571260
`'hex'`, or `'base64'`.
12581261

12591262
If `prime_encoding` is specified, `prime` is expected to be a string; otherwise
1260-
a [`Buffer`][] is expected.
1263+
a [`Buffer`][] or `Uint8Array` is expected.
12611264

12621265
If `generator_encoding` is specified, `generator` is expected to be a string;
12631266
otherwise either a number or [`Buffer`][] or `Uint8Array` is expected.

lib/crypto.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const timingSafeEqual = binding.timingSafeEqual;
4242
const Buffer = require('buffer').Buffer;
4343
const stream = require('stream');
4444
const util = require('util');
45+
const { isUint8Array } = process.binding('util');
4546
const LazyTransform = require('internal/streams/lazy_transform');
4647

4748
const DH_GENERATOR = 2;
@@ -368,10 +369,12 @@ function DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding) {
368369
if (!(this instanceof DiffieHellman))
369370
return new DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding);
370371

371-
if (!(sizeOrKey instanceof Buffer) &&
372-
typeof sizeOrKey !== 'number' &&
373-
typeof sizeOrKey !== 'string')
374-
throw new TypeError('First argument should be number, string or Buffer');
372+
if (typeof sizeOrKey !== 'number' &&
373+
typeof sizeOrKey !== 'string' &&
374+
!isUint8Array(sizeOrKey)) {
375+
throw new TypeError('First argument should be number, string, ' +
376+
'Uint8Array or Buffer');
377+
}
375378

376379
if (keyEncoding) {
377380
if (typeof keyEncoding !== 'string' ||

test/parallel/test-crypto-dh.js

+64-40
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ assert.strictEqual(dh1.verifyError, 0);
2424
assert.strictEqual(dh2.verifyError, 0);
2525

2626
const argumentsError =
27-
/^TypeError: First argument should be number, string or Buffer$/;
27+
/^TypeError: First argument should be number, string, Uint8Array or Buffer$/;
2828

2929
assert.throws(() => {
3030
crypto.createDiffieHellman([0x1, 0x2]);
@@ -112,45 +112,69 @@ const modp2buf = Buffer.from([
112112
0x1f, 0xe6, 0x49, 0x28, 0x66, 0x51, 0xec, 0xe6, 0x53, 0x81,
113113
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
114114
]);
115-
const exmodp2 = crypto.createDiffieHellman(modp2buf, Buffer.from([2]));
116-
modp2.generateKeys();
117-
exmodp2.generateKeys();
118-
let modp2Secret = modp2.computeSecret(exmodp2.getPublicKey()).toString('hex');
119-
const exmodp2Secret = exmodp2.computeSecret(modp2.getPublicKey())
120-
.toString('hex');
121-
assert.strictEqual(modp2Secret, exmodp2Secret);
122-
assert.strictEqual(modp2.verifyError, DH_NOT_SUITABLE_GENERATOR);
123-
assert.strictEqual(exmodp2.verifyError, DH_NOT_SUITABLE_GENERATOR);
124-
125-
126-
// Ensure specific generator (string with encoding) works as expected.
127-
const exmodp2_2 = crypto.createDiffieHellman(modp2buf, '02', 'hex');
128-
exmodp2_2.generateKeys();
129-
modp2Secret = modp2.computeSecret(exmodp2_2.getPublicKey()).toString('hex');
130-
const exmodp2_2Secret = exmodp2_2.computeSecret(modp2.getPublicKey())
131-
.toString('hex');
132-
assert.strictEqual(modp2Secret, exmodp2_2Secret);
133-
assert.strictEqual(exmodp2_2.verifyError, DH_NOT_SUITABLE_GENERATOR);
134-
135-
136-
// Ensure specific generator (string without encoding) works as expected.
137-
const exmodp2_3 = crypto.createDiffieHellman(modp2buf, '\x02');
138-
exmodp2_3.generateKeys();
139-
modp2Secret = modp2.computeSecret(exmodp2_3.getPublicKey()).toString('hex');
140-
const exmodp2_3Secret = exmodp2_3.computeSecret(modp2.getPublicKey())
141-
.toString('hex');
142-
assert.strictEqual(modp2Secret, exmodp2_3Secret);
143-
assert.strictEqual(exmodp2_3.verifyError, DH_NOT_SUITABLE_GENERATOR);
144-
145-
146-
// Ensure specific generator (numeric) works as expected.
147-
const exmodp2_4 = crypto.createDiffieHellman(modp2buf, 2);
148-
exmodp2_4.generateKeys();
149-
modp2Secret = modp2.computeSecret(exmodp2_4.getPublicKey()).toString('hex');
150-
const exmodp2_4Secret = exmodp2_4.computeSecret(modp2.getPublicKey())
151-
.toString('hex');
152-
assert.strictEqual(modp2Secret, exmodp2_4Secret);
153-
assert.strictEqual(exmodp2_4.verifyError, DH_NOT_SUITABLE_GENERATOR);
115+
116+
{
117+
const exmodp2 = crypto.createDiffieHellman(modp2buf, Buffer.from([2]));
118+
modp2.generateKeys();
119+
exmodp2.generateKeys();
120+
const modp2Secret = modp2.computeSecret(exmodp2.getPublicKey())
121+
.toString('hex');
122+
const exmodp2Secret = exmodp2.computeSecret(modp2.getPublicKey())
123+
.toString('hex');
124+
assert.strictEqual(modp2Secret, exmodp2Secret);
125+
assert.strictEqual(modp2.verifyError, DH_NOT_SUITABLE_GENERATOR);
126+
assert.strictEqual(exmodp2.verifyError, DH_NOT_SUITABLE_GENERATOR);
127+
}
128+
129+
{
130+
// Ensure specific generator (string with encoding) works as expected.
131+
const exmodp2 = crypto.createDiffieHellman(modp2buf, '02', 'hex');
132+
exmodp2.generateKeys();
133+
const modp2Secret = modp2.computeSecret(exmodp2.getPublicKey())
134+
.toString('hex');
135+
const exmodp2Secret = exmodp2.computeSecret(modp2.getPublicKey())
136+
.toString('hex');
137+
assert.strictEqual(modp2Secret, exmodp2Secret);
138+
assert.strictEqual(exmodp2.verifyError, DH_NOT_SUITABLE_GENERATOR);
139+
}
140+
141+
{
142+
// Ensure specific generator (string with encoding) works as expected,
143+
// with a Uint8Array as the first argument to createDiffieHellman().
144+
const exmodp2 = crypto.createDiffieHellman(new Uint8Array(modp2buf),
145+
'02', 'hex');
146+
exmodp2.generateKeys();
147+
const modp2Secret = modp2.computeSecret(exmodp2.getPublicKey())
148+
.toString('hex');
149+
const exmodp2Secret = exmodp2.computeSecret(modp2.getPublicKey())
150+
.toString('hex');
151+
assert.strictEqual(modp2Secret, exmodp2Secret);
152+
assert.strictEqual(exmodp2.verifyError, DH_NOT_SUITABLE_GENERATOR);
153+
}
154+
155+
{
156+
// Ensure specific generator (string without encoding) works as expected.
157+
const exmodp2 = crypto.createDiffieHellman(modp2buf, '\x02');
158+
exmodp2.generateKeys();
159+
const modp2Secret = modp2.computeSecret(exmodp2.getPublicKey())
160+
.toString('hex');
161+
const exmodp2Secret = exmodp2.computeSecret(modp2.getPublicKey())
162+
.toString('hex');
163+
assert.strictEqual(modp2Secret, exmodp2Secret);
164+
assert.strictEqual(exmodp2.verifyError, DH_NOT_SUITABLE_GENERATOR);
165+
}
166+
167+
{
168+
// Ensure specific generator (numeric) works as expected.
169+
const exmodp2 = crypto.createDiffieHellman(modp2buf, 2);
170+
exmodp2.generateKeys();
171+
const modp2Secret = modp2.computeSecret(exmodp2.getPublicKey())
172+
.toString('hex');
173+
const exmodp2Secret = exmodp2.computeSecret(modp2.getPublicKey())
174+
.toString('hex');
175+
assert.strictEqual(modp2Secret, exmodp2Secret);
176+
assert.strictEqual(exmodp2.verifyError, DH_NOT_SUITABLE_GENERATOR);
177+
}
154178

155179

156180
const p = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' +

0 commit comments

Comments
 (0)