-
Notifications
You must be signed in to change notification settings - Fork 271
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
Display and Debug for secret keys prints a hash #312
Conversation
c7315bb
to
2d260f1
Compare
adfda2e
to
739d36f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK
src/key.rs
Outdated
#[cfg(any(feature = "std", feature = "alloc"))] { | ||
#[allow(deprecated)] | ||
s.serialize_str(&self.format_secret()) | ||
} | ||
#[cfg(not(any(feature = "std", feature = "alloc")))] | ||
s.serialize_bytes(&self[..]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
idk if we really want that.
serializing differently depending on features can cause serious breakage.
we can also easily implement stack based str here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, can you elaborate how to do that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the last 2 commits here: https://github.com/elichai/rust-secp256k1/tree/pr-312 (feel free to cherry-pick them)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@elichai cherry-picked, thanks!
Is there an actual need to print a hash of the private key instead of just |
@elichai I think since we need to distinguish two different keys it's good to print their hashes |
idk, I'm not a big fun of actual logic inside of Debug prints, and also not sure assuming that it's safe to print a hash of a private key is such a great assumption, @real-or-random @apoelstra what do you think? |
No strong opinions here. I think it's acceptable for Debug.
I think it's fine. I think even printing the keys out is fine, even though it's better to avoid that footgun. (But if you have Debug prints in your code, it's your fault in the end...) Hashing is for sure a better idea, and secret keys should have enough entropy. But we should nevertheless tag the tash, i.e., add a prefix like "rust-secp256k1DEBUG" to make sure we don't collide with other Maybe even BIP340-style tagging if bitcoinhashes supports this. |
@devrandom I did tagged hashing. Doing it with |
Ironically enough, the wrong random person was tagged in the previous message. ;-) |
Ha! That's funny! Sorry :) @real-or-random, I meant you |
src/macros.rs
Outdated
/// This is the only method that outputs the actual secret key value, and, thus, | ||
/// should be used with extreme precaution. | ||
#[deprecated( | ||
note = "Caution: you are explicitly outputting secret key value! This can be done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a user says they want to do something, let them do it. Forcing a warning print or an allow statement after they explicitly stated they want it (via an aptly named method call) is just making the library harder to use for no obvious gain. The goal here should be to make sure that the users' code is readable - if they're writing out the secret key it should be really painfully obvious that they are - not to make it actively hard for the user to write out secret key material.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume the point of the warning is that users don't forget to remove debug prints from their code after debugging. And this seems indeed helpful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And if a user actually wants to print a secret for some reason? eg in lightning you might imagine a secret which just represents the payment claim, and which the sender should not consider materially "secret"? Not all cryptographic protocols require that secrets stay out of debug logs, nor should we be the ones to decide that even if the secrets control lots of bitcoin! It's not our job to "fix" client applications, only remove foot guns; if they don't do code review or catch bugs that our well-named functions make obvious, there isn't anything we can do about it, and we shouldn't make the lives of our users harder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And if a user actually wants to print a secret for some reason? eg in lightning you might imagine a secret which just represents the payment claim, and which the sender should not consider materially "secret"?
Yeah, and you may want to build protocols where public keys are secret. secp256k1 is supposed to be high-level library hard to misuse. As a wrapper we should follow the same philosophy. And this means we need to make an educated guess which values are supposed to be secret, and I think then a secret key is a good candidate. ;)
Not all cryptographic protocols require that secrets stay out of debug logs, nor should we be the ones to decide that even if the secrets control lots of bitcoin! It's not our job to "fix" client applications, only remove foot guns; if they don't do code review or catch bugs that our well-named functions make obvious, there isn't anything we can do about it, and we shouldn't make the lives of our users harder.
I think in this case is foot-gunny. You introduce some Debug prints for debugging, then fix your bug and forget to remove the Debug prints. If you want to print secrets in production, even for logging, there are other ways to do. It's not impossible to do it, we're just forcing the users to think about their intentions.
But of course, the distinction between avoiding foot guns and imposing our will on users is fuzzy, and it's no surprise that different people draw the line in different places. So in the end, I don't care too much.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look at it another way, what if a user, for whatever reason, legitimately wants to print a secret key? Adding a giant warning every time they compile is just being obnoxious. We can be anti-footgun by making the warning something clearer (I dunno, fmt_secret_key_printing_secret), forcing users to see a scary compile warning is going beyond anti-footgun and assuming users are using the library in exactly the way we intend (which I guess is just on-chain bitcoin, cause this doesn't make sense for lighting).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And if a user actually wants to print a secret for some reason?
Then you should mark such calls with #[allow(deprecated)]
as like here: b284e44#diff-0988d5d2259e1a401001675578c38d09c46290b877b66b07fb96a7e034ccdf70R674
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Frankly, I find that kind of thing obnoxious to our users. It is not our job to tell users exactly how they must use this library, and we shouldn't force our users to add stupid hacks and workarounds just to use the library. We can help them avoid bugs by making sure their code is clear in their calls to clearly-named functions, but that's about it. Also, this method is not deprecated, it's intended to be in the API, so it's just completely a misnomer and confusing to users on top.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed that depreciation part
0858c9f
to
a828af6
Compare
@TheBlueMatt @thomaseizinger @elichai Tried to fulfill all suggestions, completelly refactored PR history. Now there is no |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
A few nits, but generally ACK a828af6
UPDT: @thomaseizinger actually had to revert that change: its impossible to use |
e209663
to
73c0779
Compare
Should remove the commit from #314 and I'm not sure why |
73c0779
to
7cd29e0
Compare
@thomaseizinger all all suggestions are implemented @apoelstra commit removed. As for manual hex, we need this function b/c of no-std |
1f5d6da
to
60f7e58
Compare
Debug-print secrets as tagged hashes Refactoring Display/Debug for secret values with display_secret
60f7e58
to
6810c2b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 6810c2b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 6810c2b
I assume this can be merged now? At least github says all criteria are fulfilled. |
Yep, thanks |
de77518 Serde serialization for KeyPair (Dr Maxim Orlovsky) Pull request description: Serde implementation for `KeyPair` type (which hadn't it before). Based on #312 (includes all commits from that PR, will be rebased upon merge) ACKs for top commit: apoelstra: ACK de77518 Tree-SHA512: 1e75c4fc772dcba5ce7edb30235a58550342cf986c6a77b4affd81defeba456c9655e28b081e0040c1f8440da3f7ad2224485d35222c1921099567b4d1533794
Needed to pump the lightning version used and had to pump bitcoin, bitcoincore-rpc aswell to match dep verions in lightining merkle root computation changed in `bitcoin`, thus some methods in the test_utils needed to adapt (basically by adding a tx if there is none in a block). See: rust-bitcoin/rust-bitcoin@b454cf8 Also SecretKey had it's `to_string` method removed, so TEOS now encodes its tower key using `secret_bytes()` and `from_slice()`. See: rust-bitcoin/rust-secp256k1#312
Needed to pump the lightning version used and had to pump bitcoin, bitcoincore-rpc aswell to match dep verions in lightining merkle root computation changed in `bitcoin`, thus some methods in the test_utils needed to adapt (basically by adding a tx if there is none in a block). See: rust-bitcoin/rust-bitcoin@b454cf8 Also SecretKey had it's `to_string` method removed, so TEOS now encodes its tower key using `secret_bytes()` and `from_slice()`. See: rust-bitcoin/rust-secp256k1#312
Needed to pump the lightning version used and had to pump bitcoin, bitcoincore-rpc aswell to match dep verions in lightining merkle root computation changed in `bitcoin`, thus some methods in the test_utils needed to adapt (basically by adding a tx if there is none in a block). See: rust-bitcoin/rust-bitcoin@b454cf8 Also SecretKey had it's `to_string` method removed, so TEOS now encodes its tower key using `secret_bytes()` and `from_slice()`. See: rust-bitcoin/rust-secp256k1#312
Needed to pump the lightning version used and had to pump bitcoin, bitcoincore-rpc aswell to match dep verions in lightining merkle root computation changed in `bitcoin`, thus some methods in the test_utils needed to adapt (basically by adding a tx if there is none in a block). See: rust-bitcoin/rust-bitcoin@b454cf8 Also SecretKey had it's `to_string` method removed, so TEOS now encodes its tower key using `secret_bytes()` and `from_slice()`. See: rust-bitcoin/rust-secp256k1#312
Needed to pump the lightning version used and had to pump bitcoin, bitcoincore-rpc aswell to match dep verions in lightining merkle root computation changed in `bitcoin`, thus some methods in the test_utils needed to adapt (basically by adding a tx if there is none in a block). See: rust-bitcoin/rust-bitcoin@b454cf8 Also SecretKey had it's `to_string` method removed, so TEOS now encodes its tower key using `secret_bytes()` and `from_slice()`. See: rust-bitcoin/rust-secp256k1#312
Needed to bump the lightning version used and had to bump bitcoin, bitcoincore-rpc aswell to match dep verions in lightining merkle root computation changed in `bitcoin`, thus some methods in the test_utils needed to adapt (basically by adding a tx if there is none in a block). See: rust-bitcoin/rust-bitcoin@b454cf8 Also SecretKey had it's `to_string` method removed, so TEOS now encodes its tower key using `secret_bytes()` and `from_slice()`. See: rust-bitcoin/rust-secp256k1#312
Needed to bump the lightning version used and had to bump bitcoin, bitcoincore-rpc aswell to match dep verions in lightining merkle root computation changed in `bitcoin`, thus some methods in the test_utils needed to adapt (basically by adding a tx if there is none in a block). See: rust-bitcoin/rust-bitcoin@b454cf8 Also SecretKey had it's `to_string` method removed, so TEOS now encodes its tower key using `display_secret().to_string()`. See: rust-bitcoin/rust-secp256k1#312
Needed to bump the lightning version used and had to bump bitcoin, bitcoincore-rpc aswell to match dep verions in lightining merkle root computation changed in `bitcoin`, thus some methods in the test_utils needed to adapt (basically by adding a tx if there is none in a block). See: rust-bitcoin/rust-bitcoin@b454cf8 Also SecretKey had it's `to_string` method removed, so TEOS now encodes its tower key using `display_secret().to_string()`. See: rust-bitcoin/rust-secp256k1#312
Extract of concept ACK part of #311 related to changing the way secret keys are displayed/printed out