-
Notifications
You must be signed in to change notification settings - Fork 169
base32ct: Fix a panic when decoding inputs; enforce lengths. #2084
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
Conversation
|
Thanks, |
Formerly, Encoding::decode would write beyond the end of `dst` when the input (ignoring padding) had (length%8) == 1, 3, or 6. These lengths are not valid base32, so we now reject them.
0083d11 to
ece7177
Compare
So, it appears that, even without this change, base32ct rejects a bunch of strings that are allowed by base32, and vice versa. Is there a particular standard for what we should accept/reject? (For example, should we reject everything not explicitly allowed by RFC4648?) Or should I try to reverse-engineer what the base32 allows? (And should normalizing this be part of this PR?) |
|
Hmm, it's unfortunate the Perhaps compare to |
|
Going to go ahead and merge this. If you can follow up with some better testing, that'd be great, otherwise I will try to look into it eventually |
It documents the alphabet, but the problem lies in decoding erroneous inputs. For example, should the "unpadded" variant tolerate padding? And should the "padded" variant tolerate missing padding, or padding of an incorrect amount? And should both variants tolerate strings of an incorrect length, or strings where the final characters are padded out with "1" instead of "0"? According to RFC4648, encoders shouldn't generate any of those. Some of these are explicitly "MAY" reject, but others aren't specified. |
For the purposes of the Regarding the others, I'd generally prefer the strictest interpretation, especially if ambiguities complicate constant-time operation. If other crates tolerate that sort of thing, it might need a separate "linter" to enforce strictness the other implementations lack. |
Formerly, Encoding::decode would write beyond the end of
dstwhen the input (ignoring padding) had (length%8) == 1, 3, or 6.These lengths are not valid base32, so we now reject them.
I've included a unit test to make sure that we now give equivalent outputs for truncated and non-truncated cases. Formerly, this test would panic for inputs of the wrong lengths. To reproduce the panic, try running:
I have not verified that rejecting inputs with impossible base32 lengths is the same behavior as the base32 crate.
I have not fuzzed the decoders to verify that no other panics are possible.