Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto: Improve error checking and reporting #3753

Closed
wants to merge 1 commit into from

Conversation

stefanmb
Copy link
Contributor

In FIPS mode several test failures occur because of missing checks for OpenSSL API return codes. Where error checking already existed, the error messages often report some static string instead of passing through the actual error string from OpenSSL (which is significantly more helpful in identifying the root cause of the problem). I’ve added checks where necessary to prevent hard crashes and have given precedence to returning the OpenSSL error strings, instead of generic error strings, whenever possible.

@mscdex mscdex added crypto Issues and PRs related to the crypto subsystem. c++ Issues and PRs that require attention from people who are familiar with C++. labels Nov 11, 2015
@mhdawson
Copy link
Member

This looks pretty straight forward. Just one question on this part:

bool DiffieHellman::Init(int primeLength, int g) {
   dh = DH_new();
-  DH_generate_parameters_ex(dh, primeLength, g, 0);
+  if (!DH_generate_parameters_ex(dh, primeLength, g, 0))
+    return false;
   bool result = VerifyContext();
   if (!result)
     return false;

Can you explain how it failed without the change versus with. I'm assuming that VerifyContext() would have returned an error but that checking the result from DH_generate_parameters_ex() makes it return a better error

@stefanmb
Copy link
Contributor Author

@mhdawson

Without that change you will get a segfault. Here is the VerifyContext code:

bool DiffieHellman::VerifyContext() {
  int codes;
  if (!DH_check(dh, &codes))
    return false;
  verifyError_ = codes;
  return true;
}

If the previous call to DH_generate_parameters_ex fails, the dh output parameter will not be populated, and DH_check will segfault. For example:

gdb --args out/Debug/node node/test/parallel/test-crypto-dh-odd-key.js

Program received signal SIGSEGV, Segmentation fault.
0x0000000000c85175 in DH_check (dh=0x1fb1870, ret=0x7fffffffcb9c) at ../deps/openssl/openssl/crypto/dh/dh_check.c:115
115     } else if (BN_is_word(dh->g, DH_GENERATOR_2)) {
(gdb) bt 3
#0  0x0000000000c85175 in DH_check (dh=0x1fb1870, ret=0x7fffffffcb9c) at ../deps/openssl/openssl/crypto/dh/dh_check.c:115
#1  0x00000000015e704b in node::crypto::DiffieHellman::VerifyContext (this=0x1fb2df0) at ../src/node_crypto.cc:4578
#2  0x00000000015e5d36 in node::crypto::DiffieHellman::Init (this=0x1fb2df0, primeLength=32, g=2) at ../src/node_crypto.cc:4251

@mhdawson
Copy link
Member

Thanks for the details.

lgtm

@indutny
Copy link
Member

indutny commented Nov 11, 2015

LGTM

cc @nodejs/crypto I would like to have one more LGTM on this, just to be sure

@shigeki
Copy link
Contributor

shigeki commented Nov 12, 2015

LGTM

@mhdawson mhdawson self-assigned this Nov 12, 2015
@mhdawson
Copy link
Member

@mhdawson
Copy link
Member

lint failures

Done processing src/node_win32_etw_provider.cc
Done processing src/tty_wrap.cc
Done processing src/node_crypto_clienthello.cc
src/node_crypto.cc:3525: Lines should be <= 80 characters long [whitespace/line_length] [2]
src/node_crypto.cc:4542: Lines should be <= 80 characters long [whitespace/line_length] [2]
Done processing src/node_crypto.cc
Done processing src/node_crypto_bio.cc

Stefan please update commit/test and make sure "make lint" passes then I'll respin the CI run

Added checks where necessary to prevent hard crashes and gave
precedence to returning the OpenSSL error strings instead of generic
error strings.
@stefanmb
Copy link
Contributor Author

@mhdawson

Fixed!

@indutny
Copy link
Member

indutny commented Nov 12, 2015

LGTM

@mhdawson
Copy link
Member

lgtm and follow up CI Run https://ci.nodejs.org/job/node-test-pull-request/714/

Will land once this completes

mhdawson pushed a commit that referenced this pull request Nov 12, 2015
Added checks where necessary to prevent hard crashes and gave
precedence to returning the OpenSSL error strings instead of generic
error strings.

PR-URL: #3753
Reviewed-By: Fedor Indutny <[email protected]>
Reviewed-By: Shigeki Ohtsu <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
@mhdawson
Copy link
Member

Nothing in the CI run looked related (failures mostly job not starting to run as opposed to a test failing)

Landed as b7089f6

@mhdawson mhdawson closed this Nov 12, 2015
rvagg pushed a commit that referenced this pull request Nov 13, 2015
Added checks where necessary to prevent hard crashes and gave
precedence to returning the OpenSSL error strings instead of generic
error strings.

PR-URL: #3753
Reviewed-By: Fedor Indutny <[email protected]>
Reviewed-By: Shigeki Ohtsu <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
MylesBorins pushed a commit that referenced this pull request Nov 17, 2015
Added checks where necessary to prevent hard crashes and gave
precedence to returning the OpenSSL error strings instead of generic
error strings.

PR-URL: #3753
Reviewed-By: Fedor Indutny <[email protected]>
Reviewed-By: Shigeki Ohtsu <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
@MylesBorins
Copy link
Contributor

landed in v4.x-staging in c37a560

rvagg pushed a commit that referenced this pull request Dec 4, 2015
Added checks where necessary to prevent hard crashes and gave
precedence to returning the OpenSSL error strings instead of generic
error strings.

PR-URL: #3753
Reviewed-By: Fedor Indutny <[email protected]>
Reviewed-By: Shigeki Ohtsu <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
@@ -3530,6 +3535,9 @@ bool Hash::HashInit(const char* hash_type) {
return false;
EVP_MD_CTX_init(&mdctx_);
EVP_DigestInit_ex(&mdctx_, md_, nullptr);
if (0 != ERR_peek_error()) {
return false;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stefanmb Is there a reason you use ERR_peek_error() here instead of looking at the return value of EVP_DigestInit_ex()?

See #4221 for context.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bnoordhuis Nope, chalk it up to my unfamiliarity with OpenSSL API. Checking EVP_DigestInit_ex's return code should accomplish the same thing, without breaking #4221.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stefanmb Checking error stack instead of function return status is wrong as it will generate false positive in case there is previously (intentionally) ignored error. It broke node on Alpine Linux.

+1 for fixing this properly.

(yeah, openssl api is funky...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ncopa Thank you for bringing this up. Let's continue the discussion under #4221.

@jasnell jasnell mentioned this pull request Dec 17, 2015
jasnell pushed a commit that referenced this pull request Dec 17, 2015
Added checks where necessary to prevent hard crashes and gave
precedence to returning the OpenSSL error strings instead of generic
error strings.

PR-URL: #3753
Reviewed-By: Fedor Indutny <[email protected]>
Reviewed-By: Shigeki Ohtsu <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
jasnell pushed a commit that referenced this pull request Dec 23, 2015
Added checks where necessary to prevent hard crashes and gave
precedence to returning the OpenSSL error strings instead of generic
error strings.

PR-URL: #3753
Reviewed-By: Fedor Indutny <[email protected]>
Reviewed-By: Shigeki Ohtsu <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. crypto Issues and PRs related to the crypto subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants