rev260, Fix SIGSEGV on CentOS and other platforms that dont has secp256k1 support in OpenSSL, SSLBenchmark new psutil support and use cert from data dir
This commit is contained in:
parent
dc791a31ab
commit
0ca0c754e6
3 changed files with 339 additions and 292 deletions
|
@ -4,7 +4,7 @@ import ConfigParser
|
||||||
class Config(object):
|
class Config(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.version = "0.3.1"
|
self.version = "0.3.1"
|
||||||
self.rev = 259
|
self.rev = 260
|
||||||
self.parser = self.createArguments()
|
self.parser = self.createArguments()
|
||||||
argv = sys.argv[:] # Copy command line arguments
|
argv = sys.argv[:] # Copy command line arguments
|
||||||
argv = self.parseConfig(argv) # Add arguments from config file
|
argv = self.parseConfig(argv) # Add arguments from config file
|
||||||
|
|
|
@ -31,7 +31,7 @@ def handle(sock_raw, addr):
|
||||||
break
|
break
|
||||||
elif line == "gotssl\n":
|
elif line == "gotssl\n":
|
||||||
sock.sendall("yes\n")
|
sock.sendall("yes\n")
|
||||||
sock = gevent.ssl.wrap_socket(sock_raw, server_side=True, keyfile='src/Test/testdata/key-rsa.pem', certfile='src/Test/testdata/cert-rsa.pem', ciphers=ciphers)
|
sock = gevent.ssl.wrap_socket(sock_raw, server_side=True, keyfile='data/key-rsa.pem', certfile='data/cert-rsa.pem', ciphers=ciphers)
|
||||||
else:
|
else:
|
||||||
sock.sendall(data)
|
sock.sendall(data)
|
||||||
except Exception, err:
|
except Exception, err:
|
||||||
|
@ -69,7 +69,7 @@ def getData():
|
||||||
#clipher = sock.cipher()
|
#clipher = sock.cipher()
|
||||||
sock.send("gotssl\n")
|
sock.send("gotssl\n")
|
||||||
if sock.recv(128) == "yes\n":
|
if sock.recv(128) == "yes\n":
|
||||||
sock = ssl.wrap_socket(sock, ciphers=ciphers)
|
sock = ssl.wrap_socket(sock, ciphers=ciphers, ssl_version=ssl.PROTOCOL_TLSv1)
|
||||||
sock.do_handshake()
|
sock.do_handshake()
|
||||||
clipher = sock.cipher()
|
clipher = sock.cipher()
|
||||||
|
|
||||||
|
@ -98,8 +98,12 @@ s = time.time()
|
||||||
def info():
|
def info():
|
||||||
import psutil, os
|
import psutil, os
|
||||||
process = psutil.Process(os.getpid())
|
process = psutil.Process(os.getpid())
|
||||||
|
if "memory_info" in dir(process):
|
||||||
|
memory_info = process.memory_info
|
||||||
|
else:
|
||||||
|
memory_info = process.get_memory_info
|
||||||
while 1:
|
while 1:
|
||||||
print total_num, "req", (total_bytes/1024), "kbytes", "transfered in", time.time()-s, "using", clipher, "Mem:", process.get_memory_info()[0] / float(2 ** 20)
|
print total_num, "req", (total_bytes/1024), "kbytes", "transfered in", time.time()-s, "using", clipher, "Mem:", memory_info()[0] / float(2 ** 20)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
gevent.spawn(info)
|
gevent.spawn(info)
|
||||||
|
|
|
@ -12,195 +12,205 @@ import hashlib
|
||||||
import base64
|
import base64
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
|
import sys
|
||||||
addrtype = 0
|
addrtype = 0
|
||||||
|
|
||||||
|
|
||||||
class _OpenSSL:
|
class _OpenSSL:
|
||||||
"""
|
|
||||||
Wrapper for OpenSSL using ctypes
|
|
||||||
"""
|
|
||||||
def __init__(self, library):
|
|
||||||
self.time_opened = time.time()
|
|
||||||
"""
|
|
||||||
Build the wrapper
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
self._lib = ctypes.CDLL(library)
|
|
||||||
except:
|
|
||||||
self._lib = ctypes.cdll.LoadLibrary(library)
|
|
||||||
|
|
||||||
self.pointer = ctypes.pointer
|
"""
|
||||||
self.c_int = ctypes.c_int
|
Wrapper for OpenSSL using ctypes
|
||||||
self.byref = ctypes.byref
|
"""
|
||||||
self.create_string_buffer = ctypes.create_string_buffer
|
|
||||||
|
|
||||||
self.BN_new = self._lib.BN_new
|
def __init__(self, library):
|
||||||
self.BN_new.restype = ctypes.c_void_p
|
self.time_opened = time.time()
|
||||||
self.BN_new.argtypes = []
|
"""
|
||||||
|
Build the wrapper
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
self._lib = ctypes.CDLL(library)
|
||||||
|
except:
|
||||||
|
self._lib = ctypes.cdll.LoadLibrary(library)
|
||||||
|
|
||||||
self.BN_copy = self._lib.BN_copy
|
self.pointer = ctypes.pointer
|
||||||
self.BN_copy.restype = ctypes.c_void_p
|
self.c_int = ctypes.c_int
|
||||||
self.BN_copy.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
|
self.byref = ctypes.byref
|
||||||
|
self.create_string_buffer = ctypes.create_string_buffer
|
||||||
|
|
||||||
self.BN_mul_word = self._lib.BN_mul_word
|
self.BN_new = self._lib.BN_new
|
||||||
self.BN_mul_word.restype = ctypes.c_int
|
self.BN_new.restype = ctypes.c_void_p
|
||||||
self.BN_mul_word.argtypes = [ctypes.c_void_p, ctypes.c_int]
|
self.BN_new.argtypes = []
|
||||||
|
|
||||||
self.BN_set_word = self._lib.BN_set_word
|
self.BN_copy = self._lib.BN_copy
|
||||||
self.BN_set_word.restype = ctypes.c_int
|
self.BN_copy.restype = ctypes.c_void_p
|
||||||
self.BN_set_word.argtypes = [ctypes.c_void_p, ctypes.c_int]
|
self.BN_copy.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
|
||||||
|
|
||||||
self.BN_add = self._lib.BN_add
|
self.BN_mul_word = self._lib.BN_mul_word
|
||||||
self.BN_add.restype = ctypes.c_void_p
|
self.BN_mul_word.restype = ctypes.c_int
|
||||||
self.BN_add.argtypes = [ctypes.c_void_p, ctypes.c_void_p,
|
self.BN_mul_word.argtypes = [ctypes.c_void_p, ctypes.c_int]
|
||||||
ctypes.c_void_p]
|
|
||||||
|
|
||||||
self.BN_mod_sub = self._lib.BN_mod_sub
|
self.BN_set_word = self._lib.BN_set_word
|
||||||
self.BN_mod_sub.restype = ctypes.c_int
|
self.BN_set_word.restype = ctypes.c_int
|
||||||
self.BN_mod_sub.argtypes = [ctypes.c_void_p, ctypes.c_void_p,
|
self.BN_set_word.argtypes = [ctypes.c_void_p, ctypes.c_int]
|
||||||
ctypes.c_void_p,
|
|
||||||
ctypes.c_void_p,
|
|
||||||
ctypes.c_void_p]
|
|
||||||
|
|
||||||
self.BN_mod_mul = self._lib.BN_mod_mul
|
self.BN_add = self._lib.BN_add
|
||||||
self.BN_mod_mul.restype = ctypes.c_int
|
self.BN_add.restype = ctypes.c_void_p
|
||||||
self.BN_mod_mul.argtypes = [ctypes.c_void_p, ctypes.c_void_p,
|
self.BN_add.argtypes = [ctypes.c_void_p, ctypes.c_void_p,
|
||||||
ctypes.c_void_p,
|
ctypes.c_void_p]
|
||||||
ctypes.c_void_p,
|
|
||||||
ctypes.c_void_p]
|
|
||||||
|
|
||||||
self.BN_mod_inverse = self._lib.BN_mod_inverse
|
self.BN_mod_sub = self._lib.BN_mod_sub
|
||||||
self.BN_mod_inverse.restype = ctypes.c_void_p
|
self.BN_mod_sub.restype = ctypes.c_int
|
||||||
self.BN_mod_inverse.argtypes = [ctypes.c_void_p, ctypes.c_void_p,
|
self.BN_mod_sub.argtypes = [ctypes.c_void_p, ctypes.c_void_p,
|
||||||
ctypes.c_void_p,
|
ctypes.c_void_p,
|
||||||
ctypes.c_void_p]
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
self.BN_cmp = self._lib.BN_cmp
|
self.BN_mod_mul = self._lib.BN_mod_mul
|
||||||
self.BN_cmp.restype = ctypes.c_int
|
self.BN_mod_mul.restype = ctypes.c_int
|
||||||
self.BN_cmp.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
|
self.BN_mod_mul.argtypes = [ctypes.c_void_p, ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
self.BN_bn2bin = self._lib.BN_bn2bin
|
self.BN_mod_inverse = self._lib.BN_mod_inverse
|
||||||
self.BN_bn2bin.restype = ctypes.c_int
|
self.BN_mod_inverse.restype = ctypes.c_void_p
|
||||||
self.BN_bn2bin.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
|
self.BN_mod_inverse.argtypes = [ctypes.c_void_p, ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
self.BN_bin2bn = self._lib.BN_bin2bn
|
self.BN_cmp = self._lib.BN_cmp
|
||||||
self.BN_bin2bn.restype = ctypes.c_void_p
|
self.BN_cmp.restype = ctypes.c_int
|
||||||
self.BN_bin2bn.argtypes = [ctypes.c_void_p, ctypes.c_int,
|
self.BN_cmp.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
|
||||||
ctypes.c_void_p]
|
|
||||||
|
|
||||||
self.EC_KEY_new_by_curve_name = self._lib.EC_KEY_new_by_curve_name
|
self.BN_bn2bin = self._lib.BN_bn2bin
|
||||||
self.EC_KEY_new_by_curve_name.restype = ctypes.c_void_p
|
self.BN_bn2bin.restype = ctypes.c_int
|
||||||
self.EC_KEY_new_by_curve_name.argtypes = [ctypes.c_int]
|
self.BN_bn2bin.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
|
||||||
|
|
||||||
self.EC_KEY_get0_group = self._lib.EC_KEY_get0_group
|
self.BN_bin2bn = self._lib.BN_bin2bn
|
||||||
self.EC_KEY_get0_group.restype = ctypes.c_void_p
|
self.BN_bin2bn.restype = ctypes.c_void_p
|
||||||
self.EC_KEY_get0_group.argtypes = [ctypes.c_void_p]
|
self.BN_bin2bn.argtypes = [ctypes.c_void_p, ctypes.c_int,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
self.EC_KEY_set_private_key = self._lib.EC_KEY_set_private_key
|
self.EC_KEY_new_by_curve_name = self._lib.EC_KEY_new_by_curve_name
|
||||||
self.EC_KEY_set_private_key.restype = ctypes.c_int
|
self.EC_KEY_new_by_curve_name.restype = ctypes.c_void_p
|
||||||
self.EC_KEY_set_private_key.argtypes = [ctypes.c_void_p,
|
self.EC_KEY_new_by_curve_name.argtypes = [ctypes.c_int]
|
||||||
ctypes.c_void_p]
|
|
||||||
|
|
||||||
self.EC_KEY_set_public_key = self._lib.EC_KEY_set_public_key
|
self.EC_KEY_get0_group = self._lib.EC_KEY_get0_group
|
||||||
self.EC_KEY_set_public_key.restype = ctypes.c_int
|
self.EC_KEY_get0_group.restype = ctypes.c_void_p
|
||||||
self.EC_KEY_set_public_key.argtypes = [ctypes.c_void_p,
|
self.EC_KEY_get0_group.argtypes = [ctypes.c_void_p]
|
||||||
ctypes.c_void_p]
|
|
||||||
|
|
||||||
self.EC_POINT_set_compressed_coordinates_GFp = self._lib.EC_POINT_set_compressed_coordinates_GFp
|
self.EC_KEY_set_private_key = self._lib.EC_KEY_set_private_key
|
||||||
self.EC_POINT_set_compressed_coordinates_GFp.restype = ctypes.c_int
|
self.EC_KEY_set_private_key.restype = ctypes.c_int
|
||||||
self.EC_POINT_set_compressed_coordinates_GFp.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p]
|
self.EC_KEY_set_private_key.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
self.EC_POINT_new = self._lib.EC_POINT_new
|
self.EC_KEY_set_public_key = self._lib.EC_KEY_set_public_key
|
||||||
self.EC_POINT_new.restype = ctypes.c_void_p
|
self.EC_KEY_set_public_key.restype = ctypes.c_int
|
||||||
self.EC_POINT_new.argtypes = [ctypes.c_void_p]
|
self.EC_KEY_set_public_key.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
self.EC_POINT_free = self._lib.EC_POINT_free
|
self.EC_POINT_set_compressed_coordinates_GFp = self._lib.EC_POINT_set_compressed_coordinates_GFp
|
||||||
self.EC_POINT_free.restype = None
|
self.EC_POINT_set_compressed_coordinates_GFp.restype = ctypes.c_int
|
||||||
self.EC_POINT_free.argtypes = [ctypes.c_void_p]
|
self.EC_POINT_set_compressed_coordinates_GFp.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p]
|
||||||
|
|
||||||
self.EC_GROUP_get_order = self._lib.EC_GROUP_get_order
|
self.EC_POINT_new = self._lib.EC_POINT_new
|
||||||
self.EC_GROUP_get_order.restype = ctypes.c_void_p
|
self.EC_POINT_new.restype = ctypes.c_void_p
|
||||||
self.EC_GROUP_get_order.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
|
self.EC_POINT_new.argtypes = [ctypes.c_void_p]
|
||||||
|
|
||||||
self.EC_GROUP_get_degree = self._lib.EC_GROUP_get_degree
|
self.EC_POINT_free = self._lib.EC_POINT_free
|
||||||
self.EC_GROUP_get_degree.restype = ctypes.c_void_p
|
self.EC_POINT_free.restype = None
|
||||||
self.EC_GROUP_get_degree.argtypes = [ctypes.c_void_p]
|
self.EC_POINT_free.argtypes = [ctypes.c_void_p]
|
||||||
|
|
||||||
self.EC_GROUP_get_curve_GFp = self._lib.EC_GROUP_get_curve_GFp
|
self.EC_GROUP_get_order = self._lib.EC_GROUP_get_order
|
||||||
self.EC_GROUP_get_curve_GFp.restype = ctypes.c_void_p
|
self.EC_GROUP_get_order.restype = ctypes.c_void_p
|
||||||
self.EC_GROUP_get_curve_GFp.argtypes = [ctypes.c_void_p,
|
self.EC_GROUP_get_order.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
|
||||||
ctypes.c_void_p,
|
|
||||||
ctypes.c_void_p,
|
|
||||||
ctypes.c_void_p,
|
|
||||||
ctypes.c_void_p]
|
|
||||||
|
|
||||||
self.EC_POINT_mul = self._lib.EC_POINT_mul
|
self.EC_GROUP_get_degree = self._lib.EC_GROUP_get_degree
|
||||||
self.EC_POINT_mul.restype = ctypes.c_int
|
self.EC_GROUP_get_degree.restype = ctypes.c_void_p
|
||||||
self.EC_POINT_mul.argtypes = [ctypes.c_void_p, ctypes.c_void_p,
|
self.EC_GROUP_get_degree.argtypes = [ctypes.c_void_p]
|
||||||
ctypes.c_void_p, ctypes.c_void_p,
|
|
||||||
ctypes.c_void_p, ctypes.c_void_p]
|
|
||||||
|
|
||||||
self.EC_KEY_set_private_key = self._lib.EC_KEY_set_private_key
|
self.EC_GROUP_get_curve_GFp = self._lib.EC_GROUP_get_curve_GFp
|
||||||
self.EC_KEY_set_private_key.restype = ctypes.c_int
|
self.EC_GROUP_get_curve_GFp.restype = ctypes.c_void_p
|
||||||
self.EC_KEY_set_private_key.argtypes = [ctypes.c_void_p,
|
self.EC_GROUP_get_curve_GFp.argtypes = [ctypes.c_void_p,
|
||||||
ctypes.c_void_p]
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
self.EC_KEY_set_conv_form = self._lib.EC_KEY_set_conv_form
|
self.EC_POINT_mul = self._lib.EC_POINT_mul
|
||||||
self.EC_KEY_set_conv_form.restype = None
|
self.EC_POINT_mul.restype = ctypes.c_int
|
||||||
self.EC_KEY_set_conv_form.argtypes = [ctypes.c_void_p,
|
self.EC_POINT_mul.argtypes = [ctypes.c_void_p, ctypes.c_void_p,
|
||||||
ctypes.c_int]
|
ctypes.c_void_p, ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p, ctypes.c_void_p]
|
||||||
|
|
||||||
self.BN_CTX_new = self._lib.BN_CTX_new
|
self.EC_KEY_set_private_key = self._lib.EC_KEY_set_private_key
|
||||||
self._lib.BN_CTX_new.restype = ctypes.c_void_p
|
self.EC_KEY_set_private_key.restype = ctypes.c_int
|
||||||
self._lib.BN_CTX_new.argtypes = []
|
self.EC_KEY_set_private_key.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
self.BN_CTX_start = self._lib.BN_CTX_start
|
self.EC_KEY_set_conv_form = self._lib.EC_KEY_set_conv_form
|
||||||
self._lib.BN_CTX_start.restype = ctypes.c_void_p
|
self.EC_KEY_set_conv_form.restype = None
|
||||||
self._lib.BN_CTX_start.argtypes = [ctypes.c_void_p]
|
self.EC_KEY_set_conv_form.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_int]
|
||||||
|
|
||||||
self.BN_CTX_get = self._lib.BN_CTX_get
|
self.BN_CTX_new = self._lib.BN_CTX_new
|
||||||
self._lib.BN_CTX_get.restype = ctypes.c_void_p
|
self._lib.BN_CTX_new.restype = ctypes.c_void_p
|
||||||
self._lib.BN_CTX_get.argtypes = [ctypes.c_void_p]
|
self._lib.BN_CTX_new.argtypes = []
|
||||||
|
|
||||||
self.ECDSA_sign = self._lib.ECDSA_sign
|
self.BN_CTX_start = self._lib.BN_CTX_start
|
||||||
self.ECDSA_sign.restype = ctypes.c_int
|
self._lib.BN_CTX_start.restype = ctypes.c_void_p
|
||||||
self.ECDSA_sign.argtypes = [ctypes.c_int, ctypes.c_void_p,
|
self._lib.BN_CTX_start.argtypes = [ctypes.c_void_p]
|
||||||
ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
|
|
||||||
|
|
||||||
self.ECDSA_verify = self._lib.ECDSA_verify
|
self.BN_CTX_get = self._lib.BN_CTX_get
|
||||||
self.ECDSA_verify.restype = ctypes.c_int
|
self._lib.BN_CTX_get.restype = ctypes.c_void_p
|
||||||
self.ECDSA_verify.argtypes = [ctypes.c_int, ctypes.c_void_p,
|
self._lib.BN_CTX_get.argtypes = [ctypes.c_void_p]
|
||||||
ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p]
|
|
||||||
|
|
||||||
self.i2o_ECPublicKey = self._lib.i2o_ECPublicKey
|
self.ECDSA_sign = self._lib.ECDSA_sign
|
||||||
self.i2o_ECPublicKey.restype = ctypes.c_void_p
|
self.ECDSA_sign.restype = ctypes.c_int
|
||||||
self.i2o_ECPublicKey.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
|
self.ECDSA_sign.argtypes = [ctypes.c_int, ctypes.c_void_p,
|
||||||
|
ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
|
||||||
|
|
||||||
self.BN_CTX_free = self._lib.BN_CTX_free
|
self.ECDSA_verify = self._lib.ECDSA_verify
|
||||||
self.BN_CTX_free.restype = None
|
self.ECDSA_verify.restype = ctypes.c_int
|
||||||
self.BN_CTX_free.argtypes = [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]
|
||||||
|
|
||||||
self.EC_POINT_free = self._lib.EC_POINT_free
|
self.i2o_ECPublicKey = self._lib.i2o_ECPublicKey
|
||||||
self.EC_POINT_free.restype = None
|
self.i2o_ECPublicKey.restype = ctypes.c_void_p
|
||||||
self.EC_POINT_free.argtypes = [ctypes.c_void_p]
|
self.i2o_ECPublicKey.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
|
||||||
|
|
||||||
|
self.BN_CTX_free = self._lib.BN_CTX_free
|
||||||
|
self.BN_CTX_free.restype = None
|
||||||
|
self.BN_CTX_free.argtypes = [ctypes.c_void_p]
|
||||||
|
|
||||||
|
self.EC_POINT_free = self._lib.EC_POINT_free
|
||||||
|
self.EC_POINT_free.restype = None
|
||||||
|
self.EC_POINT_free.argtypes = [ctypes.c_void_p]
|
||||||
|
|
||||||
|
ssl = None
|
||||||
|
|
||||||
|
|
||||||
def openLibrary():
|
def openLibrary():
|
||||||
global ssl
|
global ssl
|
||||||
try:
|
try:
|
||||||
ssl = _OpenSSL("src/lib/opensslVerify/libeay32.dll")
|
if sys.platform.startswith("win"):
|
||||||
except:
|
ssl = _OpenSSL("src/lib/opensslVerify/libeay32.dll")
|
||||||
ssl = _OpenSSL(ctypes.util.find_library('ssl') or ctypes.util.find_library('crypto') or 'libeay32')
|
else: # Try to use self-compiled first
|
||||||
|
ssl = _OpenSSL("/usr/local/ssl/lib/libcrypto.so")
|
||||||
|
except:
|
||||||
|
ssl = _OpenSSL(ctypes.util.find_library('ssl') or ctypes.util.find_library('crypto') or 'libeay32')
|
||||||
|
|
||||||
openLibrary()
|
openLibrary()
|
||||||
openssl_version = "%.9X" % ssl._lib.SSLeay()
|
openssl_version = "%.9X" % ssl._lib.SSLeay()
|
||||||
|
|
||||||
NID_secp256k1 = 714
|
NID_secp256k1 = 714
|
||||||
|
|
||||||
def check_result (val, func, args):
|
|
||||||
if val == 0:
|
def check_result(val, func, args):
|
||||||
raise ValueError
|
if val == 0:
|
||||||
else:
|
raise ValueError
|
||||||
return ctypes.c_void_p (val)
|
else:
|
||||||
|
return ctypes.c_void_p(val)
|
||||||
|
|
||||||
ssl.EC_KEY_new_by_curve_name.restype = ctypes.c_void_p
|
ssl.EC_KEY_new_by_curve_name.restype = ctypes.c_void_p
|
||||||
ssl.EC_KEY_new_by_curve_name.errcheck = check_result
|
ssl.EC_KEY_new_by_curve_name.errcheck = check_result
|
||||||
|
@ -211,193 +221,226 @@ POINT_CONVERSION_UNCOMPRESSED = 4
|
||||||
__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
||||||
__b58base = len(__b58chars)
|
__b58base = len(__b58chars)
|
||||||
|
|
||||||
|
|
||||||
def b58encode(v):
|
def b58encode(v):
|
||||||
""" encode v, which is a string of bytes, to base58.
|
""" encode v, which is a string of bytes, to base58.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
long_value = 0L
|
long_value = 0L
|
||||||
for (i, c) in enumerate(v[::-1]):
|
for (i, c) in enumerate(v[::-1]):
|
||||||
long_value += (256**i) * ord(c)
|
long_value += (256 ** i) * ord(c)
|
||||||
|
|
||||||
result = ''
|
result = ''
|
||||||
while long_value >= __b58base:
|
while long_value >= __b58base:
|
||||||
div, mod = divmod(long_value, __b58base)
|
div, mod = divmod(long_value, __b58base)
|
||||||
result = __b58chars[mod] + result
|
result = __b58chars[mod] + result
|
||||||
long_value = div
|
long_value = div
|
||||||
result = __b58chars[long_value] + result
|
result = __b58chars[long_value] + result
|
||||||
|
|
||||||
# Bitcoin does a little leading-zero-compression:
|
# Bitcoin does a little leading-zero-compression:
|
||||||
# leading 0-bytes in the input become leading-1s
|
# leading 0-bytes in the input become leading-1s
|
||||||
nPad = 0
|
nPad = 0
|
||||||
for c in v:
|
for c in v:
|
||||||
if c == '\0': nPad += 1
|
if c == '\0':
|
||||||
else: break
|
nPad += 1
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
return (__b58chars[0] * nPad) + result
|
||||||
|
|
||||||
return (__b58chars[0]*nPad) + result
|
|
||||||
|
|
||||||
def hash_160(public_key):
|
def hash_160(public_key):
|
||||||
md = hashlib.new('ripemd160')
|
md = hashlib.new('ripemd160')
|
||||||
md.update(hashlib.sha256(public_key).digest())
|
md.update(hashlib.sha256(public_key).digest())
|
||||||
return md.digest()
|
return md.digest()
|
||||||
|
|
||||||
|
|
||||||
def hash_160_to_bc_address(h160):
|
def hash_160_to_bc_address(h160):
|
||||||
vh160 = chr(addrtype) + h160
|
vh160 = chr(addrtype) + h160
|
||||||
h = Hash(vh160)
|
h = Hash(vh160)
|
||||||
addr = vh160 + h[0:4]
|
addr = vh160 + h[0:4]
|
||||||
return b58encode(addr)
|
return b58encode(addr)
|
||||||
|
|
||||||
|
|
||||||
def public_key_to_bc_address(public_key):
|
def public_key_to_bc_address(public_key):
|
||||||
h160 = hash_160(public_key)
|
h160 = hash_160(public_key)
|
||||||
return hash_160_to_bc_address(h160)
|
return hash_160_to_bc_address(h160)
|
||||||
|
|
||||||
|
|
||||||
def encode(val, base, minlen=0):
|
def encode(val, base, minlen=0):
|
||||||
base, minlen = int(base), int(minlen)
|
base, minlen = int(base), int(minlen)
|
||||||
code_string = ''.join([chr(x) for x in range(256)])
|
code_string = ''.join([chr(x) for x in range(256)])
|
||||||
result = ""
|
result = ""
|
||||||
while val > 0:
|
while val > 0:
|
||||||
result = code_string[val % base] + result
|
result = code_string[val % base] + result
|
||||||
val //= base
|
val //= base
|
||||||
return code_string[0] * max(minlen - len(result), 0) + result
|
return code_string[0] * max(minlen - len(result), 0) + result
|
||||||
|
|
||||||
|
|
||||||
def num_to_var_int(x):
|
def num_to_var_int(x):
|
||||||
x = int(x)
|
x = int(x)
|
||||||
if x < 253: return chr(x)
|
if x < 253:
|
||||||
elif x < 65536: return chr(253)+encode(x, 256, 2)[::-1]
|
return chr(x)
|
||||||
elif x < 4294967296: return chr(254) + encode(x, 256, 4)[::-1]
|
elif x < 65536:
|
||||||
else: return chr(255) + encode(x, 256, 8)[::-1]
|
return chr(253) + encode(x, 256, 2)[::-1]
|
||||||
|
elif x < 4294967296:
|
||||||
|
return chr(254) + encode(x, 256, 4)[::-1]
|
||||||
|
else:
|
||||||
|
return chr(255) + encode(x, 256, 8)[::-1]
|
||||||
|
|
||||||
|
|
||||||
def msg_magic(message):
|
def msg_magic(message):
|
||||||
return "\x18Bitcoin Signed Message:\n" + num_to_var_int( len(message) ) + message
|
return "\x18Bitcoin Signed Message:\n" + num_to_var_int(len(message)) + message
|
||||||
|
|
||||||
|
|
||||||
def get_address(eckey):
|
def get_address(eckey):
|
||||||
size = ssl.i2o_ECPublicKey (eckey, 0)
|
size = ssl.i2o_ECPublicKey(eckey, 0)
|
||||||
mb = ctypes.create_string_buffer (size)
|
mb = ctypes.create_string_buffer(size)
|
||||||
ssl.i2o_ECPublicKey (eckey, ctypes.byref (ctypes.pointer (mb)))
|
ssl.i2o_ECPublicKey(eckey, ctypes.byref(ctypes.pointer(mb)))
|
||||||
return public_key_to_bc_address(mb.raw)
|
return public_key_to_bc_address(mb.raw)
|
||||||
|
|
||||||
|
|
||||||
def Hash(data):
|
def Hash(data):
|
||||||
return hashlib.sha256(hashlib.sha256(data).digest()).digest()
|
return hashlib.sha256(hashlib.sha256(data).digest()).digest()
|
||||||
|
|
||||||
|
|
||||||
def bx(bn, size=32):
|
def bx(bn, size=32):
|
||||||
b = ctypes.create_string_buffer(size)
|
b = ctypes.create_string_buffer(size)
|
||||||
ssl.BN_bn2bin(bn, b);
|
ssl.BN_bn2bin(bn, b)
|
||||||
return b.raw.encode('hex')
|
return b.raw.encode('hex')
|
||||||
|
|
||||||
|
|
||||||
def verify_message(address, signature, message):
|
def verify_message(address, signature, message):
|
||||||
pkey = ssl.EC_KEY_new_by_curve_name(NID_secp256k1)
|
pkey = ssl.EC_KEY_new_by_curve_name(NID_secp256k1)
|
||||||
eckey = SetCompactSignature(pkey, Hash(msg_magic(message)), signature)
|
eckey = SetCompactSignature(pkey, Hash(msg_magic(message)), signature)
|
||||||
addr = get_address(eckey)
|
addr = get_address(eckey)
|
||||||
return (address == addr)
|
return (address == addr)
|
||||||
|
|
||||||
|
|
||||||
def SetCompactSignature(pkey, hash, signature):
|
def SetCompactSignature(pkey, hash, signature):
|
||||||
sig = base64.b64decode(signature)
|
sig = base64.b64decode(signature)
|
||||||
if len(sig) != 65:
|
if len(sig) != 65:
|
||||||
raise BaseException("Wrong encoding")
|
raise BaseException("Wrong encoding")
|
||||||
nV = ord(sig[0])
|
nV = ord(sig[0])
|
||||||
if nV < 27 or nV >= 35:
|
if nV < 27 or nV >= 35:
|
||||||
return False
|
return False
|
||||||
if nV >= 31:
|
if nV >= 31:
|
||||||
ssl.EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED)
|
ssl.EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED)
|
||||||
nV -= 4
|
nV -= 4
|
||||||
r = ssl.BN_bin2bn (sig[1:33], 32, None)
|
r = ssl.BN_bin2bn(sig[1:33], 32, None)
|
||||||
s = ssl.BN_bin2bn (sig[33:], 32, None)
|
s = ssl.BN_bin2bn(sig[33:], 32, None)
|
||||||
eckey = ECDSA_SIG_recover_key_GFp(pkey, r, s, hash, len(hash), nV - 27,
|
eckey = ECDSA_SIG_recover_key_GFp(pkey, r, s, hash, len(hash), nV - 27,
|
||||||
False);
|
False)
|
||||||
return eckey
|
return eckey
|
||||||
|
|
||||||
|
|
||||||
def ECDSA_SIG_recover_key_GFp(eckey, r, s, msg, msglen, recid, check):
|
def ECDSA_SIG_recover_key_GFp(eckey, r, s, msg, msglen, recid, check):
|
||||||
n = 0
|
n = 0
|
||||||
i = recid / 2
|
i = recid / 2
|
||||||
ctx = R = O = Q = None
|
ctx = R = O = Q = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
group = ssl.EC_KEY_get0_group(eckey)
|
group = ssl.EC_KEY_get0_group(eckey)
|
||||||
ctx = ssl.BN_CTX_new()
|
ctx = ssl.BN_CTX_new()
|
||||||
ssl.BN_CTX_start(ctx)
|
ssl.BN_CTX_start(ctx)
|
||||||
order = ssl.BN_CTX_get(ctx)
|
order = ssl.BN_CTX_get(ctx)
|
||||||
ssl.EC_GROUP_get_order(group, order, ctx)
|
ssl.EC_GROUP_get_order(group, order, ctx)
|
||||||
x = ssl.BN_CTX_get(ctx)
|
x = ssl.BN_CTX_get(ctx)
|
||||||
ssl.BN_copy(x, order);
|
ssl.BN_copy(x, order)
|
||||||
ssl.BN_mul_word(x, i);
|
ssl.BN_mul_word(x, i)
|
||||||
ssl.BN_add(x, x, r)
|
ssl.BN_add(x, x, r)
|
||||||
field = ssl.BN_CTX_get(ctx)
|
field = ssl.BN_CTX_get(ctx)
|
||||||
ssl.EC_GROUP_get_curve_GFp(group, field, None, None, ctx)
|
ssl.EC_GROUP_get_curve_GFp(group, field, None, None, ctx)
|
||||||
|
|
||||||
if (ssl.BN_cmp(x, field) >= 0):
|
if (ssl.BN_cmp(x, field) >= 0):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
R = ssl.EC_POINT_new(group)
|
R = ssl.EC_POINT_new(group)
|
||||||
ssl.EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)
|
ssl.EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)
|
||||||
|
|
||||||
if check:
|
if check:
|
||||||
O = ssl.EC_POINT_new(group)
|
O = ssl.EC_POINT_new(group)
|
||||||
ssl.EC_POINT_mul(group, O, None, R, order, ctx)
|
ssl.EC_POINT_mul(group, O, None, R, order, ctx)
|
||||||
if ssl.EC_POINT_is_at_infinity(group, O):
|
if ssl.EC_POINT_is_at_infinity(group, O):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
Q = ssl.EC_POINT_new(group)
|
Q = ssl.EC_POINT_new(group)
|
||||||
n = ssl.EC_GROUP_get_degree(group)
|
n = ssl.EC_GROUP_get_degree(group)
|
||||||
e = ssl.BN_CTX_get(ctx)
|
e = ssl.BN_CTX_get(ctx)
|
||||||
ssl.BN_bin2bn(msg, msglen, e)
|
ssl.BN_bin2bn(msg, msglen, e)
|
||||||
if 8 * msglen > n: ssl.BN_rshift(e, e, 8 - (n & 7))
|
if 8 * msglen > n:
|
||||||
|
ssl.BN_rshift(e, e, 8 - (n & 7))
|
||||||
|
|
||||||
|
zero = ssl.BN_CTX_get(ctx)
|
||||||
|
ssl.BN_set_word(zero, 0)
|
||||||
|
ssl.BN_mod_sub(e, zero, e, order, ctx)
|
||||||
|
rr = ssl.BN_CTX_get(ctx)
|
||||||
|
ssl.BN_mod_inverse(rr, r, order, ctx)
|
||||||
|
sor = ssl.BN_CTX_get(ctx)
|
||||||
|
ssl.BN_mod_mul(sor, s, rr, order, ctx)
|
||||||
|
eor = ssl.BN_CTX_get(ctx)
|
||||||
|
ssl.BN_mod_mul(eor, e, rr, order, ctx)
|
||||||
|
ssl.EC_POINT_mul(group, Q, eor, R, sor, ctx)
|
||||||
|
ssl.EC_KEY_set_public_key(eckey, Q)
|
||||||
|
return eckey
|
||||||
|
finally:
|
||||||
|
if ctx:
|
||||||
|
ssl.BN_CTX_free(ctx)
|
||||||
|
if R:
|
||||||
|
ssl.EC_POINT_free(R)
|
||||||
|
if O:
|
||||||
|
ssl.EC_POINT_free(O)
|
||||||
|
if Q:
|
||||||
|
ssl.EC_POINT_free(Q)
|
||||||
|
|
||||||
zero = ssl.BN_CTX_get(ctx)
|
|
||||||
ssl.BN_set_word(zero, 0)
|
|
||||||
ssl.BN_mod_sub(e, zero, e, order, ctx)
|
|
||||||
rr = ssl.BN_CTX_get(ctx);
|
|
||||||
ssl.BN_mod_inverse(rr, r, order, ctx)
|
|
||||||
sor = ssl.BN_CTX_get(ctx)
|
|
||||||
ssl.BN_mod_mul(sor, s, rr, order, ctx)
|
|
||||||
eor = ssl.BN_CTX_get(ctx)
|
|
||||||
ssl.BN_mod_mul(eor, e, rr, order, ctx)
|
|
||||||
ssl.EC_POINT_mul(group, Q, eor, R, sor, ctx)
|
|
||||||
ssl.EC_KEY_set_public_key(eckey, Q)
|
|
||||||
return eckey
|
|
||||||
finally:
|
|
||||||
if ctx: ssl.BN_CTX_free(ctx)
|
|
||||||
if R: ssl.EC_POINT_free(R)
|
|
||||||
if O: ssl.EC_POINT_free(O)
|
|
||||||
if Q: ssl.EC_POINT_free(Q)
|
|
||||||
|
|
||||||
def closeLibrary():
|
def closeLibrary():
|
||||||
import _ctypes
|
import _ctypes
|
||||||
if "FreeLibrary" in dir(_ctypes):
|
if "FreeLibrary" in dir(_ctypes):
|
||||||
_ctypes.FreeLibrary(ssl._lib._handle)
|
_ctypes.FreeLibrary(ssl._lib._handle)
|
||||||
else:
|
else:
|
||||||
_ctypes.dlclose(ssl._lib._handle)
|
_ctypes.dlclose(ssl._lib._handle)
|
||||||
|
|
||||||
|
|
||||||
def getMessagePubkey(message, sig):
|
def getMessagePubkey(message, sig):
|
||||||
pkey = ssl.EC_KEY_new_by_curve_name(NID_secp256k1)
|
pkey = ssl.EC_KEY_new_by_curve_name(NID_secp256k1)
|
||||||
eckey = SetCompactSignature(pkey, Hash(msg_magic(message)), sig)
|
if not pkey.value:
|
||||||
size = ssl.i2o_ECPublicKey (eckey, 0)
|
raise Exception(
|
||||||
mb = ctypes.create_string_buffer (size)
|
"OpenSSL %s (%s) EC_KEY_new_by_curve_name failed: %s, probably your OpenSSL lib does not support secp256k1 elliptic curve. Please check: https://github.com/HelloZeroNet/ZeroNet/issues/132" %
|
||||||
ssl.i2o_ECPublicKey (eckey, ctypes.byref (ctypes.pointer (mb)))
|
(openssl_version, ssl._lib._name, pkey.value)
|
||||||
pub = mb.raw
|
)
|
||||||
if time.time()-ssl.time_opened>60*5: # Reopen every 5 min
|
eckey = SetCompactSignature(pkey, Hash(msg_magic(message)), sig)
|
||||||
logging.debug("Reopening OpenSSL...")
|
size = ssl.i2o_ECPublicKey(eckey, 0)
|
||||||
closeLibrary()
|
mb = ctypes.create_string_buffer(size)
|
||||||
openLibrary()
|
ssl.i2o_ECPublicKey(eckey, ctypes.byref(ctypes.pointer(mb)))
|
||||||
return pub
|
pub = mb.raw
|
||||||
|
if time.time() - ssl.time_opened > 60 * 5: # Reopen every 5 min
|
||||||
|
logging.debug("Reopening OpenSSL...")
|
||||||
|
closeLibrary()
|
||||||
|
openLibrary()
|
||||||
|
return pub
|
||||||
|
|
||||||
|
|
||||||
def test():
|
def test():
|
||||||
sign = "HGbib2kv9gm9IJjDt1FXbXFczZi35u0rZR3iPUIt5GglDDCeIQ7v8eYXVNIaLoJRI4URGZrhwmsYQ9aVtRTnTfQ="
|
sign = "HGbib2kv9gm9IJjDt1FXbXFczZi35u0rZR3iPUIt5GglDDCeIQ7v8eYXVNIaLoJRI4URGZrhwmsYQ9aVtRTnTfQ="
|
||||||
pubkey = "044827c756561b8ef6b28b5e53a000805adbf4938ab82e1c2b7f7ea16a0d6face9a509a0a13e794d742210b00581f3e249ebcc705240af2540ea19591091ac1d41"
|
pubkey = "044827c756561b8ef6b28b5e53a000805adbf4938ab82e1c2b7f7ea16a0d6face9a509a0a13e794d742210b00581f3e249ebcc705240af2540ea19591091ac1d41"
|
||||||
assert getMessagePubkey("hello", sign).encode("hex") == pubkey
|
assert getMessagePubkey("hello", sign).encode("hex") == pubkey
|
||||||
|
|
||||||
test() # Make sure it working right
|
test() # Make sure it working right
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import time, os, sys
|
import time
|
||||||
sys.path.append("..")
|
import os
|
||||||
from pybitcointools import bitcoin as btctools
|
import sys
|
||||||
print "OpenSSL version %s" % openssl_version
|
sys.path.append("..")
|
||||||
priv = "5JsunC55XGVqFQj5kPGK4MWgTL26jKbnPhjnmchSNPo75XXCwtk"
|
from pybitcointools import bitcoin as btctools
|
||||||
address = "1N2XWu5soeppX2qUjvrf81rpdbShKJrjTr"
|
print "OpenSSL version %s" % openssl_version
|
||||||
sign = btctools.ecdsa_sign("hello", priv) # HGbib2kv9gm9IJjDt1FXbXFczZi35u0rZR3iPUIt5GglDDCeIQ7v8eYXVNIaLoJRI4URGZrhwmsYQ9aVtRTnTfQ=
|
priv = "5JsunC55XGVqFQj5kPGK4MWgTL26jKbnPhjnmchSNPo75XXCwtk"
|
||||||
|
address = "1N2XWu5soeppX2qUjvrf81rpdbShKJrjTr"
|
||||||
|
sign = btctools.ecdsa_sign("hello", priv) # HGbib2kv9gm9IJjDt1FXbXFczZi35u0rZR3iPUIt5GglDDCeIQ7v8eYXVNIaLoJRI4URGZrhwmsYQ9aVtRTnTfQ=
|
||||||
|
|
||||||
s = time.time()
|
s = time.time()
|
||||||
for i in range(100):
|
for i in range(100):
|
||||||
pubkey = getMessagePubkey("hello", sign)
|
pubkey = getMessagePubkey("hello", sign)
|
||||||
verified = btctools.pubkey_to_address(pubkey) == address
|
verified = btctools.pubkey_to_address(pubkey) == address
|
||||||
print "100x Verified", verified, time.time()-s
|
print "100x Verified", verified, time.time() - s
|
||||||
|
|
Loading…
Reference in a new issue