mirror of
https://github.com/nodejs/node.git
synced 2025-05-07 19:56:48 +00:00

Failed ConvertKey() operations should not leave errors on OpenSSL's error stack because that's observable by subsequent cryptographic operations. More to the point, it makes said operations fail with an unrelated error. PR-URL: https://github.com/nodejs/node/pull/26153 Fixes: https://github.com/nodejs/node/issues/26133 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
126 lines
4.4 KiB
JavaScript
126 lines
4.4 KiB
JavaScript
'use strict';
|
|
const common = require('../common');
|
|
if (!common.hasCrypto)
|
|
common.skip('missing crypto');
|
|
|
|
const assert = require('assert');
|
|
|
|
const { ECDH, createSign, getCurves } = require('crypto');
|
|
|
|
// A valid private key for the secp256k1 curve.
|
|
const cafebabeKey = 'cafebabe'.repeat(8);
|
|
// Associated compressed and uncompressed public keys (points).
|
|
const cafebabePubPtComp =
|
|
'03672a31bfc59d3f04548ec9b7daeeba2f61814e8ccc40448045007f5479f693a3';
|
|
const cafebabePubPtUnComp =
|
|
'04672a31bfc59d3f04548ec9b7daeeba2f61814e8ccc40448045007f5479f693a3' +
|
|
'2e02c7f93d13dc2732b760ca377a5897b9dd41a1c1b29dc0442fdce6d0a04d1d';
|
|
|
|
// Invalid test: key argument is undefined.
|
|
common.expectsError(
|
|
() => ECDH.convertKey(),
|
|
{
|
|
code: 'ERR_INVALID_ARG_TYPE',
|
|
type: TypeError,
|
|
});
|
|
|
|
// Invalid test: curve argument is undefined.
|
|
common.expectsError(
|
|
() => ECDH.convertKey(cafebabePubPtComp),
|
|
{
|
|
code: 'ERR_INVALID_ARG_TYPE',
|
|
type: TypeError,
|
|
});
|
|
|
|
// Invalid test: curve argument is invalid.
|
|
common.expectsError(
|
|
() => ECDH.convertKey(cafebabePubPtComp, 'badcurve'),
|
|
{
|
|
type: TypeError,
|
|
message: 'Invalid ECDH curve name'
|
|
});
|
|
|
|
if (getCurves().includes('secp256k1')) {
|
|
// Invalid test: format argument is undefined.
|
|
common.expectsError(
|
|
() => ECDH.convertKey(cafebabePubPtComp, 'secp256k1', 'hex', 'hex', 10),
|
|
{
|
|
code: 'ERR_CRYPTO_ECDH_INVALID_FORMAT',
|
|
type: TypeError,
|
|
message: 'Invalid ECDH format: 10'
|
|
});
|
|
|
|
// Point formats.
|
|
let uncompressed = ECDH.convertKey(cafebabePubPtComp,
|
|
'secp256k1',
|
|
'hex',
|
|
'buffer',
|
|
'uncompressed');
|
|
let compressed = ECDH.convertKey(cafebabePubPtComp,
|
|
'secp256k1',
|
|
'hex',
|
|
'buffer',
|
|
'compressed');
|
|
let hybrid = ECDH.convertKey(cafebabePubPtComp,
|
|
'secp256k1',
|
|
'hex',
|
|
'buffer',
|
|
'hybrid');
|
|
assert.strictEqual(uncompressed[0], 4);
|
|
let firstByte = compressed[0];
|
|
assert(firstByte === 2 || firstByte === 3);
|
|
firstByte = hybrid[0];
|
|
assert(firstByte === 6 || firstByte === 7);
|
|
|
|
// Format conversion from hex to hex
|
|
uncompressed = ECDH.convertKey(cafebabePubPtComp,
|
|
'secp256k1',
|
|
'hex',
|
|
'hex',
|
|
'uncompressed');
|
|
compressed = ECDH.convertKey(cafebabePubPtComp,
|
|
'secp256k1',
|
|
'hex',
|
|
'hex',
|
|
'compressed');
|
|
hybrid = ECDH.convertKey(cafebabePubPtComp,
|
|
'secp256k1',
|
|
'hex',
|
|
'hex',
|
|
'hybrid');
|
|
assert.strictEqual(uncompressed, cafebabePubPtUnComp);
|
|
assert.strictEqual(compressed, cafebabePubPtComp);
|
|
|
|
// Compare to getPublicKey.
|
|
const ecdh1 = ECDH('secp256k1');
|
|
ecdh1.generateKeys();
|
|
ecdh1.setPrivateKey(cafebabeKey, 'hex');
|
|
assert.strictEqual(ecdh1.getPublicKey('hex', 'uncompressed'), uncompressed);
|
|
assert.strictEqual(ecdh1.getPublicKey('hex', 'compressed'), compressed);
|
|
assert.strictEqual(ecdh1.getPublicKey('hex', 'hybrid'), hybrid);
|
|
}
|
|
|
|
// See https://github.com/nodejs/node/issues/26133, failed ConvertKey
|
|
// operations should not leave errors on OpenSSL's error stack because
|
|
// that's observable by subsequent operations.
|
|
{
|
|
const privateKey =
|
|
'-----BEGIN EC PRIVATE KEY-----\n' +
|
|
'MHcCAQEEIF+jnWY1D5kbVYDNvxxo/Y+ku2uJPDwS0r/VuPZQrjjVoAoGCCqGSM49\n' +
|
|
'AwEHoUQDQgAEurOxfSxmqIRYzJVagdZfMMSjRNNhB8i3mXyIMq704m2m52FdfKZ2\n' +
|
|
'pQhByd5eyj3lgZ7m7jbchtdgyOF8Io/1ng==\n' +
|
|
'-----END EC PRIVATE KEY-----';
|
|
|
|
const sign = createSign('sha256').update('plaintext');
|
|
|
|
// TODO(bnoordhuis) This should really bubble up the specific OpenSSL error
|
|
// rather than Node's generic error message.
|
|
const badKey = 'f'.repeat(128);
|
|
assert.throws(
|
|
() => ECDH.convertKey(badKey, 'secp256k1', 'hex', 'hex', 'compressed'),
|
|
/Failed to convert Buffer to EC_POINT/);
|
|
|
|
// Next statement should not throw an exception.
|
|
sign.sign(privateKey);
|
|
}
|