More docstrings and formatting fixes in highlevelcrypto and shutdown
This commit is contained in:
parent
a7da0c0eff
commit
d9fa6a94f4
|
@ -1,6 +1,10 @@
|
||||||
"""
|
"""
|
||||||
src/highlevelcrypto.py
|
High level cryptographic functions based on `.pyelliptic` OpenSSL bindings.
|
||||||
======================
|
|
||||||
|
.. note::
|
||||||
|
Upstream pyelliptic was upgraded from SHA1 to SHA256 for signing.
|
||||||
|
We must upgrade PyBitmessage gracefully.
|
||||||
|
`More discussion. <https://github.com/yann2192/pyelliptic/issues/32>`_
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from binascii import hexlify
|
from binascii import hexlify
|
||||||
|
@ -12,12 +16,13 @@ from pyelliptic import arithmetic as a
|
||||||
|
|
||||||
|
|
||||||
def makeCryptor(privkey):
|
def makeCryptor(privkey):
|
||||||
"""Return a private pyelliptic.ECC() instance"""
|
"""Return a private `.pyelliptic.ECC` instance"""
|
||||||
private_key = a.changebase(privkey, 16, 256, minlen=32)
|
private_key = a.changebase(privkey, 16, 256, minlen=32)
|
||||||
public_key = pointMult(private_key)
|
public_key = pointMult(private_key)
|
||||||
privkey_bin = '\x02\xca\x00\x20' + private_key
|
privkey_bin = '\x02\xca\x00\x20' + private_key
|
||||||
pubkey_bin = '\x02\xca\x00\x20' + public_key[1:-32] + '\x00\x20' + public_key[-32:]
|
pubkey_bin = '\x02\xca\x00\x20' + public_key[1:-32] + '\x00\x20' + public_key[-32:]
|
||||||
cryptor = pyelliptic.ECC(curve='secp256k1', privkey=privkey_bin, pubkey=pubkey_bin)
|
cryptor = pyelliptic.ECC(
|
||||||
|
curve='secp256k1', privkey=privkey_bin, pubkey=pubkey_bin)
|
||||||
return cryptor
|
return cryptor
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,7 +34,7 @@ def hexToPubkey(pubkey):
|
||||||
|
|
||||||
|
|
||||||
def makePubCryptor(pubkey):
|
def makePubCryptor(pubkey):
|
||||||
"""Return a public pyelliptic.ECC() instance"""
|
"""Return a public `.pyelliptic.ECC` instance"""
|
||||||
pubkey_bin = hexToPubkey(pubkey)
|
pubkey_bin = hexToPubkey(pubkey)
|
||||||
return pyelliptic.ECC(curve='secp256k1', pubkey=pubkey_bin)
|
return pyelliptic.ECC(curve='secp256k1', pubkey=pubkey_bin)
|
||||||
|
|
||||||
|
@ -43,7 +48,8 @@ def privToPub(privkey):
|
||||||
|
|
||||||
def encrypt(msg, hexPubkey):
|
def encrypt(msg, hexPubkey):
|
||||||
"""Encrypts message with hex public key"""
|
"""Encrypts message with hex public key"""
|
||||||
return pyelliptic.ECC(curve='secp256k1').encrypt(msg, hexToPubkey(hexPubkey))
|
return pyelliptic.ECC(curve='secp256k1').encrypt(
|
||||||
|
msg, hexToPubkey(hexPubkey))
|
||||||
|
|
||||||
|
|
||||||
def decrypt(msg, hexPrivkey):
|
def decrypt(msg, hexPrivkey):
|
||||||
|
@ -52,36 +58,38 @@ def decrypt(msg, hexPrivkey):
|
||||||
|
|
||||||
|
|
||||||
def decryptFast(msg, cryptor):
|
def decryptFast(msg, cryptor):
|
||||||
"""Decrypts message with an existing pyelliptic.ECC.ECC object"""
|
"""Decrypts message with an existing `.pyelliptic.ECC` object"""
|
||||||
return cryptor.decrypt(msg)
|
return cryptor.decrypt(msg)
|
||||||
|
|
||||||
|
|
||||||
def sign(msg, hexPrivkey):
|
def sign(msg, hexPrivkey):
|
||||||
"""Signs with hex private key"""
|
"""
|
||||||
# pyelliptic is upgrading from SHA1 to SHA256 for signing. We must
|
Signs with hex private key using SHA1 or SHA256 depending on
|
||||||
# upgrade PyBitmessage gracefully.
|
"digestalg" setting
|
||||||
# https://github.com/yann2192/pyelliptic/pull/33
|
"""
|
||||||
# More discussion: https://github.com/yann2192/pyelliptic/issues/32
|
digestAlg = BMConfigParser().safeGet(
|
||||||
digestAlg = BMConfigParser().safeGet('bitmessagesettings', 'digestalg', 'sha1')
|
'bitmessagesettings', 'digestalg', 'sha1')
|
||||||
if digestAlg == "sha1":
|
if digestAlg == "sha1":
|
||||||
# SHA1, this will eventually be deprecated
|
# SHA1, this will eventually be deprecated
|
||||||
return makeCryptor(hexPrivkey).sign(msg, digest_alg=OpenSSL.digest_ecdsa_sha1)
|
return makeCryptor(hexPrivkey).sign(
|
||||||
|
msg, digest_alg=OpenSSL.digest_ecdsa_sha1)
|
||||||
elif digestAlg == "sha256":
|
elif digestAlg == "sha256":
|
||||||
# SHA256. Eventually this will become the default
|
# SHA256. Eventually this will become the default
|
||||||
return makeCryptor(hexPrivkey).sign(msg, digest_alg=OpenSSL.EVP_sha256)
|
return makeCryptor(hexPrivkey).sign(msg, digest_alg=OpenSSL.EVP_sha256)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Unknown digest algorithm %s" % (digestAlg))
|
raise ValueError("Unknown digest algorithm %s" % digestAlg)
|
||||||
|
|
||||||
|
|
||||||
def verify(msg, sig, hexPubkey):
|
def verify(msg, sig, hexPubkey):
|
||||||
"""Verifies with hex public key"""
|
"""Verifies with hex public key using SHA1 or SHA256"""
|
||||||
# As mentioned above, we must upgrade gracefully to use SHA256. So
|
# As mentioned above, we must upgrade gracefully to use SHA256. So
|
||||||
# let us check the signature using both SHA1 and SHA256 and if one
|
# let us check the signature using both SHA1 and SHA256 and if one
|
||||||
# of them passes then we will be satisfied. Eventually this can
|
# of them passes then we will be satisfied. Eventually this can
|
||||||
# be simplified and we'll only check with SHA256.
|
# be simplified and we'll only check with SHA256.
|
||||||
try:
|
try:
|
||||||
# old SHA1 algorithm.
|
# old SHA1 algorithm.
|
||||||
sigVerifyPassed = makePubCryptor(hexPubkey).verify(sig, msg, digest_alg=OpenSSL.digest_ecdsa_sha1)
|
sigVerifyPassed = makePubCryptor(hexPubkey).verify(
|
||||||
|
sig, msg, digest_alg=OpenSSL.digest_ecdsa_sha1)
|
||||||
except:
|
except:
|
||||||
sigVerifyPassed = False
|
sigVerifyPassed = False
|
||||||
if sigVerifyPassed:
|
if sigVerifyPassed:
|
||||||
|
@ -89,7 +97,8 @@ def verify(msg, sig, hexPubkey):
|
||||||
return True
|
return True
|
||||||
# The signature check using SHA1 failed. Let us try it with SHA256.
|
# The signature check using SHA1 failed. Let us try it with SHA256.
|
||||||
try:
|
try:
|
||||||
return makePubCryptor(hexPubkey).verify(sig, msg, digest_alg=OpenSSL.EVP_sha256)
|
return makePubCryptor(hexPubkey).verify(
|
||||||
|
sig, msg, digest_alg=OpenSSL.EVP_sha256)
|
||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -106,7 +115,8 @@ def pointMult(secret):
|
||||||
"""
|
"""
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
k = OpenSSL.EC_KEY_new_by_curve_name(OpenSSL.get_curve('secp256k1'))
|
k = OpenSSL.EC_KEY_new_by_curve_name(
|
||||||
|
OpenSSL.get_curve('secp256k1'))
|
||||||
priv_key = OpenSSL.BN_bin2bn(secret, 32, None)
|
priv_key = OpenSSL.BN_bin2bn(secret, 32, None)
|
||||||
group = OpenSSL.EC_KEY_get0_group(k)
|
group = OpenSSL.EC_KEY_get0_group(k)
|
||||||
pub_key = OpenSSL.EC_POINT_new(group)
|
pub_key = OpenSSL.EC_POINT_new(group)
|
||||||
|
|
|
@ -16,7 +16,9 @@ from queues import (
|
||||||
|
|
||||||
|
|
||||||
def doCleanShutdown():
|
def doCleanShutdown():
|
||||||
"""Used to tell proof of work worker threads and the objectProcessorThread to exit."""
|
"""
|
||||||
|
Used to tell all the treads to finish work and exit.
|
||||||
|
"""
|
||||||
state.shutdown = 1
|
state.shutdown = 1
|
||||||
|
|
||||||
objectProcessorQueue.put(('checkShutdownVariable', 'no data'))
|
objectProcessorQueue.put(('checkShutdownVariable', 'no data'))
|
||||||
|
@ -52,9 +54,11 @@ def doCleanShutdown():
|
||||||
time.sleep(.25)
|
time.sleep(.25)
|
||||||
|
|
||||||
for thread in threading.enumerate():
|
for thread in threading.enumerate():
|
||||||
if (thread is not threading.currentThread() and
|
if (
|
||||||
isinstance(thread, StoppableThread) and
|
thread is not threading.currentThread()
|
||||||
thread.name != 'SQL'):
|
and isinstance(thread, StoppableThread)
|
||||||
|
and thread.name != 'SQL'
|
||||||
|
):
|
||||||
logger.debug("Waiting for thread %s", thread.name)
|
logger.debug("Waiting for thread %s", thread.name)
|
||||||
thread.join()
|
thread.join()
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user