Browse Source
crypto: clear err stack after ECDH::BufferToPoint
Functions that call `ECDH::BufferToPoint` were not clearing the
error stack on failure, so an invalid key could leave leftover
error state and cause subsequent (unrelated) signing operations
to fail.
PR-URL: https://github.com/nodejs/node/pull/13275
Backport-PR-URL: https://github.com/nodejs/node/pull/13397
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
v6.x
Ryan Kelly
8 years ago
committed by
Myles Borins
No known key found for this signature in database
GPG Key ID: 933B01F40B5CA946
2 changed files with
24 additions and
0 deletions
src/node_crypto.cc
test/parallel/test-crypto-dh.js
@ -5011,6 +5011,8 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
ECDH * ecdh ;
ECDH * ecdh ;
ASSIGN_OR_RETURN_UNWRAP ( & ecdh , args . Holder ( ) ) ;
ASSIGN_OR_RETURN_UNWRAP ( & ecdh , args . Holder ( ) ) ;
MarkPopErrorOnReturn mark_pop_error_on_return ;
if ( ! ecdh - > IsKeyPairValid ( ) )
if ( ! ecdh - > IsKeyPairValid ( ) )
return env - > ThrowError ( " Invalid key pair " ) ;
return env - > ThrowError ( " Invalid key pair " ) ;
@ -5160,6 +5162,8 @@ void ECDH::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
THROW_AND_RETURN_IF_NOT_BUFFER ( args [ 0 ] , " Public key " ) ;
THROW_AND_RETURN_IF_NOT_BUFFER ( args [ 0 ] , " Public key " ) ;
MarkPopErrorOnReturn mark_pop_error_on_return ;
EC_POINT * pub = ecdh - > BufferToPoint ( Buffer : : Data ( args [ 0 ] . As < Object > ( ) ) ,
EC_POINT * pub = ecdh - > BufferToPoint ( Buffer : : Data ( args [ 0 ] . As < Object > ( ) ) ,
Buffer : : Length ( args [ 0 ] . As < Object > ( ) ) ) ;
Buffer : : Length ( args [ 0 ] . As < Object > ( ) ) ) ;
if ( pub = = nullptr )
if ( pub = = nullptr )
@ -270,6 +270,26 @@ ecdh5.setPrivateKey(cafebabeKey, 'hex');
assert . strictEqual ( ecdh5 . getPrivateKey ( 'hex' ) , cafebabeKey ) ;
assert . strictEqual ( ecdh5 . getPrivateKey ( 'hex' ) , cafebabeKey ) ;
} ) ;
} ) ;
// Use of invalid keys was not cleaning up ERR stack, and was causing
// unexpected failure in subsequent signing operations.
const ecdh6 = crypto . createECDH ( 'prime256v1' ) ;
const invalidKey = Buffer . alloc ( 65 ) ;
invalidKey . fill ( '\0' ) ;
ecdh6 . generateKeys ( ) ;
assert . throws ( ( ) => {
ecdh6 . computeSecret ( invalidKey ) ;
} , /^Error: Failed to translate Buffer to a EC_POINT$/ ) ;
// Check that signing operations are not impacted by the above error.
const ecPrivateKey =
'-----BEGIN EC PRIVATE KEY-----\n' +
'MHcCAQEEIF+jnWY1D5kbVYDNvxxo/Y+ku2uJPDwS0r/VuPZQrjjVoAoGCCqGSM49\n' +
'AwEHoUQDQgAEurOxfSxmqIRYzJVagdZfMMSjRNNhB8i3mXyIMq704m2m52FdfKZ2\n' +
'pQhByd5eyj3lgZ7m7jbchtdgyOF8Io/1ng==\n' +
'-----END EC PRIVATE KEY-----' ;
assert . doesNotThrow ( ( ) => {
crypto . createSign ( 'SHA256' ) . sign ( ecPrivateKey ) ;
} ) ;
// invalid test: curve argument is undefined
// invalid test: curve argument is undefined
assert . throws ( ( ) => {
assert . throws ( ( ) => {
crypto . createECDH ( ) ;
crypto . createECDH ( ) ;