Skip to content

Commit

Permalink
crypto: allow zero-length secret KeyObject
Browse files Browse the repository at this point in the history
PR-URL: #44201
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Backport-PR-URL: #44872
  • Loading branch information
panva authored and juanarbol committed Oct 11, 2022
1 parent 7e705d8 commit e5c9975
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 16 deletions.
3 changes: 3 additions & 0 deletions doc/api/crypto.md
Original file line number Diff line number Diff line change
Expand Up @@ -3530,6 +3530,9 @@ and it will be impossible to extract the private key from the returned object.
<!-- YAML
added: v11.6.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/44201
description: The key can now be zero-length.
- version: v15.0.0
pr-url: https://github.com/nodejs/node/pull/35093
description: The key can also be an ArrayBuffer or string. The encoding
Expand Down
3 changes: 0 additions & 3 deletions lib/internal/crypto/keys.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ const {
ERR_ILLEGAL_CONSTRUCTOR,
ERR_INVALID_ARG_TYPE,
ERR_INVALID_ARG_VALUE,
ERR_OUT_OF_RANGE,
}
} = require('internal/errors');

Expand Down Expand Up @@ -592,8 +591,6 @@ function prepareSecretKey(key, encoding, bufferOnly = false) {

function createSecretKey(key, encoding) {
key = prepareSecretKey(key, encoding, true);
if (key.byteLength === 0)
throw new ERR_OUT_OF_RANGE('key.byteLength', '> 0', key.byteLength);
const handle = new KeyObjectHandle();
handle.init(kKeyTypeSecret, key);
return new SecretKeyObject(handle);
Expand Down
1 change: 0 additions & 1 deletion src/crypto/crypto_keys.cc
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,6 @@ void KeyObjectData::MemoryInfo(MemoryTracker* tracker) const {
}

std::shared_ptr<KeyObjectData> KeyObjectData::CreateSecret(ByteSource key) {
CHECK(key);
return std::shared_ptr<KeyObjectData>(new KeyObjectData(std::move(key)));
}

Expand Down
9 changes: 9 additions & 0 deletions test/parallel/test-crypto-hmac.js
Original file line number Diff line number Diff line change
Expand Up @@ -450,3 +450,12 @@ assert.strictEqual(
() => crypto.createHmac('sha7', 'key'),
/Invalid digest/);
}

{
const buf = Buffer.alloc(0);
const keyObject = crypto.createSecretKey(Buffer.alloc(0));
assert.deepStrictEqual(
crypto.createHmac('sha256', buf).update('foo').digest(),
crypto.createHmac('sha256', keyObject).update('foo').digest(),
);
}
22 changes: 10 additions & 12 deletions test/parallel/test-crypto-key-objects.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,6 @@ const publicDsa = fixtures.readKey('dsa_public_1025.pem', 'ascii');
const privateDsa = fixtures.readKey('dsa_private_encrypted_1025.pem',
'ascii');

{
// Attempting to create an empty key should throw.
assert.throws(() => {
createSecretKey(Buffer.alloc(0));
}, {
name: 'RangeError',
code: 'ERR_OUT_OF_RANGE',
message: 'The value of "key.byteLength" is out of range. ' +
'It must be > 0. Received 0'
});
}

{
// Attempting to create a key of a wrong type should throw
const TYPE = 'wrong_type';
Expand Down Expand Up @@ -871,6 +859,16 @@ const privateDsa = fixtures.readKey('dsa_private_encrypted_1025.pem',
assert(!first.privateKey.equals(second.publicKey));
}

{
const first = createSecretKey(Buffer.alloc(0));
const second = createSecretKey(new ArrayBuffer(0));
const third = createSecretKey(Buffer.alloc(1));
assert(first.equals(first));
assert(first.equals(second));
assert(!first.equals(third));
assert(!third.equals(first));
}

{
// This should not cause a crash: https://github.com/nodejs/node/issues/44471
for (const key of ['', 'foo', null, undefined, true, Boolean]) {
Expand Down

0 comments on commit e5c9975

Please sign in to comment.