#17040 closed Bug (fixed)
In utils.crypto.constant_time_compare only call ord on non ints.
Reported by: | adsworth | Owned by: | adsworth |
---|---|---|---|
Component: | Python 3 | Version: | 1.3 |
Severity: | Normal | Keywords: | |
Cc: | adsworth | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Iterating over a byte string in Python 3 will yield ints. Make sure that ord is only called on non ints.
Attachments (2)
Change History (10)
by , 13 years ago
Attachment: | utils-crypto_constant_time_compare.patch added |
---|
comment:1 by , 13 years ago
Patch needs improvement: | set |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:3 by , 13 years ago
In a py3 version we could call smart_str on the input then we are sure to have a byte string.
If we want the function to take unicode, then we don't need a new function only a check if the input is a unicode string. Iterating unicode strings in py3 yields chars.
I'll write up a patch with a separate py3 function.
by , 13 years ago
Attachment: | fix-1740-separate-function-for-py3.patch added |
---|
comment:4 by , 13 years ago
Patch needs improvement: | unset |
---|
new patch with a separate function for py3. The new function also calls smart_str on the input parameters to make certain they are byte strings.
I'm removing the "Patch needs improvement" flag. I hope that is OK.
comment:5 by , 13 years ago
Calling smart_str doesn't seem correct to me. ISTM that this function should either take a bytestring or a unicode string (and I'm not sure which) and any other input should be an error. Also, I'm not sure you can write a constant time comparison of unicode strings in py3k.
comment:6 by , 13 years ago
I am no crypto expert, but since constant_time_compare in django and in the contrib apps is only used to compare hashes or some sort of token. I'd think it save to assume byte strings is the "right thing".
Since a unicode string can use one or two bytes per char depending on the contents I think you are right about a constant time compare not being possible.
also calling ord() on a unicode char that is 2 bytes long results in a TypeError.
>>> ord('ழ்') Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: ord() expected a character, but string of length 2 found >>>
comment:7 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Accepted. But doing an
isinstance
check for each element seems like a pretty inefficient approach. The function is short enough that we are probably better of conditionally defining a different function for Python 3.