-
Notifications
You must be signed in to change notification settings - Fork 29.7k
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: Better documentation for cases where peer's public key is invalid #16625
Comments
Documentation pull request welcome but apropos this suggestion:
No, no other built-in APIs do that either, crypto or otherwise. |
But the fs API has an extended Error type, which has properties like code and errno. There you can easily detect specific errors as they are properly documented. |
Maybe we have a different definition of 'typed error'. Putting a couple of extra properties on a
|
Yeah sure extra properties on the |
Hi @Emill |
@bnoordhuis Are you going to act as a mentor here? |
I can. @j0t3x If you are asking for assistance, can you phrase you questions as closed (or at least directed) questions? "Any guidance" is a bit open-ended. |
Thanks @bnoordhuis!, Here it goes: For the first one, i have to use a generic error with description for when the public key lies out of the curve, right? From what i saw here, the crypto binding should throw the generic error and i should catch it?. For the second one, i can follow similar explanations like the one in net module notes here? :
|
Ideally, return an error code and construct the exception object in JS land.
Yes, that's the one you want.
Yep. |
Sorry to bother @bnoordhuis, Just to make it crystal clear for me, this implies using a try catch for the 2 error cases coming from crypto to then in the catch, construct the exception for every one of the 2? Thanks in advance. |
What I mean is that you replace the It's usually a number but it could be a string in this case, as long as you can distinguish it from a genuine return value in JS land (which in this function is a buffer.) While a try/catch would work, it's a bit inefficient because you end up creating two exception objects - one in C++, one in JS land - and that's fairly heavyweight because exceptions have to capture the stack. |
Ok, so it's getting clearer now 😄 . That part of the change should happen in if (!ecdh->IsKeyPairValid())
args.GetReturnValue().Set( the error here 1)//Invalid key pair if (!r) {
free(out);
args.GetReturnValue().Set(the error here 2)//Failed to compute ECDH key
}
Understood. Thanks @bnoordhuis |
Returning strings seems like the least-effort path. Numbers you'd have to map back to error messages first. |
Hi @bnoordhuis, Im almost done with the changes, just have a few questions:
Are those correct? Thanks in advance. |
Sounds alright to me and if not, I'll point it out during review. :-) |
Hi @bnoordhuis, heres the pr. Thanks to all involved for this 1st stage help :D |
The documentation for ecdh.computeSecret doesn't discuss what happens when the other public key doesn't lie on the curve. It just states that either a string with the given encoding or a Buffer will be returned. For other methods in the same class there are explicit documentation that these throws an error if for example the input is not valid for this curve, but not on this one.
If the own private key is static or not re-generated in each exchange, there are attacks that recover the private key. So all implementers need to handle this case as part of implementing a protocol where ECDH is used, by validating the provided public key and gracefully abort if the point is invalid. Using prime256v1 as an example, a first attempt might be to simply check that the buffer length of the input public key is 65 and the first byte is 0x04. But this is not enough since the point must also be checked against the curve equation. Since bignums are needed for this it's non-trivial to do this directly before the call, and one must rely on the library handling this.
Thankfully the actual implementation throws a generic error with the string
Failed to translate Buffer to a EC_POINT
, at least when I test it with prime256v1. I was hoping for a more catchable-friendly error, at least having a documented type or error code so it's easily distinguished to other errors. As far as my brain goes, I cannot find a single use case where one would not also want to check for this error since it's not a programmer error but always a possible user-input error.Since people are generally not aware how to use crypto, it's extremely important that the APIs are clear, easy to use and no mistakes are possible. So I was googling around a bit for "createECDH computeSecret" and found some code examples and tutorials. None of them handled this case or didn't even bring up the possibility that an attacker might give an incorrect public key. The only case I found testing this was the official test file. Just guessing, but I'm pretty sure there's a bunch of production systems that will crash if one gives an incorrect public key. And when the programmer then checks the crash log generated I'm not sure he would even know what
Failed to translate Buffer to a EC_POINT
means.My proposal is to first change the code to use some kind of typed error so it can be easily identified for this specific case and then update the documentation to catch this error in the example code as well as document in the
computeSecret
method how the invalid point error is reported. The example currently only usesassert.strictEqual
to confirm that the two values are equal.The text was updated successfully, but these errors were encountered: