Fix sweep nonce non-determinism and disabled TLS hostname verification - #14
Fix sweep nonce non-determinism and disabled TLS hostname verification#14RobGanon wants to merge 1 commit into
Conversation
In electrumsv/gui/qt/sweep_helper.py: - Sign sweep transactions with RFC6979 deterministic nonce (sign_digest_deterministic) instead of the non-deterministic ecdsa.sign_digest which falls back to os.urandom. Prevents potential private key recovery via nonce reuse. - Stop setting check_hostname=False on the ElectrumX socket TLS context, restoring hostname verification (fails secure).
|
I investigated both changes separately. The deterministic-signature issue is already resolved in my development branch, where sweep signing uses bitcoinx/libsecp256k1 rather than the ecdsa signing path in this PR. Regarding TLS hostname verification, I agree that disabling hostname verification weakens TLS security. However, ElectrumSVP currently uses server-specific self-signed certificates, and I verified that at least sv2.satoshi.io currently presents a self-signed certificate for CN=electrumr with no SAN for sv2.satoshi.io. With that certificate explicitly trusted, hostname verification succeeds only when check_hostname=False; enabling it produces a hostname-mismatch failure. Simply removing check_hostname=False would therefore break some existing configured servers. This is not ideal, but in the specific case of the sweep operation, a MITM would not gain access to the private keys. They could potentially provide incomplete or incorrect UTXO data, which could cause a sweep to fail or result in fewer UTXOs being included, but they would not be able to sign transactions with the user's private keys. I am not adopting that change as-is and will investigate the certificate/TLS architecture separately. |
ElectrumSVP: fix two sweep-path security issues
Attach
electrumsvp-fixes.patch(or paste the diff below) to an Issue — or open it as a PR againstTruthMachine/ElectrumSVP.Problem 1 — non-deterministic ECDSA nonce in sweep signing
electrumsv/gui/qt/sweep_helper.pysigns sweep txs withecdsa.SigningKey.sign_digest(...), which — because nokis supplied —falls back to
os.urandomfor the nonce (theecdsadocs themselves say touse
sign_digest_deterministicinstead). With a weak/broken RNG or noncereuse, an attacker can recover the swept private key. Everywhere else the
wallet uses RFC6979 (bitcoinx
PrivateKey.sign→ libsecp256k1); the sweeppath is the only exception.
Fix: sign with an RFC6979 deterministic nonce:
hashlibis already imported in this module. Output format is unchanged(low-S canonical DER +
0x41sighash suffix).Problem 2 — TLS hostname verification disabled
sweep_helper.create_ssl_context()setsctx.check_hostname = Falsefor thedirect ElectrumX socket fallback, disabling hostname verification (normal
wallet connections via aiorpcx don't do this). Fix: remove that line.
ctx.load_verify_locations(cafile=pem_path) - ctx.check_hostname = FalseVerification performed
structure, and the signature verifies against the public key.
check_hostname=True/CERT_REQUIRED.py_compilepasses; the only changes are insweep_helper.py(2+/2-).How to apply
or