Add OpenSSL 1.1.0 compatibility
- thanks to Wolfgang Frisch <wfr@roembden.net>
This commit is contained in:
parent
59cf33c9a1
commit
6778d6046f
|
@ -100,11 +100,7 @@ def createSupportMessage(myapp):
|
|||
architecture = "32" if ctypes.sizeof(ctypes.c_voidp) == 4 else "64"
|
||||
pythonversion = sys.version
|
||||
|
||||
SSLEAY_VERSION = 0
|
||||
OpenSSL._lib.SSLeay.restype = ctypes.c_long
|
||||
OpenSSL._lib.SSLeay_version.restype = ctypes.c_char_p
|
||||
OpenSSL._lib.SSLeay_version.argtypes = [ctypes.c_int]
|
||||
opensslversion = "%s (Python internal), %s (external for PyElliptic)" % (ssl.OPENSSL_VERSION, OpenSSL._lib.SSLeay_version(SSLEAY_VERSION))
|
||||
opensslversion = "%s (Python internal), %s (external for PyElliptic)" % (ssl.OPENSSL_VERSION, OpenSSL()._version)
|
||||
|
||||
frozen = "N/A"
|
||||
if paths.frozen:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#! python
|
||||
|
||||
import sys
|
||||
import pyelliptic.openssl
|
||||
|
||||
#Only really old versions of Python don't have sys.hexversion. We don't support
|
||||
#them. The logging module was introduced in Python 2.3
|
||||
|
@ -106,8 +107,9 @@ def check_openssl():
|
|||
except:
|
||||
pass
|
||||
|
||||
SSLEAY_VERSION = 0
|
||||
SSLEAY_CFLAGS = 2
|
||||
openssl_version = None
|
||||
openssl_hexversion = None
|
||||
openssl_cflags = None
|
||||
|
||||
cflags_regex = re.compile(r'(?:OPENSSL_NO_)(AES|EC|ECDH|ECDSA)(?!\w)')
|
||||
|
||||
|
@ -118,23 +120,18 @@ def check_openssl():
|
|||
except OSError:
|
||||
continue
|
||||
logger.info('OpenSSL Name: ' + library._name)
|
||||
try:
|
||||
library.SSLeay.restype = ctypes.c_long
|
||||
library.SSLeay_version.restype = ctypes.c_char_p
|
||||
library.SSLeay_version.argtypes = [ctypes.c_int]
|
||||
except AttributeError:
|
||||
openssl_version, openssl_hexversion, openssl_cflags = pyelliptic.openssl.get_version(library)
|
||||
if not openssl_version:
|
||||
logger.error('Cannot determine version of this OpenSSL library.')
|
||||
return False
|
||||
logger.info('OpenSSL Version: ' + library.SSLeay_version(SSLEAY_VERSION))
|
||||
compile_options = library.SSLeay_version(SSLEAY_CFLAGS)
|
||||
logger.info('OpenSSL Compile Options: ' + compile_options)
|
||||
openssl_hexversion = library.SSLeay()
|
||||
logger.info('OpenSSL Version: ' + openssl_version)
|
||||
logger.info('OpenSSL Compile Options: ' + openssl_cflags)
|
||||
#PyElliptic uses EVP_CIPHER_CTX_new and EVP_CIPHER_CTX_free which were
|
||||
#introduced in 0.9.8b.
|
||||
if openssl_hexversion < 0x90802F:
|
||||
logger.error('This OpenSSL library is too old. PyBitmessage requires OpenSSL 0.9.8b or later with AES, Elliptic Curves (EC), ECDH, and ECDSA enabled.')
|
||||
return False
|
||||
matches = cflags_regex.findall(compile_options)
|
||||
matches = cflags_regex.findall(openssl_cflags)
|
||||
if len(matches) > 0:
|
||||
logger.error('This OpenSSL library is missing the following required features: ' + ', '.join(matches) + '. PyBitmessage requires OpenSSL 0.9.8b or later with AES, Elliptic Curves (EC), ECDH, and ECDSA enabled.')
|
||||
return False
|
||||
|
|
|
@ -35,7 +35,7 @@ def sign(msg,hexPrivkey):
|
|||
# upgrade PyBitmessage gracefully.
|
||||
# https://github.com/yann2192/pyelliptic/pull/33
|
||||
# More discussion: https://github.com/yann2192/pyelliptic/issues/32
|
||||
return makeCryptor(hexPrivkey).sign(msg, digest_alg=OpenSSL.EVP_ecdsa) # SHA1
|
||||
return makeCryptor(hexPrivkey).sign(msg, digest_alg=OpenSSL.digest_ecdsa_sha1) # SHA1
|
||||
#return makeCryptor(hexPrivkey).sign(msg, digest_alg=OpenSSL.EVP_sha256) # SHA256. We should switch to this eventually.
|
||||
# Verifies with hex public key
|
||||
def verify(msg,sig,hexPubkey):
|
||||
|
@ -44,7 +44,7 @@ def verify(msg,sig,hexPubkey):
|
|||
# of them passes then we will be satisfied. Eventually this can
|
||||
# be simplified and we'll only check with SHA256.
|
||||
try:
|
||||
sigVerifyPassed = makePubCryptor(hexPubkey).verify(sig,msg,digest_alg=OpenSSL.EVP_ecdsa) # old SHA1 algorithm.
|
||||
sigVerifyPassed = makePubCryptor(hexPubkey).verify(sig,msg,digest_alg=OpenSSL.digest_ecdsa_sha1) # old SHA1 algorithm.
|
||||
except:
|
||||
sigVerifyPassed = False
|
||||
if sigVerifyPassed:
|
||||
|
|
|
@ -77,5 +77,8 @@ class Cipher:
|
|||
return buff + self.final()
|
||||
|
||||
def __del__(self):
|
||||
if OpenSSL._hexversion > 0x10100000:
|
||||
OpenSSL.EVP_CIPHER_CTX_reset(self.ctx)
|
||||
else:
|
||||
OpenSSL.EVP_CIPHER_CTX_cleanup(self.ctx)
|
||||
OpenSSL.EVP_CIPHER_CTX_free(self.ctx)
|
||||
|
|
|
@ -223,6 +223,9 @@ class ECC:
|
|||
if (OpenSSL.EC_KEY_set_private_key(own_key, own_priv_key)) == 0:
|
||||
raise Exception("[OpenSSL] EC_KEY_set_private_key FAIL ...")
|
||||
|
||||
if OpenSSL._hexversion > 0x10100000:
|
||||
OpenSSL.EC_KEY_set_method(own_key, OpenSSL.EC_KEY_OpenSSL())
|
||||
else:
|
||||
OpenSSL.ECDH_set_method(own_key, OpenSSL.ECDH_OpenSSL())
|
||||
ecdh_keylen = OpenSSL.ECDH_compute_key(
|
||||
ecdh_keybuffer, 32, other_pub_key, own_key, 0)
|
||||
|
@ -299,7 +302,7 @@ class ECC:
|
|||
if privkey is not None:
|
||||
OpenSSL.BN_free(priv_key)
|
||||
|
||||
def sign(self, inputb, digest_alg=OpenSSL.EVP_ecdsa):
|
||||
def sign(self, inputb, digest_alg=OpenSSL.digest_ecdsa_sha1):
|
||||
"""
|
||||
Sign the input with ECDSA method and returns the signature
|
||||
"""
|
||||
|
@ -307,6 +310,9 @@ class ECC:
|
|||
size = len(inputb)
|
||||
buff = OpenSSL.malloc(inputb, size)
|
||||
digest = OpenSSL.malloc(0, 64)
|
||||
if OpenSSL._hexversion > 0x10100000:
|
||||
md_ctx = OpenSSL.EVP_MD_CTX_new()
|
||||
else:
|
||||
md_ctx = OpenSSL.EVP_MD_CTX_create()
|
||||
dgst_len = OpenSSL.pointer(OpenSSL.c_int(0))
|
||||
siglen = OpenSSL.pointer(OpenSSL.c_int(0))
|
||||
|
@ -337,6 +343,9 @@ class ECC:
|
|||
if (OpenSSL.EC_KEY_check_key(key)) == 0:
|
||||
raise Exception("[OpenSSL] EC_KEY_check_key FAIL ...")
|
||||
|
||||
if OpenSSL._hexversion > 0x10100000:
|
||||
OpenSSL.EVP_MD_CTX_new(md_ctx)
|
||||
else:
|
||||
OpenSSL.EVP_MD_CTX_init(md_ctx)
|
||||
OpenSSL.EVP_DigestInit_ex(md_ctx, digest_alg(), None)
|
||||
|
||||
|
@ -356,9 +365,13 @@ class ECC:
|
|||
OpenSSL.BN_free(pub_key_y)
|
||||
OpenSSL.BN_free(priv_key)
|
||||
OpenSSL.EC_POINT_free(pub_key)
|
||||
if OpenSSL._hexversion > 0x10100000:
|
||||
OpenSSL.EVP_MD_CTX_free(md_ctx)
|
||||
else:
|
||||
OpenSSL.EVP_MD_CTX_destroy(md_ctx)
|
||||
pass
|
||||
|
||||
def verify(self, sig, inputb, digest_alg=OpenSSL.EVP_ecdsa):
|
||||
def verify(self, sig, inputb, digest_alg=OpenSSL.digest_ecdsa_sha1):
|
||||
"""
|
||||
Verify the signature with the input and the local public key.
|
||||
Returns a boolean
|
||||
|
@ -368,8 +381,10 @@ class ECC:
|
|||
binputb = OpenSSL.malloc(inputb, len(inputb))
|
||||
digest = OpenSSL.malloc(0, 64)
|
||||
dgst_len = OpenSSL.pointer(OpenSSL.c_int(0))
|
||||
if OpenSSL._hexversion > 0x10100000:
|
||||
md_ctx = OpenSSL.EVP_MD_CTX_new()
|
||||
else:
|
||||
md_ctx = OpenSSL.EVP_MD_CTX_create()
|
||||
|
||||
key = OpenSSL.EC_KEY_new_by_curve_name(self.curve)
|
||||
|
||||
if key == 0:
|
||||
|
@ -390,7 +405,9 @@ class ECC:
|
|||
raise Exception("[OpenSSL] EC_KEY_set_public_key FAIL ...")
|
||||
if (OpenSSL.EC_KEY_check_key(key)) == 0:
|
||||
raise Exception("[OpenSSL] EC_KEY_check_key FAIL ...")
|
||||
|
||||
if OpenSSL._hexversion > 0x10100000:
|
||||
OpenSSL.EVP_MD_CTX_new(md_ctx)
|
||||
else:
|
||||
OpenSSL.EVP_MD_CTX_init(md_ctx)
|
||||
OpenSSL.EVP_DigestInit_ex(md_ctx, digest_alg(), None)
|
||||
if (OpenSSL.EVP_DigestUpdate(md_ctx, binputb, len(inputb))) == 0:
|
||||
|
@ -414,6 +431,9 @@ class ECC:
|
|||
OpenSSL.BN_free(pub_key_x)
|
||||
OpenSSL.BN_free(pub_key_y)
|
||||
OpenSSL.EC_POINT_free(pub_key)
|
||||
if OpenSSL._hexversion > 0x10100000:
|
||||
OpenSSL.EVP_MD_CTX_free(md_ctx)
|
||||
else:
|
||||
OpenSSL.EVP_MD_CTX_destroy(md_ctx)
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -31,6 +31,37 @@ class CipherName:
|
|||
return self._blocksize
|
||||
|
||||
|
||||
def get_version(library):
|
||||
version = None
|
||||
hexversion = None
|
||||
cflags = None
|
||||
try:
|
||||
#OpenSSL 1.1
|
||||
OPENSSL_VERSION = 0
|
||||
OPENSSL_CFLAGS = 1
|
||||
library.OpenSSL_version.argtypes = [ctypes.c_int]
|
||||
library.OpenSSL_version.restype = ctypes.c_char_p
|
||||
version = library.OpenSSL_version(OPENSSL_VERSION)
|
||||
cflags = library.OpenSSL_version(OPENSSL_CFLAGS)
|
||||
library.OpenSSL_version_num.restype = ctypes.c_long
|
||||
hexversion = library.OpenSSL_version_num()
|
||||
except AttributeError:
|
||||
try:
|
||||
#OpenSSL 1.0
|
||||
SSLEAY_VERSION = 0
|
||||
SSLEAY_CFLAGS = 2
|
||||
library.SSLeay.restype = ctypes.c_long
|
||||
library.SSLeay_version.restype = ctypes.c_char_p
|
||||
library.SSLeay_version.argtypes = [ctypes.c_int]
|
||||
version = library.SSLeay_version(SSLEAY_VERSION)
|
||||
cflags = library.SSLeay_version(SSLEAY_CFLAGS)
|
||||
hexversion = library.SSLeay()
|
||||
except AttributeError:
|
||||
#raise NotImplementedError('Cannot determine version of this OpenSSL library.')
|
||||
pass
|
||||
return (version, hexversion, cflags)
|
||||
|
||||
|
||||
class _OpenSSL:
|
||||
"""
|
||||
Wrapper for OpenSSL using ctypes
|
||||
|
@ -40,6 +71,7 @@ class _OpenSSL:
|
|||
Build the wrapper
|
||||
"""
|
||||
self._lib = ctypes.CDLL(library)
|
||||
self._version, self._hexversion, self._cflags = get_version(self._lib)
|
||||
|
||||
self.pointer = ctypes.pointer
|
||||
self.c_int = ctypes.c_int
|
||||
|
@ -138,18 +170,27 @@ class _OpenSSL:
|
|||
self.EC_KEY_set_private_key.argtypes = [ctypes.c_void_p,
|
||||
ctypes.c_void_p]
|
||||
|
||||
if self._hexversion > 0x10100000:
|
||||
self.EC_KEY_OpenSSL = self._lib.EC_KEY_OpenSSL
|
||||
self._lib.EC_KEY_OpenSSL.restype = ctypes.c_void_p
|
||||
self._lib.EC_KEY_OpenSSL.argtypes = []
|
||||
|
||||
self.EC_KEY_set_method = self._lib.EC_KEY_set_method
|
||||
self._lib.EC_KEY_set_method.restype = ctypes.c_int
|
||||
self._lib.EC_KEY_set_method.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
|
||||
else:
|
||||
self.ECDH_OpenSSL = self._lib.ECDH_OpenSSL
|
||||
self._lib.ECDH_OpenSSL.restype = ctypes.c_void_p
|
||||
self._lib.ECDH_OpenSSL.argtypes = []
|
||||
|
||||
self.BN_CTX_new = self._lib.BN_CTX_new
|
||||
self._lib.BN_CTX_new.restype = ctypes.c_void_p
|
||||
self._lib.BN_CTX_new.argtypes = []
|
||||
|
||||
self.ECDH_set_method = self._lib.ECDH_set_method
|
||||
self._lib.ECDH_set_method.restype = ctypes.c_int
|
||||
self._lib.ECDH_set_method.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
|
||||
|
||||
self.BN_CTX_new = self._lib.BN_CTX_new
|
||||
self._lib.BN_CTX_new.restype = ctypes.c_void_p
|
||||
self._lib.BN_CTX_new.argtypes = []
|
||||
|
||||
self.ECDH_compute_key = self._lib.ECDH_compute_key
|
||||
self.ECDH_compute_key.restype = ctypes.c_int
|
||||
self.ECDH_compute_key.argtypes = [ctypes.c_void_p,
|
||||
|
@ -209,6 +250,11 @@ class _OpenSSL:
|
|||
self.EVP_rc4.restype = ctypes.c_void_p
|
||||
self.EVP_rc4.argtypes = []
|
||||
|
||||
if self._hexversion > 0x10100000:
|
||||
self.EVP_CIPHER_CTX_reset = self._lib.EVP_CIPHER_CTX_reset
|
||||
self.EVP_CIPHER_CTX_reset.restype = ctypes.c_int
|
||||
self.EVP_CIPHER_CTX_reset.argtypes = [ctypes.c_void_p]
|
||||
else:
|
||||
self.EVP_CIPHER_CTX_cleanup = self._lib.EVP_CIPHER_CTX_cleanup
|
||||
self.EVP_CIPHER_CTX_cleanup.restype = ctypes.c_int
|
||||
self.EVP_CIPHER_CTX_cleanup.argtypes = [ctypes.c_void_p]
|
||||
|
@ -250,10 +296,6 @@ class _OpenSSL:
|
|||
self.EVP_DigestFinal_ex.argtypes = [ctypes.c_void_p,
|
||||
ctypes.c_void_p, ctypes.c_void_p]
|
||||
|
||||
self.EVP_ecdsa = self._lib.EVP_ecdsa
|
||||
self._lib.EVP_ecdsa.restype = ctypes.c_void_p
|
||||
self._lib.EVP_ecdsa.argtypes = []
|
||||
|
||||
self.ECDSA_sign = self._lib.ECDSA_sign
|
||||
self.ECDSA_sign.restype = ctypes.c_int
|
||||
self.ECDSA_sign.argtypes = [ctypes.c_int, ctypes.c_void_p,
|
||||
|
@ -264,6 +306,25 @@ class _OpenSSL:
|
|||
self.ECDSA_verify.argtypes = [ctypes.c_int, ctypes.c_void_p,
|
||||
ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p]
|
||||
|
||||
if self._hexversion > 0x10100000:
|
||||
self.EVP_MD_CTX_new = self._lib.EVP_MD_CTX_new
|
||||
self.EVP_MD_CTX_new.restype = ctypes.c_void_p
|
||||
self.EVP_MD_CTX_new.argtypes = []
|
||||
|
||||
self.EVP_MD_CTX_reset = self._lib.EVP_MD_CTX_reset
|
||||
self.EVP_MD_CTX_reset.restype = None
|
||||
self.EVP_MD_CTX_reset.argtypes = [ctypes.c_void_p]
|
||||
|
||||
self.EVP_MD_CTX_free = self._lib.EVP_MD_CTX_free
|
||||
self.EVP_MD_CTX_free.restype = None
|
||||
self.EVP_MD_CTX_free.argtypes = [ctypes.c_void_p]
|
||||
|
||||
self.EVP_sha1 = self._lib.EVP_sha1
|
||||
self.EVP_sha1.restype = ctypes.c_void_p
|
||||
self.EVP_sha1.argtypes = []
|
||||
|
||||
self.digest_ecdsa_sha1 = self.EVP_sha1
|
||||
else:
|
||||
self.EVP_MD_CTX_create = self._lib.EVP_MD_CTX_create
|
||||
self.EVP_MD_CTX_create.restype = ctypes.c_void_p
|
||||
self.EVP_MD_CTX_create.argtypes = []
|
||||
|
@ -276,11 +337,16 @@ class _OpenSSL:
|
|||
self.EVP_MD_CTX_destroy.restype = None
|
||||
self.EVP_MD_CTX_destroy.argtypes = [ctypes.c_void_p]
|
||||
|
||||
self.EVP_ecdsa = self._lib.EVP_ecdsa
|
||||
self._lib.EVP_ecdsa.restype = ctypes.c_void_p
|
||||
self._lib.EVP_ecdsa.argtypes = []
|
||||
|
||||
self.digest_ecdsa_sha1 = self.EVP_ecdsa
|
||||
|
||||
self.RAND_bytes = self._lib.RAND_bytes
|
||||
self.RAND_bytes.restype = ctypes.c_int
|
||||
self.RAND_bytes.argtypes = [ctypes.c_void_p, ctypes.c_int]
|
||||
|
||||
|
||||
self.EVP_sha256 = self._lib.EVP_sha256
|
||||
self.EVP_sha256.restype = ctypes.c_void_p
|
||||
self.EVP_sha256.argtypes = []
|
||||
|
@ -437,7 +503,11 @@ def loadOpenSSL():
|
|||
if 'darwin' in sys.platform:
|
||||
libdir.extend([
|
||||
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.dylib'),
|
||||
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.1.0.0.dylib')
|
||||
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.1.1.0.dylib'),
|
||||
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.1.0.2.dylib'),
|
||||
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.1.0.1.dylib'),
|
||||
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.1.0.0.dylib'),
|
||||
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.0.9.8.dylib'),
|
||||
])
|
||||
elif 'win32' in sys.platform or 'win64' in sys.platform:
|
||||
libdir.append(path.join(sys._MEIPASS, 'libeay32.dll'))
|
||||
|
@ -445,8 +515,16 @@ def loadOpenSSL():
|
|||
libdir.extend([
|
||||
path.join(sys._MEIPASS, 'libcrypto.so'),
|
||||
path.join(sys._MEIPASS, 'libssl.so'),
|
||||
path.join(sys._MEIPASS, 'libcrypto.so.1.1.0'),
|
||||
path.join(sys._MEIPASS, 'libssl.so.1.1.0'),
|
||||
path.join(sys._MEIPASS, 'libcrypto.so.1.0.2'),
|
||||
path.join(sys._MEIPASS, 'libssl.so.1.0.2'),
|
||||
path.join(sys._MEIPASS, 'libcrypto.so.1.0.1'),
|
||||
path.join(sys._MEIPASS, 'libssl.so.1.0.1'),
|
||||
path.join(sys._MEIPASS, 'libcrypto.so.1.0.0'),
|
||||
path.join(sys._MEIPASS, 'libssl.so.1.0.0'),
|
||||
path.join(sys._MEIPASS, 'libcrypto.so.0.9.8'),
|
||||
path.join(sys._MEIPASS, 'libssl.so.0.9.8'),
|
||||
])
|
||||
if 'darwin' in sys.platform:
|
||||
libdir.extend(['libcrypto.dylib', '/usr/local/opt/openssl/lib/libcrypto.dylib'])
|
||||
|
@ -455,7 +533,7 @@ def loadOpenSSL():
|
|||
else:
|
||||
libdir.append('libcrypto.so')
|
||||
libdir.append('libssl.so')
|
||||
if 'linux' in sys.platform or 'darwin' in sys.platform or 'freebsd' in sys.platform:
|
||||
if 'linux' in sys.platform or 'darwin' in sys.platform or 'bsd' in sys.platform:
|
||||
libdir.append(find_library('ssl'))
|
||||
elif 'win32' in sys.platform or 'win64' in sys.platform:
|
||||
libdir.append(find_library('libeay32'))
|
||||
|
|
Loading…
Reference in New Issue
Block a user