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

src: split CryptoPemCallback into two functions #12827

Closed

Conversation

danbev
Copy link
Contributor

@danbev danbev commented May 4, 2017

Currently the function CryptoPemCallback is used for two things:

  1. As a passphrase callback.
  2. To avoid the default OpenSSL passphrase routine.

The default OpenSSL passphase routine would apply if both
the callback and the passphrase are null pointers and the typical
behaviour is to prompt for the passphase which is not appropriate in
node.

This commit suggests that the PasswordCallback function only handle
passphrases, and that an additional function named NoPasswordCallback
used for the second case to avoid OpenSSL's passphase routine.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • commit message follows commit guidelines
Affected core subsystem(s)

src

Currently the function CryptoPemCallback is used for two things:
1. As a passphrase callback.
2. To avoid the default OpenSSL passphrase routine.

The default OpenSSL passphase routine would apply if both
the callback and the passphrase are null pointers and the typical
behaviour is to prompt for the passphase which is not appropriate in
node.

This commit suggests that the PasswordCallback function only handle
passphrases, and that an additional function named NoPasswordCallback
used for the second case to avoid OpenSSL's passphase routine.
@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. crypto Issues and PRs related to the crypto subsystem. labels May 4, 2017
@danbev
Copy link
Contributor Author

danbev commented May 4, 2017

Copy link
Contributor

@cjihrig cjihrig left a comment

Choose a reason for hiding this comment

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

LGTM, but @shigeki should probably take a look.

@mscdex
Copy link
Contributor

mscdex commented May 4, 2017

/cc @nodejs/crypto

indutny
indutny previously requested changes May 4, 2017
Copy link
Member

@indutny indutny left a comment

Choose a reason for hiding this comment

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

I like this direction, let's do it! Few nits, though.

len = len > buflen ? buflen : len;
memcpy(buf, u, len);
return len;
}

Copy link
Member

Choose a reason for hiding this comment

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

Please add one more newline here, please.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll fix that.

@@ -473,7 +475,7 @@ void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {

if (len == 2) {
if (args[1]->IsUndefined() || args[1]->IsNull())
len = 1;
has_password = false;
else
THROW_AND_RETURN_IF_NOT_STRING(args[1], "Pass phrase");
}
Copy link
Member

Choose a reason for hiding this comment

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

What if len == 1 from the start? It looks like has_password will be true?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh yes, sorry. Let me fix that. Thanks

@danbev
Copy link
Contributor Author

danbev commented May 5, 2017

memcpy(buf, u, len);
return len;
}
CHECK_NE(u, nullptr);
Copy link
Contributor

@sam-github sam-github May 5, 2017

Choose a reason for hiding this comment

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

consider bringing back the conditional... EDIT: ... because it simplifies code, see below.

Copy link
Member

Choose a reason for hiding this comment

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

@@ -482,12 +485,13 @@ void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
if (!bio)
return;

node::Utf8Value passphrase(env->isolate(), args[1]);

auto callback = has_password ? PasswordCallback : NoPasswordCallback;
Copy link
Contributor

Choose a reason for hiding this comment

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

... because it really simplifies this code.

This function uses the password cb because it may have a password.

The other examples below that use NoPasswordCallback I agree are more clear because the usage makes it really clear that there is no password, but I think here it is unnecessarily complex, caused only because the PasswordCallback stopped supporting an empty password.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, I see. 👍

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, for the unnecessarily obscure comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fair point. Let me restore the original allowing a null passphrase but keep the NoPasswordCallback for this.

@@ -243,6 +241,13 @@ static int PasswordCallback(char *buf, int size, int rwflag, void *u) {
}


// This callback is used to avoid the default passphrase callback in OpenSSL
// which will typically prompt for the passphrase.
Copy link
Contributor

Choose a reason for hiding this comment

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

"the prompting is designed for the openssl CLI, but works poorly for Node.js because it involves synchronous interaction with the controlling terminal, something we never want, and use this function to avoid." <--- Maybe add something like that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added that now, thanks!

Copy link
Member

@addaleax addaleax left a comment

Choose a reason for hiding this comment

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

Just reaffirming my LGTM for the latest changes

@danbev
Copy link
Contributor Author

danbev commented May 9, 2017

@indutny Would you mind taking a look and see what you think now? Your requested changes have been added (really only became the extra line as the other was reverted following the suggestions by sam-github). Thanks

@danbev
Copy link
Contributor Author

danbev commented May 12, 2017

@indutny Sorry about nagging, just wanted to ask again if you have anything against this landing?

@addaleax
Copy link
Member

Landed in 29d89c9

@addaleax addaleax closed this May 18, 2017
addaleax pushed a commit that referenced this pull request May 18, 2017
Currently the function CryptoPemCallback is used for two things:
1. As a passphrase callback.
2. To avoid the default OpenSSL passphrase routine.

The default OpenSSL passphase routine would apply if both
the callback and the passphrase are null pointers and the typical
behaviour is to prompt for the passphase which is not appropriate in
node.

This commit suggests that the PasswordCallback function only handle
passphrases, and that an additional function named NoPasswordCallback
used for the second case to avoid OpenSSL's passphase routine.

PR-URL: #12827
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
@danbev
Copy link
Contributor Author

danbev commented May 19, 2017

@addaleax Thanks!

anchnk pushed a commit to anchnk/node that referenced this pull request May 19, 2017
Currently the function CryptoPemCallback is used for two things:
1. As a passphrase callback.
2. To avoid the default OpenSSL passphrase routine.

The default OpenSSL passphase routine would apply if both
the callback and the passphrase are null pointers and the typical
behaviour is to prompt for the passphase which is not appropriate in
node.

This commit suggests that the PasswordCallback function only handle
passphrases, and that an additional function named NoPasswordCallback
used for the second case to avoid OpenSSL's passphase routine.

PR-URL: nodejs#12827
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
@jasnell jasnell mentioned this pull request May 28, 2017
@gibfahn gibfahn mentioned this pull request Jun 15, 2017
3 tasks
@danbev danbev deleted the crypto-password-callback-refactor branch June 28, 2017 05:28
MylesBorins pushed a commit that referenced this pull request Jul 17, 2017
Currently the function CryptoPemCallback is used for two things:
1. As a passphrase callback.
2. To avoid the default OpenSSL passphrase routine.

The default OpenSSL passphase routine would apply if both
the callback and the passphrase are null pointers and the typical
behaviour is to prompt for the passphase which is not appropriate in
node.

This commit suggests that the PasswordCallback function only handle
passphrases, and that an additional function named NoPasswordCallback
used for the second case to avoid OpenSSL's passphase routine.

PR-URL: #12827
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
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