Skip to content

Commit b8e81b7

Browse files
theunilaanwj
authored andcommitted
consensus: guard against openssl's new strict DER checks
New versions of OpenSSL will reject non-canonical DER signatures. However, it'll happily decode them. Decode then re-encode before verification in order to ensure that it is properly consumed. Github-Pull: #5634 Rebased-From: 488ed32
1 parent 0a94661 commit b8e81b7

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

src/key.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,20 @@ class CECKey {
227227
}
228228

229229
bool Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
230-
// -1 = error, 0 = bad sig, 1 = good
231-
if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
230+
// New versions of OpenSSL will reject non-canonical DER signatures. de/re-serialize first.
231+
unsigned char *norm_der = NULL;
232+
ECDSA_SIG *norm_sig = ECDSA_SIG_new();
233+
const unsigned char* sigptr = &vchSig[0];
234+
d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size());
235+
int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der);
236+
ECDSA_SIG_free(norm_sig);
237+
if (derlen <= 0)
232238
return false;
233-
return true;
239+
240+
// -1 = error, 0 = bad sig, 1 = good
241+
bool ret = ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), norm_der, derlen, pkey) == 1;
242+
OPENSSL_free(norm_der);
243+
return ret;
234244
}
235245

236246
bool SignCompact(const uint256 &hash, unsigned char *p64, int &rec) {

0 commit comments

Comments
 (0)