Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5109241

Browse filesBrowse files
committed
Merge pull request petertodd#79
3a936ac Fix OpenSSL related crashes on OSX and Arch (Peter Todd)
2 parents 79e5949 + 3a936ac commit 5109241
Copy full SHA for 5109241

File tree

Expand file treeCollapse file tree

1 file changed

+163
-27
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

1 file changed

+163
-27
lines changed
Open diff view settings
Collapse file

‎bitcoin/core/key.py‎

Copy file name to clipboardExpand all lines: bitcoin/core/key.py
+163-27Lines changed: 163 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -27,37 +27,173 @@
2727
if sys.version > '3':
2828
_bchr = lambda x: bytes([x])
2929
_bord = lambda x: x
30-
from io import BytesIO as BytesIO
31-
else:
32-
from cStringIO import StringIO as BytesIO
3330

3431
import bitcoin.core.script
3532

3633
_ssl = ctypes.cdll.LoadLibrary(ctypes.util.find_library('ssl') or 'libeay32')
3734

38-
# this specifies the curve used with ECDSA.
39-
_NID_secp256k1 = 714 # from openssl/obj_mac.h
35+
class OpenSSLException(EnvironmentError):
36+
pass
4037

41-
# test that openssl support secp256k1
42-
if _ssl.EC_KEY_new_by_curve_name(_NID_secp256k1) == 0:
43-
errno = _ssl.ERR_get_error()
44-
errmsg = ctypes.create_string_buffer(120)
45-
_ssl.ERR_error_string_n(errno, errmsg, 120)
46-
raise RuntimeError('openssl error: %s' % errmsg.value)
47-
48-
# Thx to Sam Devlin for the ctypes magic 64-bit fix.
49-
def _check_result (val, func, args):
38+
# Thx to Sam Devlin for the ctypes magic 64-bit fix (FIXME: should this
39+
# be applied to every OpenSSL call whose return type is a pointer?)
40+
def _check_res_void_p(val, func, args): # pylint: disable=unused-argument
5041
if val == 0:
51-
raise ValueError
52-
else:
53-
return ctypes.c_void_p(val)
42+
errno = _ssl.ERR_get_error()
43+
errmsg = ctypes.create_string_buffer(120)
44+
_ssl.ERR_error_string_n(errno, errmsg, 120)
45+
raise OpenSSLException(errno, str(errmsg.value))
46+
47+
return ctypes.c_void_p(val)
48+
49+
_ssl.BN_add.restype = ctypes.c_int
50+
_ssl.BN_add.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
51+
52+
_ssl.BN_bin2bn.restype = ctypes.c_void_p
53+
_ssl.BN_bin2bn.argtypes = [ctypes.c_char_p, ctypes.c_int, ctypes.c_void_p]
54+
55+
_ssl.BN_cmp.restype = ctypes.c_int
56+
_ssl.BN_cmp.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
57+
58+
_ssl.BN_copy.restype = ctypes.c_void_p
59+
_ssl.BN_copy.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
60+
61+
_ssl.BN_free.restype = None
62+
_ssl.BN_free.argtypes = [ctypes.c_void_p]
63+
64+
_ssl.BN_mod_inverse.restype = ctypes.c_void_p
65+
_ssl.BN_mod_inverse.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
66+
67+
_ssl.BN_mod_mul.restype = ctypes.c_int
68+
_ssl.BN_mod_mul.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
69+
70+
_ssl.BN_mod_sub.restype = ctypes.c_int
71+
_ssl.BN_mod_sub.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
72+
73+
_ssl.BN_mul_word.restype = ctypes.c_int
74+
_ssl.BN_mul_word.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
5475

76+
_ssl.BN_new.errcheck = _check_res_void_p
77+
_ssl.BN_new.restype = ctypes.c_void_p
78+
_ssl.BN_new.argtypes = []
79+
80+
_ssl.BN_rshift.restype = ctypes.c_int
81+
_ssl.BN_rshift.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int]
82+
83+
_ssl.BN_rshift1.restype = ctypes.c_int
84+
_ssl.BN_rshift1.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
85+
86+
_ssl.BN_sub.restype = ctypes.c_int
87+
_ssl.BN_sub.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
88+
89+
# _ssl.BN_zero.restype = ctypes.c_int
90+
# _ssl.BN_zero.argtypes = [ctypes.c_void_p]
91+
92+
_ssl.BN_CTX_free.restype = None
93+
_ssl.BN_CTX_free.argtypes = [ctypes.c_void_p]
94+
95+
_ssl.BN_CTX_get.restype = ctypes.c_void_p
96+
_ssl.BN_CTX_get.argtypes = [ctypes.c_void_p]
97+
98+
_ssl.BN_CTX_new.errcheck = _check_res_void_p
99+
_ssl.BN_CTX_new.restype = ctypes.c_void_p
100+
_ssl.BN_CTX_new.argtypes = []
101+
102+
_ssl.EC_GROUP_get_curve_GFp.restype = ctypes.c_int
103+
_ssl.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]
104+
105+
_ssl.EC_GROUP_get_degree.restype = ctypes.c_int
106+
_ssl.EC_GROUP_get_degree.argtypes = [ctypes.c_void_p]
107+
108+
_ssl.EC_GROUP_get_order.restype = ctypes.c_int
109+
_ssl.EC_GROUP_get_order.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
110+
111+
_ssl.EC_KEY_free.restype = None
112+
_ssl.EC_KEY_free.argtypes = [ctypes.c_void_p]
113+
114+
_ssl.EC_KEY_new_by_curve_name.errcheck = _check_res_void_p
55115
_ssl.EC_KEY_new_by_curve_name.restype = ctypes.c_void_p
56-
_ssl.EC_KEY_new_by_curve_name.errcheck = _check_result
116+
_ssl.EC_KEY_new_by_curve_name.argtypes = [ctypes.c_int]
117+
118+
_ssl.EC_KEY_get0_group.restype = ctypes.c_void_p
119+
_ssl.EC_KEY_get0_group.argtypes = [ctypes.c_void_p]
120+
121+
_ssl.EC_KEY_get0_public_key.restype = ctypes.c_void_p
122+
_ssl.EC_KEY_get0_public_key.argtypes = [ctypes.c_void_p]
123+
124+
_ssl.EC_KEY_set_conv_form.restype = None
125+
_ssl.EC_KEY_set_conv_form.argtypes = [ctypes.c_void_p, ctypes.c_int]
126+
127+
_ssl.EC_KEY_set_private_key.restype = ctypes.c_int
128+
_ssl.EC_KEY_set_private_key.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
129+
130+
_ssl.EC_KEY_set_public_key.restype = ctypes.c_int
131+
_ssl.EC_KEY_set_public_key.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
132+
133+
_ssl.EC_POINT_free.restype = None
134+
_ssl.EC_POINT_free.argtypes = [ctypes.c_void_p]
135+
136+
_ssl.EC_POINT_is_at_infinity.restype = ctypes.c_int
137+
_ssl.EC_POINT_is_at_infinity.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
138+
139+
_ssl.EC_POINT_new.errcheck = _check_res_void_p
140+
_ssl.EC_POINT_new.restype = ctypes.c_void_p
141+
_ssl.EC_POINT_new.argtypes = [ctypes.c_void_p]
142+
143+
_ssl.EC_POINT_mul.restype = ctypes.c_int
144+
_ssl.EC_POINT_mul.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]
145+
146+
_ssl.EC_POINT_set_compressed_coordinates_GFp.restype = ctypes.c_int
147+
_ssl.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]
148+
149+
_ssl.ECDSA_sign.restype = ctypes.c_int
150+
_ssl.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]
151+
152+
_ssl.ECDSA_size.restype = ctypes.c_int
153+
_ssl.ECDSA_size.argtypes = [ctypes.c_void_p]
154+
155+
_ssl.ECDSA_verify.restype = ctypes.c_int
156+
_ssl.ECDSA_verify.argtypes = [ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p]
157+
158+
_ssl.ECDSA_SIG_free.restype = None
159+
_ssl.ECDSA_SIG_free.argtypes = [ctypes.c_void_p]
160+
161+
_ssl.ECDH_compute_key.restype = ctypes.c_int
162+
_ssl.ECDH_compute_key.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p]
163+
164+
_ssl.ERR_error_string_n.restype = None
165+
_ssl.ERR_error_string_n.argtypes = [ctypes.c_ulong, ctypes.c_char_p, ctypes.c_size_t]
166+
167+
_ssl.ERR_get_error.restype = ctypes.c_ulong
168+
_ssl.ERR_get_error.argtypes = []
169+
170+
_ssl.d2i_ECDSA_SIG.restype = ctypes.c_void_p
171+
_ssl.d2i_ECDSA_SIG.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_long]
172+
173+
_ssl.d2i_ECPrivateKey.restype = ctypes.c_void_p
174+
_ssl.d2i_ECPrivateKey.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_long]
175+
176+
_ssl.i2d_ECDSA_SIG.restype = ctypes.c_int
177+
_ssl.i2d_ECDSA_SIG.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
178+
179+
_ssl.i2d_ECPrivateKey.restype = ctypes.c_int
180+
_ssl.i2d_ECPrivateKey.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
181+
182+
_ssl.i2o_ECPublicKey.restype = ctypes.c_void_p
183+
_ssl.i2o_ECPublicKey.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
184+
185+
_ssl.o2i_ECPublicKey.restype = ctypes.c_void_p
186+
_ssl.o2i_ECPublicKey.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_long]
187+
188+
# this specifies the curve used with ECDSA.
189+
_NID_secp256k1 = 714 # from openssl/obj_mac.h
190+
191+
# test that OpenSSL supports secp256k1
192+
_ssl.EC_KEY_new_by_curve_name(_NID_secp256k1)
57193

58194
# From openssl/ecdsa.h
59195
class ECDSA_SIG_st(ctypes.Structure):
60-
_fields_ = [("r", ctypes.c_void_p),
196+
_fields_ = [("r", ctypes.c_void_p),
61197
("s", ctypes.c_void_p)]
62198

63199
class CECKey:
@@ -122,7 +258,7 @@ def get_ecdh_key(self, other_pubkey, kdf=lambda k: hashlib.sha256(k).digest()):
122258
r = self.get_raw_ecdh_key(other_pubkey)
123259
return kdf(r)
124260

125-
def sign(self, hash):
261+
def sign(self, hash): # pylint: disable=redefined-builtin
126262
if not isinstance(hash, bytes):
127263
raise TypeError('Hash must be bytes instance; got %r' % hash.__class__)
128264
if len(hash) != 32:
@@ -138,7 +274,7 @@ def sign(self, hash):
138274
else:
139275
return self.signature_to_low_s(mb_sig.raw[:sig_size0.value])
140276

141-
def sign_compact(self, hash):
277+
def sign_compact(self, hash): # pylint: disable=redefined-builtin
142278
if not isinstance(hash, bytes):
143279
raise TypeError('Hash must be bytes instance; got %r' % hash.__class__)
144280
if len(hash) != 32:
@@ -214,10 +350,10 @@ def signature_to_low_s(self, sig):
214350

215351
return new_sig.raw
216352

217-
def verify(self, hash, sig):
353+
def verify(self, hash, sig): # pylint: disable=redefined-builtin
218354
"""Verify a DER signature"""
219355
if not sig:
220-
return false
356+
return False
221357

222358
# New versions of OpenSSL will reject non-canonical DER signatures. de/re-serialize first.
223359
norm_sig = ctypes.c_void_p(0)
@@ -226,7 +362,7 @@ def verify(self, hash, sig):
226362
derlen = _ssl.i2d_ECDSA_SIG(norm_sig, 0)
227363
if derlen == 0:
228364
_ssl.ECDSA_SIG_free(norm_sig)
229-
return false
365+
return False
230366

231367
norm_der = ctypes.create_string_buffer(derlen)
232368
_ssl.i2d_ECDSA_SIG(norm_sig, ctypes.byref(ctypes.pointer(norm_der)))
@@ -362,11 +498,11 @@ def __new__(cls, buf, _cec_key=None):
362498
if _cec_key is None:
363499
_cec_key = CECKey()
364500
self._cec_key = _cec_key
365-
self.is_fullyvalid = _cec_key.set_pubkey(self) != 0
501+
self.is_fullyvalid = _cec_key.set_pubkey(self) is not None
366502
return self
367503

368504
@classmethod
369-
def recover_compact(cls, hash, sig):
505+
def recover_compact(cls, hash, sig): # pylint: disable=redefined-builtin
370506
"""Recover a public key from a compact signature."""
371507
if len(sig) != 65:
372508
raise ValueError("Signature should be 65 characters, not [%d]" % (len(sig), ))
@@ -397,7 +533,7 @@ def is_valid(self):
397533
def is_compressed(self):
398534
return len(self) == 33
399535

400-
def verify(self, hash, sig):
536+
def verify(self, hash, sig): # pylint: disable=redefined-builtin
401537
return self._cec_key.verify(hash, sig)
402538

403539
def __str__(self):

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.