pyopenssl
pyopenssl copied to clipboard
TypeError due to missing encoding in byte_string
Passing a unicode string to the sign method in Python 2.6, I get the following error:
File "/usr/local/lib/python2.6/dist-packages/pyOpenSSL-0.14-py2.6.egg/OpenSSL/crypto.py", line 827, in sign evp_md = _lib.EVP_get_digestbyname(_byte_string(digest)) TypeError: initializer for ctype 'char *' must be a str or list or tuple, not unicode
I think the byte_string function in _util.py:
if PY3:
def byte_string(s):
return s.encode("charmap")
else:
def byte_string(s):
return s
should be changed to:
def byte_string(s):
if isinstance(s, text_type):
return s.encode("charmap")
return s
Does the same exception occur on pyOpenSSL 0.13?
No, it doesn't.
Following this suggestion will fix #741 and #730
The current definition of byte_string
doesn't work on either PY3 or PY2.
On PY3 it expects a str
, but everywhere using it documents that a bytes
is expected.
On PY2 it expects a bytes
.
This is a problem if a single file is written for both python2 & 3 by using from __future__ import unicode_literals
, because that file has to use either:
1 "sha256", which is unicode, and is converted correct on py3 (✔️) but not py2 (❌) 2. or b"sha256", which is bytes, and is not converted on py2 (✔️) but results in an attribute error on py3 (❌)
This means I'm having to make my call sites do this:
if six.PY3:
digest = 'sha256'
else:
digest = b'sha256'
or:
from future.utils import bytes_to_native_str
bytes_to_native_str(b"sha256")
which is not ideal!
Are pull requests welcome for this? I'd be happy to make the changes. This has been open for quite long time. Fix suggested by @joonis should essentially allow both str
and bytes
to be passed.
Yes we would take a PR for this, although it would be desirable for this to be consistent across the API.
This has been fixed in https://github.com/pyca/pyopenssl/commit/41ceefb0f81d6ac056e9d84e47de57191e067b8e, and can now be closed. cc @reaperhulk