Update pyelliptic

This commit is contained in:
shortcutme 2017-04-06 23:24:38 +02:00
parent 929432d469
commit ccfcdbc6ca
No known key found for this signature in database
GPG Key ID: 5B63BAE6CB9613AE
4 changed files with 134 additions and 54 deletions

View File

@ -4,7 +4,7 @@
# Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com> # Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com>
# See LICENSE for details. # See LICENSE for details.
from .openssl import OpenSSL from pyelliptic.openssl import OpenSSL
class Cipher: class Cipher:
@ -77,5 +77,8 @@ class Cipher:
return buff + self.final() return buff + self.final()
def __del__(self): def __del__(self):
OpenSSL.EVP_CIPHER_CTX_cleanup(self.ctx) if OpenSSL._hexversion > 0x10100000 and not OpenSSL._libreSSL:
OpenSSL.EVP_CIPHER_CTX_reset(self.ctx)
else:
OpenSSL.EVP_CIPHER_CTX_cleanup(self.ctx)
OpenSSL.EVP_CIPHER_CTX_free(self.ctx) OpenSSL.EVP_CIPHER_CTX_free(self.ctx)

View File

@ -5,9 +5,9 @@
# See LICENSE for details. # See LICENSE for details.
from hashlib import sha512 from hashlib import sha512
from .openssl import OpenSSL from pyelliptic.openssl import OpenSSL
from .cipher import Cipher from pyelliptic.cipher import Cipher
from .hash import hmac_sha256, equals from pyelliptic.hash import hmac_sha256, equals
from struct import pack, unpack from struct import pack, unpack
@ -223,7 +223,10 @@ class ECC:
if (OpenSSL.EC_KEY_set_private_key(own_key, own_priv_key)) == 0: if (OpenSSL.EC_KEY_set_private_key(own_key, own_priv_key)) == 0:
raise Exception("[OpenSSL] EC_KEY_set_private_key FAIL ...") raise Exception("[OpenSSL] EC_KEY_set_private_key FAIL ...")
OpenSSL.ECDH_set_method(own_key, OpenSSL.ECDH_OpenSSL()) if OpenSSL._hexversion > 0x10100000 and not OpenSSL._libreSSL:
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_keylen = OpenSSL.ECDH_compute_key(
ecdh_keybuffer, 32, other_pub_key, own_key, 0) ecdh_keybuffer, 32, other_pub_key, own_key, 0)
@ -299,7 +302,7 @@ class ECC:
if privkey is not None: if privkey is not None:
OpenSSL.BN_free(priv_key) 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 Sign the input with ECDSA method and returns the signature
""" """
@ -307,7 +310,10 @@ class ECC:
size = len(inputb) size = len(inputb)
buff = OpenSSL.malloc(inputb, size) buff = OpenSSL.malloc(inputb, size)
digest = OpenSSL.malloc(0, 64) digest = OpenSSL.malloc(0, 64)
md_ctx = OpenSSL.EVP_MD_CTX_create() if OpenSSL._hexversion > 0x10100000 and not OpenSSL._libreSSL:
md_ctx = OpenSSL.EVP_MD_CTX_new()
else:
md_ctx = OpenSSL.EVP_MD_CTX_create()
dgst_len = OpenSSL.pointer(OpenSSL.c_int(0)) dgst_len = OpenSSL.pointer(OpenSSL.c_int(0))
siglen = OpenSSL.pointer(OpenSSL.c_int(0)) siglen = OpenSSL.pointer(OpenSSL.c_int(0))
sig = OpenSSL.malloc(0, 151) sig = OpenSSL.malloc(0, 151)
@ -337,7 +343,10 @@ class ECC:
if (OpenSSL.EC_KEY_check_key(key)) == 0: if (OpenSSL.EC_KEY_check_key(key)) == 0:
raise Exception("[OpenSSL] EC_KEY_check_key FAIL ...") raise Exception("[OpenSSL] EC_KEY_check_key FAIL ...")
OpenSSL.EVP_MD_CTX_init(md_ctx) if OpenSSL._hexversion > 0x10100000 and not OpenSSL._libreSSL:
OpenSSL.EVP_MD_CTX_new(md_ctx)
else:
OpenSSL.EVP_MD_CTX_init(md_ctx)
OpenSSL.EVP_DigestInit_ex(md_ctx, digest_alg(), None) OpenSSL.EVP_DigestInit_ex(md_ctx, digest_alg(), None)
if (OpenSSL.EVP_DigestUpdate(md_ctx, buff, size)) == 0: if (OpenSSL.EVP_DigestUpdate(md_ctx, buff, size)) == 0:
@ -356,9 +365,13 @@ class ECC:
OpenSSL.BN_free(pub_key_y) OpenSSL.BN_free(pub_key_y)
OpenSSL.BN_free(priv_key) OpenSSL.BN_free(priv_key)
OpenSSL.EC_POINT_free(pub_key) OpenSSL.EC_POINT_free(pub_key)
OpenSSL.EVP_MD_CTX_destroy(md_ctx) if OpenSSL._hexversion > 0x10100000 and not OpenSSL._libreSSL:
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. Verify the signature with the input and the local public key.
Returns a boolean Returns a boolean
@ -368,8 +381,10 @@ class ECC:
binputb = OpenSSL.malloc(inputb, len(inputb)) binputb = OpenSSL.malloc(inputb, len(inputb))
digest = OpenSSL.malloc(0, 64) digest = OpenSSL.malloc(0, 64)
dgst_len = OpenSSL.pointer(OpenSSL.c_int(0)) dgst_len = OpenSSL.pointer(OpenSSL.c_int(0))
md_ctx = OpenSSL.EVP_MD_CTX_create() if OpenSSL._hexversion > 0x10100000 and not OpenSSL._libreSSL:
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) key = OpenSSL.EC_KEY_new_by_curve_name(self.curve)
if key == 0: if key == 0:
@ -390,8 +405,10 @@ class ECC:
raise Exception("[OpenSSL] EC_KEY_set_public_key FAIL ...") raise Exception("[OpenSSL] EC_KEY_set_public_key FAIL ...")
if (OpenSSL.EC_KEY_check_key(key)) == 0: if (OpenSSL.EC_KEY_check_key(key)) == 0:
raise Exception("[OpenSSL] EC_KEY_check_key FAIL ...") raise Exception("[OpenSSL] EC_KEY_check_key FAIL ...")
if OpenSSL._hexversion > 0x10100000 and not OpenSSL._libreSSL:
OpenSSL.EVP_MD_CTX_init(md_ctx) OpenSSL.EVP_MD_CTX_new(md_ctx)
else:
OpenSSL.EVP_MD_CTX_init(md_ctx)
OpenSSL.EVP_DigestInit_ex(md_ctx, digest_alg(), None) OpenSSL.EVP_DigestInit_ex(md_ctx, digest_alg(), None)
if (OpenSSL.EVP_DigestUpdate(md_ctx, binputb, len(inputb))) == 0: if (OpenSSL.EVP_DigestUpdate(md_ctx, binputb, len(inputb))) == 0:
raise Exception("[OpenSSL] EVP_DigestUpdate FAIL ...") raise Exception("[OpenSSL] EVP_DigestUpdate FAIL ...")
@ -414,7 +431,10 @@ class ECC:
OpenSSL.BN_free(pub_key_x) OpenSSL.BN_free(pub_key_x)
OpenSSL.BN_free(pub_key_y) OpenSSL.BN_free(pub_key_y)
OpenSSL.EC_POINT_free(pub_key) OpenSSL.EC_POINT_free(pub_key)
OpenSSL.EVP_MD_CTX_destroy(md_ctx) if OpenSSL._hexversion > 0x10100000 and not OpenSSL._libreSSL:
OpenSSL.EVP_MD_CTX_free(md_ctx)
else:
OpenSSL.EVP_MD_CTX_destroy(md_ctx)
@staticmethod @staticmethod
def encrypt(data, pubkey, ephemcurve=None, ciphername='aes-256-cbc'): def encrypt(data, pubkey, ephemcurve=None, ciphername='aes-256-cbc'):

View File

@ -4,7 +4,7 @@
# Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com> # Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com>
# See LICENSE for details. # See LICENSE for details.
from .openssl import OpenSSL from pyelliptic.openssl import OpenSSL
# For python3 # For python3

View File

@ -8,8 +8,6 @@
import sys import sys
import ctypes import ctypes
import logging
import os
OpenSSL = None OpenSSL = None
@ -33,6 +31,37 @@ class CipherName:
return self._blocksize 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: class _OpenSSL:
""" """
Wrapper for OpenSSL using ctypes Wrapper for OpenSSL using ctypes
@ -42,6 +71,8 @@ class _OpenSSL:
Build the wrapper Build the wrapper
""" """
self._lib = ctypes.CDLL(library) self._lib = ctypes.CDLL(library)
self._version, self._hexversion, self._cflags = get_version(self._lib)
self._libreSSL = self._version.startswith("LibreSSL")
self.pointer = ctypes.pointer self.pointer = ctypes.pointer
self.c_int = ctypes.c_int self.c_int = ctypes.c_int
@ -140,18 +171,27 @@ class _OpenSSL:
self.EC_KEY_set_private_key.argtypes = [ctypes.c_void_p, self.EC_KEY_set_private_key.argtypes = [ctypes.c_void_p,
ctypes.c_void_p] ctypes.c_void_p]
self.ECDH_OpenSSL = self._lib.ECDH_OpenSSL if self._hexversion >= 0x10100000 and not self._libreSSL:
self._lib.ECDH_OpenSSL.restype = ctypes.c_void_p self.EC_KEY_OpenSSL = self._lib.EC_KEY_OpenSSL
self._lib.ECDH_OpenSSL.argtypes = [] 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.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.BN_CTX_new = self._lib.BN_CTX_new
self._lib.BN_CTX_new.restype = ctypes.c_void_p self._lib.BN_CTX_new.restype = ctypes.c_void_p
self._lib.BN_CTX_new.argtypes = [] 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.ECDH_compute_key = self._lib.ECDH_compute_key self.ECDH_compute_key = self._lib.ECDH_compute_key
self.ECDH_compute_key.restype = ctypes.c_int self.ECDH_compute_key.restype = ctypes.c_int
self.ECDH_compute_key.argtypes = [ctypes.c_void_p, self.ECDH_compute_key.argtypes = [ctypes.c_void_p,
@ -211,9 +251,14 @@ class _OpenSSL:
self.EVP_rc4.restype = ctypes.c_void_p self.EVP_rc4.restype = ctypes.c_void_p
self.EVP_rc4.argtypes = [] self.EVP_rc4.argtypes = []
self.EVP_CIPHER_CTX_cleanup = self._lib.EVP_CIPHER_CTX_cleanup if self._hexversion >= 0x10100000 and not self._libreSSL:
self.EVP_CIPHER_CTX_cleanup.restype = ctypes.c_int self.EVP_CIPHER_CTX_reset = self._lib.EVP_CIPHER_CTX_reset
self.EVP_CIPHER_CTX_cleanup.argtypes = [ctypes.c_void_p] 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]
self.EVP_CIPHER_CTX_free = self._lib.EVP_CIPHER_CTX_free self.EVP_CIPHER_CTX_free = self._lib.EVP_CIPHER_CTX_free
self.EVP_CIPHER_CTX_free.restype = None self.EVP_CIPHER_CTX_free.restype = None
@ -252,10 +297,6 @@ class _OpenSSL:
self.EVP_DigestFinal_ex.argtypes = [ctypes.c_void_p, self.EVP_DigestFinal_ex.argtypes = [ctypes.c_void_p,
ctypes.c_void_p, 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 = self._lib.ECDSA_sign
self.ECDSA_sign.restype = ctypes.c_int self.ECDSA_sign.restype = ctypes.c_int
self.ECDSA_sign.argtypes = [ctypes.c_int, ctypes.c_void_p, self.ECDSA_sign.argtypes = [ctypes.c_int, ctypes.c_void_p,
@ -266,23 +307,47 @@ class _OpenSSL:
self.ECDSA_verify.argtypes = [ctypes.c_int, ctypes.c_void_p, 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] ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p]
self.EVP_MD_CTX_create = self._lib.EVP_MD_CTX_create if self._hexversion >= 0x10100000 and not self._libreSSL:
self.EVP_MD_CTX_create.restype = ctypes.c_void_p self.EVP_MD_CTX_new = self._lib.EVP_MD_CTX_new
self.EVP_MD_CTX_create.argtypes = [] self.EVP_MD_CTX_new.restype = ctypes.c_void_p
self.EVP_MD_CTX_new.argtypes = []
self.EVP_MD_CTX_init = self._lib.EVP_MD_CTX_init self.EVP_MD_CTX_reset = self._lib.EVP_MD_CTX_reset
self.EVP_MD_CTX_init.restype = None self.EVP_MD_CTX_reset.restype = None
self.EVP_MD_CTX_init.argtypes = [ctypes.c_void_p] self.EVP_MD_CTX_reset.argtypes = [ctypes.c_void_p]
self.EVP_MD_CTX_destroy = self._lib.EVP_MD_CTX_destroy self.EVP_MD_CTX_free = self._lib.EVP_MD_CTX_free
self.EVP_MD_CTX_destroy.restype = None self.EVP_MD_CTX_free.restype = None
self.EVP_MD_CTX_destroy.argtypes = [ctypes.c_void_p] 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 = []
self.EVP_MD_CTX_init = self._lib.EVP_MD_CTX_init
self.EVP_MD_CTX_init.restype = None
self.EVP_MD_CTX_init.argtypes = [ctypes.c_void_p]
self.EVP_MD_CTX_destroy = self._lib.EVP_MD_CTX_destroy
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 = self._lib.RAND_bytes
self.RAND_bytes.restype = ctypes.c_int self.RAND_bytes.restype = ctypes.c_int
self.RAND_bytes.argtypes = [ctypes.c_void_p, ctypes.c_int] self.RAND_bytes.argtypes = [ctypes.c_void_p, ctypes.c_int]
self.EVP_sha256 = self._lib.EVP_sha256 self.EVP_sha256 = self._lib.EVP_sha256
self.EVP_sha256.restype = ctypes.c_void_p self.EVP_sha256.restype = ctypes.c_void_p
self.EVP_sha256.argtypes = [] self.EVP_sha256.argtypes = []
@ -429,8 +494,8 @@ class _OpenSSL:
buffer = self.create_string_buffer(size) buffer = self.create_string_buffer(size)
return buffer return buffer
def loadOpenSSL():
def openLibrary(): import logging
global OpenSSL global OpenSSL
try: try:
if sys.platform.startswith("win"): if sys.platform.startswith("win"):
@ -448,12 +513,4 @@ def openLibrary():
OpenSSL = ssl OpenSSL = ssl
logging.debug("pyelliptic loaded: %s", ssl._lib) logging.debug("pyelliptic loaded: %s", ssl._lib)
loadOpenSSL()
def closeLibrary():
import _ctypes
if "FreeLibrary" in dir(_ctypes):
_ctypes.FreeLibrary(OpenSSL._lib._handle)
else:
_ctypes.dlclose(OpenSSL._lib._handle)
openLibrary()