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
Convert bcrypt to use OpenBSD code #68
Conversation
retval = _bcrypt.lib.crypt_gensalt_rn( | ||
b"$" + prefix + b"$", rounds, salt, len(salt), output, len(output), | ||
return ( | ||
b"$" + prefix + b"$" + ("%2.2u" % rounds).encode("ascii") + b"$" + |
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.
Any reason not to use b"%2.2u" % rounds
(or b"$%s$%2.2u$" % (prefix, rounds)
)?
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.
You can't use %
with bytes in Py3 :)
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 that’s what I get for “temporarily” linking python to python2. Sorry!
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.
Haha, no problem. I'm pleased that you're reviewing this!
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.
Reviewing history, I did actually check it properly: %
works with bytes
as of 3.5. (Seeing as 3.3 is the compatibility target, though, that doesn’t really matter.)
Back to WIP because this doesn't work on Windows yet. |
This is now tested on Mac (El Capitan), Linux, and Windows under py2 and py3. We should consider improving the test infra for bcrypt a blocker for merging this as that validation should be provided in the status checks, not just my assertion that I tested it and it works. |
salt = os.urandom(16) | ||
output = _bcrypt.ffi.new("unsigned char[]", 30) | ||
_bcrypt.lib.encode_base64(output, salt, len(salt)) |
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.
Any reason to write/use our own base64 encoding instead of using what the standard library already supplies?
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.
Right, I see we need our own base64 encoding in the C code to return the hashed password, but I think that this particular call can just use the standard library version. I guess there's an argument to be made for using this here so that we use the same encoding function everywhere, but it feels like to me it'd be better to just not expose the encode_base64
function via cffi and just treat it as an internal implementation detail of the library, and to use the standard library code in Python.
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.
This one doesn't add trailing = but I don't know if there are any other differences. We may be able to switch (I originally had it using stdlib but converted it during the port for no good reason)
Couple of general questions:
|
Another thought: Since we're using different backing library, would it make sense to pull out the test vectors from openwall's code and add that into this library? |
|
@reaperhulk so, at one point I think we were defaulting to
Which suggests to me that we could regain support for the import re
_normalize_re = re.compile(b"^\$2y\$")
def _normalize_prefix(hashed):
return _normalize_re.sub(b"$2b$", hashed) |
I do think if we do that though, we should fail on passing a |
That seems fair. I'll update this PR to add support for understanding |
I realize I didn't address the "what does updating this look like" question... Updating this is going to be challenging because we've taken a snapshot of the OpenBSD code, removed various functions we don't need, changed a few function definitions from static, added some include headers to make it work across various platforms, and changed the way it does endian swapping. Updating will require doing a diff of the new version vs ours and then looking at the diff to understand what has changed that we may want to pull in and what is affecting areas we've intentionally removed/changed. In practice updating is unlikely to be required except in the event of a security vulnerability. One potential way we could split this up would be to make the C code a separate project called |
@reaperhulk I'm not particularly opposed to the idea that updating is harder as long as we explicitly make that choice and we don't accidentally make it and end up regretting it. Looking at the code base for the openwall code, it appears that it's had practically no changes since it's original implementation besides the prefix handing and that one security fix, so I think it's a pretty safe thing to not really worry too hard about unless we can think of a low impact way to make it easier. |
test vectors from openwall crypt-blowfish1.3
Are we using the OpenBSD C code verbatim, sans modification? Because man there are some missing braces for some if statements that I don't like. |
There have been changes (removal of functions, removal of static on one or two declarations, and the endian change), but I've tried hard to minimize those to make it vaguely possibly to compare them. I'd rather not diverge further, but I do agree that the lack of consistent bracing is pretty unfortunate. |
|
||
for (i = 0; i < 4; i++) { | ||
for (k = 0; k < 256; k += 2) { | ||
d[0]^= Blowfish_stream2word(data, databytes, &j); |
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.
consistency nitpick: space after right bracket?
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.
Fixing this would make the diff from OpenBSD even harder to read 😢 (most of this is a direct copy from their source tree)
I have reviewed this PR. |
🎉 💃 🏆 |
This allows us to add bcrypt_pbkdf to support OpenSSH keys much more easily.
Some review things:
sha2.c
to usebe64toh
,htobe64
, andle32toh
are correct.