Don't use BMConfigParser in highlevelcrypto, instead use digestAlg kwarg,

both in .sign() and .verify(), extend TestHighlevelcrypto.test_signatures().
This commit is contained in:
Dmitri Bogomolov 2021-07-28 00:44:19 +03:00 committed by Lee Miller
parent fd3567b3fa
commit 799237c7ff
Signed by untrusted user: lee.miller
GPG Key ID: 4F97A5EA88F4AB63
3 changed files with 46 additions and 34 deletions

View File

@ -50,6 +50,8 @@ class singleWorker(StoppableThread):
def __init__(self): def __init__(self):
super(singleWorker, self).__init__(name="singleWorker") super(singleWorker, self).__init__(name="singleWorker")
self.digestAlg = config.safeGet(
'bitmessagesettings', 'digestalg', 'sha256')
proofofwork.init() proofofwork.init()
def stopThread(self): def stopThread(self):
@ -368,7 +370,8 @@ class singleWorker(StoppableThread):
payload += encodeVarint(config.getint( payload += encodeVarint(config.getint(
myAddress, 'payloadlengthextrabytes')) myAddress, 'payloadlengthextrabytes'))
signature = highlevelcrypto.sign(payload, privSigningKeyHex) signature = highlevelcrypto.sign(
payload, privSigningKeyHex, self.digestAlg)
payload += encodeVarint(len(signature)) payload += encodeVarint(len(signature))
payload += signature payload += signature
@ -455,8 +458,7 @@ class singleWorker(StoppableThread):
).digest()).digest() ).digest()).digest()
payload += doubleHashOfAddressData[32:] # the tag payload += doubleHashOfAddressData[32:] # the tag
signature = highlevelcrypto.sign( signature = highlevelcrypto.sign(
payload + dataToEncrypt, privSigningKeyHex payload + dataToEncrypt, privSigningKeyHex, self.digestAlg)
)
dataToEncrypt += encodeVarint(len(signature)) dataToEncrypt += encodeVarint(len(signature))
dataToEncrypt += signature dataToEncrypt += signature
@ -641,7 +643,7 @@ class singleWorker(StoppableThread):
dataToSign = payload + dataToEncrypt dataToSign = payload + dataToEncrypt
signature = highlevelcrypto.sign( signature = highlevelcrypto.sign(
dataToSign, privSigningKeyHex) dataToSign, privSigningKeyHex, self.digestAlg)
dataToEncrypt += encodeVarint(len(signature)) dataToEncrypt += encodeVarint(len(signature))
dataToEncrypt += signature dataToEncrypt += signature
@ -1223,7 +1225,8 @@ class singleWorker(StoppableThread):
payload += fullAckPayload payload += fullAckPayload
dataToSign = pack('>Q', embeddedTime) + '\x00\x00\x00\x02' + \ dataToSign = pack('>Q', embeddedTime) + '\x00\x00\x00\x02' + \
encodeVarint(1) + encodeVarint(toStreamNumber) + payload encodeVarint(1) + encodeVarint(toStreamNumber) + payload
signature = highlevelcrypto.sign(dataToSign, privSigningKeyHex) signature = highlevelcrypto.sign(
dataToSign, privSigningKeyHex, self.digestAlg)
payload += encodeVarint(len(signature)) payload += encodeVarint(len(signature))
payload += signature payload += signature

View File

@ -13,7 +13,6 @@ import pyelliptic
from pyelliptic import OpenSSL from pyelliptic import OpenSSL
from pyelliptic import arithmetic as a from pyelliptic import arithmetic as a
from bmconfigparser import config
__all__ = ['encrypt', 'makeCryptor', 'pointMult', 'privToPub', 'sign', 'verify'] __all__ = ['encrypt', 'makeCryptor', 'pointMult', 'privToPub', 'sign', 'verify']
@ -64,43 +63,44 @@ def decryptFast(msg, cryptor):
return cryptor.decrypt(msg) return cryptor.decrypt(msg)
def sign(msg, hexPrivkey): def _choose_digest_alg(name):
"""
Choose openssl digest constant by name raises ValueError if not appropriate
"""
if name not in ("sha1", "sha256"):
raise ValueError("Unknown digest algorithm %s" % name)
return (
# SHA1, this will eventually be deprecated
OpenSSL.digest_ecdsa_sha1 if name == "sha1" else OpenSSL.EVP_sha256)
def sign(msg, hexPrivkey, digestAlg="sha256"):
""" """
Signs with hex private key using SHA1 or SHA256 depending on Signs with hex private key using SHA1 or SHA256 depending on
"digestalg" setting *digestAlg* keyword.
""" """
digestAlg = config.safeGet(
'bitmessagesettings', 'digestalg', 'sha256')
if digestAlg == "sha1":
# SHA1, this will eventually be deprecated
return makeCryptor(hexPrivkey).sign( return makeCryptor(hexPrivkey).sign(
msg, digest_alg=OpenSSL.digest_ecdsa_sha1) msg, digest_alg=_choose_digest_alg(digestAlg))
elif digestAlg == "sha256":
# SHA256. Eventually this will become the default
return makeCryptor(hexPrivkey).sign(msg, digest_alg=OpenSSL.EVP_sha256)
else:
raise ValueError("Unknown digest algorithm %s" % digestAlg)
def verify(msg, sig, hexPubkey): def verify(msg, sig, hexPubkey, digestAlg=None):
"""Verifies with hex public key using SHA1 or SHA256""" """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: if digestAlg is None:
# old SHA1 algorithm. # old SHA1 algorithm.
sigVerifyPassed = makePubCryptor(hexPubkey).verify( sigVerifyPassed = verify(msg, sig, hexPubkey, "sha1")
sig, msg, digest_alg=OpenSSL.digest_ecdsa_sha1)
except:
sigVerifyPassed = False
if sigVerifyPassed: if sigVerifyPassed:
# The signature check passed using SHA1 # The signature check passed using SHA1
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.
return verify(msg, sig, hexPubkey, "sha256")
try: try:
return makePubCryptor(hexPubkey).verify( return makePubCryptor(hexPubkey).verify(
sig, msg, digest_alg=OpenSSL.EVP_sha256) sig, msg, digest_alg=_choose_digest_alg(digestAlg))
except: except:
return False return False

View File

@ -70,12 +70,21 @@ class TestHighlevelcrypto(unittest.TestCase):
"""Verify sample signatures and newly generated ones""" """Verify sample signatures and newly generated ones"""
pubkey_hex = hexlify(sample_pubsigningkey) pubkey_hex = hexlify(sample_pubsigningkey)
# pregenerated signatures # pregenerated signatures
self.assertTrue(highlevelcrypto.verify(
sample_msg, sample_sig, pubkey_hex, "sha256"))
self.assertFalse(highlevelcrypto.verify(
sample_msg, sample_sig, pubkey_hex, "sha1"))
self.assertTrue(highlevelcrypto.verify(
sample_msg, sample_sig_sha1, pubkey_hex, "sha1"))
self.assertTrue(highlevelcrypto.verify(
sample_msg, sample_sig_sha1, pubkey_hex))
# new signatures
sig256 = highlevelcrypto.sign(sample_msg, sample_privsigningkey)
sig1 = highlevelcrypto.sign(sample_msg, sample_privsigningkey, "sha1")
self.assertTrue( self.assertTrue(
highlevelcrypto.verify(sample_msg, sample_sig, pubkey_hex)) highlevelcrypto.verify(sample_msg, sig256, pubkey_hex))
self.assertTrue( self.assertTrue(
highlevelcrypto.verify(sample_msg, sample_sig_sha1, pubkey_hex)) highlevelcrypto.verify(sample_msg, sig256, pubkey_hex, "sha256"))
# new signature
sig1 = highlevelcrypto.sign(sample_msg, sample_privsigningkey)
self.assertTrue( self.assertTrue(
highlevelcrypto.verify(sample_msg, sig1, pubkey_hex)) highlevelcrypto.verify(sample_msg, sig1, pubkey_hex))