Fix OpenSSL 3.x signature verification failure#146
Fix OpenSSL 3.x signature verification failure#146melvincarvalho wants to merge 1 commit intomasterfrom
Conversation
OpenSSL 3.x has stricter DER signature parsing than OpenSSL 1.x, causing signature verification to fail at block 605,359 and potentially other blocks with non-canonical signature encodings. Add ecdsa_sig_parse_der_lax() as a fallback parser when OpenSSL's strict d2i_ECDSA_SIG() fails. The lax parser: - Manually parses DER SEQUENCE and INTEGER tags - Extracts R and S values using BN_bin2bn() - Creates ECDSA_SIG using ECDSA_SIG_set0() Also adds ECDSA_SIG_set0() compatibility shim for OpenSSL < 1.1.0. Fixes #145
There was a problem hiding this comment.
Pull request overview
This pull request fixes a compatibility issue with OpenSSL 3.x's stricter DER signature parsing that was causing blockchain synchronization to fail at block 605,359. The fix adds a fallback DER signature parser that handles non-canonical DER encodings accepted by older OpenSSL versions.
Key changes:
- Added
ecdsa_sig_parse_der_lax()function to manually parse DER signatures when OpenSSL's strict parser fails - Added
ECDSA_SIG_set0()compatibility shim for OpenSSL versions < 1.1.0 - Modified signature verification to fall back to the lax parser when OpenSSL 3.x rejects signatures
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (!ECDSA_SIG_set0(ret, r, s)) { | ||
| ECDSA_SIG_free(ret); | ||
| BN_free(r); | ||
| BN_free(s); | ||
| return NULL; |
There was a problem hiding this comment.
After successfully calling ECDSA_SIG_set0, ownership of the BIGNUM r and s is transferred to the ECDSA_SIG structure. If ECDSA_SIG_set0 fails, the function should free both r and s before freeing the ECDSA_SIG. However, after ECDSA_SIG_set0 succeeds, the BN_free calls on lines 109-110 will double-free the memory since the ECDSA_SIG structure now owns these BIGNUMs. The BN_free calls should be removed from this error path.
Summary
Problem
OpenSSL 3.x has stricter DER signature parsing than OpenSSL 1.x. The
d2i_ECDSA_SIG()function rejects some valid ECDSA signatures that have non-canonical DER encoding, causing sync to fail at block 605,359:Solution
Add
ecdsa_sig_parse_der_lax()as a fallback parser when OpenSSL's strict parser fails. The lax parser:BN_bin2bn()ECDSA_SIGusingECDSA_SIG_set0()Also adds
ECDSA_SIG_set0()compatibility shim for OpenSSL < 1.1.0.Testing
Test plan
Fixes #145