Skip to content

Conversation

@melvincarvalho
Copy link
Contributor

Summary

  • Add fallback DER signature parser for OpenSSL 3.x compatibility
  • Fix signature verification failure at block 605,359

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:

ERROR: CScriptCheck() : 3d7458b83ae2806d621f438da40e5f8592c5445d62cb0f6bdb0b75f94b72fb5d VerifySignature failed
InvalidChainFound: invalid block=d67b8e990ac2438dd2f144033f5337f8bdfaf8a8f3bdaf5c771739e02c36748d height=605359

Solution

Add ecdsa_sig_parse_der_lax() as a fallback parser when OpenSSL's strict parser 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.

Testing

  • Tested full reindex from genesis to block 609,000+
  • Successfully passed block 605,359 without signature errors
  • All algorithms (SCRYPT, SHA256D, YESCRYPT, ARGON2D, X17, LYRA2REv2, EQUIHASH, CRYPTONIGHT) verified

Test plan

  • Build with OpenSSL 3.x
  • Sync past block 605,359
  • Verify no signature errors in log

Fixes #145

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
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +107 to +111
if (!ECDSA_SIG_set0(ret, r, s)) {
ECDSA_SIG_free(ret);
BN_free(r);
BN_free(s);
return NULL;
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenSSL 3.x signature verification fails at block 605,359

2 participants