You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I noticed today when working with public keys and verifying signatures that I would get generic error messages when there was a problem reading a public key, for example: PEM_read_bio_PUBKEY failed
Whereas if I check the OpenSSL error stack, I find more detailed/useful error strings, for example:
Sure, all that needs to be done is pass in any invalid key:
varcrypto=require('crypto');varverifier=crypto.createVerify('sha256');verifier.update('foo');varbadKey=['-----BEGIN PUBLIC KEY-----','AFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcCBI3Rvez5Ake8TVukoQ3GNL7FSc','mwLYfY+VubJxFHytq8sLdMBd2Gjr5emoyQDJb3nt/YH+0aaPPeDr8acy9A==','-----END PUBLIC KEY-----'].join('\n');verifier.verify(badKey,newBuffer('1234567890'));
If you then apply this:
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index 986fe80..de7d8c4 100644
--- a/src/node_crypto.cc+++ b/src/node_crypto.cc@@ -4060,8 +4060,10 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem,
// consumer of public keys.
if (strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
pkey = PEM_read_bio_PUBKEY(bp, nullptr, CryptoPemCallback, nullptr);
- if (pkey == nullptr)+ if (pkey == nullptr) {+ ERR_print_errors_fp(stderr);
goto exit;
+ }
} else if (strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
RSA* rsa =
PEM_read_bio_RSAPublicKey(bp, nullptr, CryptoPemCallback, nullptr);
and re-run the example you will get more information like:
I think what may be happening is that when it jumps to exit, additional OpenSSL functions are used which somehow clears the error stack and that is why when SignBase::CheckThrow() is called, ERR_get_error() doesn't return an error, causing one of the generic messages to be used instead?
/cc @nodejs/collaborators Does anyone have any thoughts/opinions on how many of the OpenSSL errors should be returned or just use the most recent one on the OpenSSL error stack?
I wouldn't object to exposing the openssl error stack as a property on the exception object.
You call ERR_set_mark() before starting the operation that can fail. On failure, you scan the elements from ERR_get_state() until you find the one with the ERR_FLAG_MARK flag set.
I still think the actual exception message should be changed even if the OpenSSL error stack is added as a separate property, since not everyone will (or will always know to) access that property to find the "real" error.
Would anyone be opposed to changing the exception message to the most recent OpenSSL error and adding the rest of the stack as a separate property? Also any suggestions on that property name?
Yes. I've added 'good first contribution' and 'c++' tags. It's probably a fair amount of work but not very complex so a good starting point for someone who wants to dive into the C++ side of things. If you want to work on this and have questions, don't hesitate to ping me.
Would anyone be opposed to changing the exception message to the most recent OpenSSL error and adding the rest of the stack as a separate property?
Seems fine to me. Changing the error message automatically makes it semver-major though.
Total noob question here, but im not grasping something fundamental here. I understand that i'll prob have to move some code around but i'm failing to see how to add a new property to the exception object. Like, how would one add the property 'foo' with value 'bar' to the exception object.
If i step through the code, I can see the VerifyFinal return the error enum, then CheckThrow is called. Which will then call ThrowCryptoError, which will call ThrowError with the errmsg string from openssl, which will then create a v8 Exception with the errmsg passed in and throws the exception in v8. I doubt we want to be editing the v8 exception/code to take in additional parameters. Maybe i'm overlooking something but the only thing i can see is a err string being passed over, which eventually gets turned into v8 Exception. So how would one add a new property to the exception to get passed back over to JS?
Activity
mscdex commentedon Feb 26, 2016
/cc @nodejs/crypto
indutny commentedon Mar 1, 2016
Do you have a test?
mscdex commentedon Mar 1, 2016
Sure, all that needs to be done is pass in any invalid key:
If you then apply this:
and re-run the example you will get more information like:
I think what may be happening is that when it jumps to
exit, additional OpenSSL functions are used which somehow clears the error stack and that is why whenSignBase::CheckThrow()is called,ERR_get_error()doesn't return an error, causing one of the generic messages to be used instead?mscdex commentedon Apr 15, 2016
@indutny Thoughts?
mscdex commentedon Jun 16, 2016
/cc @nodejs/collaborators Does anyone have any thoughts/opinions on how many of the OpenSSL errors should be returned or just use the most recent one on the OpenSSL error stack?
bnoordhuis commentedon Jun 16, 2016
I wouldn't object to exposing the openssl error stack as a property on the exception object.
You call
ERR_set_mark()before starting the operation that can fail. On failure, you scan the elements fromERR_get_state()until you find the one with theERR_FLAG_MARKflag set.indutny commentedon Jun 16, 2016
@mscdex this sounds good to me
mscdex commentedon Jun 18, 2016
I still think the actual exception message should be changed even if the OpenSSL error stack is added as a separate property, since not everyone will (or will always know to) access that property to find the "real" error.
Would anyone be opposed to changing the exception message to the most recent OpenSSL error and adding the rest of the stack as a separate property? Also any suggestions on that property name?
indutny commentedon Jun 18, 2016
@mscdex should we add them as an array then? It could be
opensslErrorproperty, but I'm not the best person to ask about naming!Trott commentedon Jul 7, 2017
This is still an unfulfilled feature request?
bnoordhuis commentedon Jul 8, 2017
Yes. I've added 'good first contribution' and 'c++' tags. It's probably a fair amount of work but not very complex so a good starting point for someone who wants to dive into the C++ side of things. If you want to work on this and have questions, don't hesitate to ping me.
Seems fine to me. Changing the error message automatically makes it semver-major though.
4 remaining items
bnoordhuis commentedon Aug 4, 2017
The latter, the binding function.
ThrowCryptoError() is the function you want, most likely. You'll probably have to move some code around to be able to adorn the exception object.
gla5001 commentedon Aug 8, 2017
Total noob question here, but im not grasping something fundamental here. I understand that i'll prob have to move some code around but i'm failing to see how to add a new property to the exception object. Like, how would one add the property 'foo' with value 'bar' to the exception object.
If i step through the code, I can see the
VerifyFinalreturn the error enum, thenCheckThrowis called. Which will then callThrowCryptoError, which will callThrowErrorwith the errmsg string from openssl, which will then create a v8 Exception with the errmsg passed in and throws the exception in v8. I doubt we want to be editing the v8 exception/code to take in additional parameters. Maybe i'm overlooking something but the only thing i can see is a err string being passed over, which eventually gets turned into v8 Exception. So how would one add a new property to the exception to get passed back over to JS?Any help or resources would be appreciated.
bnoordhuis commentedon Aug 8, 2017
Like this, basically:
crypto: better crypto error messages
crypto: better crypto error messages
crypto: better crypto error messages
crypto: better crypto error messages
crypto: better crypto error messages
crypto: better crypto error messages
crypto: better crypto error messages
crypto: better crypto error messages
crypto: better crypto error messages
ryzokuken commentedon Mar 4, 2018
I see that commits referencing this issue have been added. Shouldn't this issue be closed?
bnoordhuis commentedon Mar 4, 2018
Yes, this is complete. I'll close.