Skip to content

Commit

Permalink
crypto: make ConvertKey clear openssl error stack
Browse files Browse the repository at this point in the history
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: #26153
Fixes: #26133
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
bnoordhuis authored and rvagg committed Feb 28, 2019
1 parent a3f7471 commit 108c698
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/node_crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6095,6 +6095,7 @@ void ExportChallenge(const FunctionCallbackInfo<Value>& args) {

// Convert the input public key to compressed, uncompressed, or hybrid formats.
void ConvertKey(const FunctionCallbackInfo<Value>& args) {
MarkPopErrorOnReturn mark_pop_error_on_return;
Environment* env = Environment::GetCurrent(args);

CHECK_EQ(args.Length(), 3);
Expand Down
26 changes: 25 additions & 1 deletion test/parallel/test-crypto-ecdh-convert-key.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ if (!common.hasCrypto)

const assert = require('assert');

const { ECDH, getCurves } = require('crypto');
const { ECDH, createSign, getCurves } = require('crypto');

// A valid private key for the secp256k1 curve.
const cafebabeKey = 'cafebabe'.repeat(8);
Expand Down Expand Up @@ -99,3 +99,27 @@ if (getCurves().includes('secp256k1')) {
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);
}

0 comments on commit 108c698

Please sign in to comment.