Skip to content

Conversation

@theuni
Copy link
Member

@theuni theuni commented Jan 10, 2015

Bump to 1.0.1k and cope with its more strict DER checks.

theuni added 2 commits January 9, 2015 21:31
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.
@gavinandresen
Copy link
Contributor

ACK: code reviewed, and fixes unit test errors running on OSX with OpenSSL 1.0.1k

Copy link
Member

Choose a reason for hiding this comment

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

use vchSig.begin(); don't use [0] unless it's guaranteed that the length is at least 1.

EDIT: not introduced by your commit, feel free to ignore, but it apparently upsets some MSVC debug mode.

@sipa
Copy link
Member

sipa commented Jan 10, 2015

untested ACK

@jgarzik
Copy link
Contributor

jgarzik commented Jan 10, 2015

tested ACK

@theuni
Copy link
Member Author

theuni commented Jan 10, 2015

@sipa afaik the iterator isn't guaranteed to be a pointer to the element there. Added an early return instead, you ok with that?

@gmaxwell
Copy link
Contributor

Tested ACK. (tests and a invalidate/reconsider loop back to 338221. Reindexed without checkpoints from 0 to 198k (still in progress))

Also +1 Tested ACK from an anonymous tester on IRC.

@petertodd
Copy link
Contributor

ut ACK

@fanquake
Copy link
Member

Tested ACK. As mentioned by Gavin, verified this fixes the unit tests on OSX when building with 1.0.1k

@ghost
Copy link

ghost commented Jan 10, 2015

Un

@pstratem
Copy link
Contributor

tested ack, invalidated to 322000 reconsidered upto 327086 (still running)

@gmaxwell gmaxwell merged commit 8dccba6 into bitcoin:master Jan 10, 2015
gmaxwell added a commit that referenced this pull request Jan 10, 2015
8dccba6 fail immediately on an empty signature (Cory Fields)
dad7764 depends: bump openssl to 1.0.1k (Cory Fields)
488ed32 consensus: guard against openssl's new strict DER checks (Cory Fields)
laanwj pushed a commit that referenced this pull request Jan 10, 2015
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
laanwj pushed a commit that referenced this pull request Jan 10, 2015
laanwj pushed a commit that referenced this pull request Jan 10, 2015
laanwj pushed a commit that referenced this pull request Jan 10, 2015
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
laanwj added a commit that referenced this pull request Jan 10, 2015
laanwj pushed a commit that referenced this pull request Jan 10, 2015
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
laanwj pushed a commit that referenced this pull request Jan 10, 2015
@petertodd
Copy link
Contributor

tested ACK, -checkpoints=0 reindexes on testnet and mainnet.

mhirki pushed a commit to mikaelh2/primecoin that referenced this pull request Jan 10, 2015
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: bitcoin#5634
Rebased-From: 488ed32
mhirki pushed a commit to mikaelh2/primecoin that referenced this pull request Jan 10, 2015
@ghost
Copy link

ghost commented Jan 11, 2015

This patch serves no purpose other than providing a "hack" around a flaw in the Bitcoin core. Previously OpenSSL did not look for invalid DER encoded data with possible trailing garbage but in the latest version it does. The actual problem is that Bitcoin accepts invalid DER encoded signatures and this is completely unrelated to OpenSSL. Now you are taking the invalid-DER encoded data and DER encoding it before calling ECDSA_verify. Because of this the same operation will be performed twice for every signature verification wasting CPU cycles. You MUST always DER encode your signature before passing it off to OpenSSL and this is nothing new. So this being "low" on OpenSSL's list is correct from my expert opinion as it is only performing validation and Bitcoin is passing invalid data.

ECDSA_verify:

int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
    const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
{
ECDSA_SIG *s;
const unsigned char *p = sigbuf;
unsigned char *der = NULL;
int derlen = -1;
int ret=-1;

s = ECDSA_SIG_new();
if (s == NULL) return(ret);
if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) goto err;
/* Ensure signature uses DER and doesn't have trailing garbage */
derlen = i2d_ECDSA_SIG(s, &der);
if (derlen != sig_len || memcmp(sigbuf, der, derlen))
    goto err;
ret=ECDSA_do_verify(dgst, dgst_len, s, eckey);
err:
if (derlen > 0)
    {
    OPENSSL_cleanse(der, derlen);
    OPENSSL_free(der);
    }
ECDSA_SIG_free(s);
return(ret);
}

@jgarzik
Copy link
Contributor

jgarzik commented Jan 11, 2015

@john-connor It is quite relevant in consensus systems, which must maintain bug-for-bug compatibility. It is impossible to rewind history, and un-accept signatures that have been previously accepted.

@ghost
Copy link

ghost commented Jan 11, 2015

@jgarzik The bug is in Bitcoin, not OpenSSL. This patch does not fix the bug. It is a hack.

@ghost
Copy link

ghost commented Jan 11, 2015

@jgarzik I know the blockchain is permanently flawed because of this bug but gavin and everybody else is blaming OpenSSL it seems. Accept the fact that Bitcoin core has a major flaw in that it does not DER encode signatures. This is something that could become fatal to Bitcoin in the future if OpenSSL were to further enforce it's fully understood rules. Why not fix the problem and hard fork instead of hacking the code?

@gmaxwell
Copy link
Contributor

@john-connor "Trailing garbage" is technically incorrect. What OpenSSL's ECDSA_verify previously supported was a very broad subset of BER. For example, encoding R and S with leading zeros. This is substantive, non-backwards compatible, arguably somewhat under-disclosed (seems that you were also unaware of the actual change, in that you refer to it as "trailing garbage"), breaking API change from the existing and widely known behavior. Signatures come from the outside world (Bitcoin Core itself has never generated anything but strictly minimal encodings), and the decoding functions are OpenSSL internal. As a result previously accepted encodings (and not just 'trailing garbage') will be rejected.

While this may not matter for most applications, a switch to be more conservative is not something that can be done in an uncoordinated way for a consensus system without resulting in an opening for funds loss. This is just the state of things, and not a question of "flaw" or blame. My description (http://sourceforge.net/p/bitcoin/mailman/message/33221963/) of the matter is just a statement of the facts about it.

@pstratem
Copy link
Contributor

@rnicoll

The documentation does say that.... but openssl itself seems to be calling ECDSA_SIG_new() before d2i_ECDSA_SIG.

Possibly there's a memory leak in openssl itself here.

@gmaxwell
Copy link
Contributor

@rnicoll Objectively, the current version does not leak (I tested with valgrind.) OpenSSL itself allocates first, so preserving its own behavior seemed to be conservative. The code in question appears to check the nullness of the pointer and allocates only if null, meaning the documentation is actually dangerously incorrect (since if you believed the documentation you may send uninitialized memory in there and have it fail to allocate).

Thanks for noticing th documentation disagreed, previously I'd just valgrinded and checked the code.

@rnicoll
Copy link
Contributor

rnicoll commented Jan 12, 2015

@gmaxwell Great, thanks for checking.

@pstratem
Copy link
Contributor

d2i_ECDSA_SIG does indeed segfault if passed an uninitialized pointer.

@pstratem
Copy link
Contributor

laanwj added a commit to laanwj/bitcoin that referenced this pull request Jan 12, 2015
Add some defensive programming on top of bitcoin#5634.

This copies the respective OpenSSL code in ECDSA_verify in
OpenSSL pre-1.0.1k (e.g. https://github.com/openssl/openssl/blob/OpenSSL_1_0_1j/crypto/ecdsa/ecs_vrf.c#L89)
more closely.

As reported by @SergioDemianLerner.
laanwj added a commit that referenced this pull request Jan 12, 2015
Add some defensive programming on top of #5634.

This copies the respective OpenSSL code in ECDSA_verify in
OpenSSL pre-1.0.1k (e.g. https://github.com/openssl/openssl/blob/OpenSSL_1_0_1j/crypto/ecdsa/ecs_vrf.c#L89)
more closely.

As reported by @SergioDemianLerner.

Github-Pull: #5640
Rebased-From: c6b7b29
laanwj added a commit that referenced this pull request Jan 12, 2015
Add some defensive programming on top of #5634.

This copies the respective OpenSSL code in ECDSA_verify in
OpenSSL pre-1.0.1k (e.g. https://github.com/openssl/openssl/blob/OpenSSL_1_0_1j/crypto/ecdsa/ecs_vrf.c#L89)
more closely.

As reported by @SergioDemianLerner.

Github-Pull: #5640
Rebased-From: c6b7b29
laanwj added a commit that referenced this pull request Jan 12, 2015
Add some defensive programming on top of #5634.

This copies the respective OpenSSL code in ECDSA_verify in
OpenSSL pre-1.0.1k (e.g. https://github.com/openssl/openssl/blob/OpenSSL_1_0_1j/crypto/ecdsa/ecs_vrf.c#L89)
more closely.

As reported by @SergioDemianLerner.

Github-Pull: #5640
Rebased-From: c6b7b29
wtogami pushed a commit to litecoin-project/litecoin that referenced this pull request Jan 13, 2015
Add some defensive programming on top of bitcoin#5634.

This copies the respective OpenSSL code in ECDSA_verify in
OpenSSL pre-1.0.1k (e.g. https://github.com/openssl/openssl/blob/OpenSSL_1_0_1j/crypto/ecdsa/ecs_vrf.c#L89)
more closely.

As reported by @SergioDemianLerner.

Bitcoin Github-Pull: bitcoin#5640
Rebased-From: c6b7b29
m21 added a commit to mastercoin-MSC/mastercore that referenced this pull request Jan 26, 2015
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: bitcoin#5634
Rebased-From: 488ed32

Conflicts:
	src/key.cpp

cherry-picked:
bitcoin@b8e81b7
bitcoin@60c51f1
bitcoin@037bfef
@abbradar
Copy link

abbradar commented Feb 2, 2015

Would there be a new point release or a patch for 0.9.3? This cannot be cleanly applied to 0.9.3 as-is (ecwrapper.cpp is missing), and I thought it would be better to ask anyway to avoid blindly patching critical piece of software.

@laanwj
Copy link
Member

laanwj commented Feb 2, 2015

Try checking out and/or cherry-picking from the v0.9.4 tag, it has the same changes.

@abbradar
Copy link

abbradar commented Feb 2, 2015

I'll just checkout v0.9.4 then. Thanks!

@fsb4000 fsb4000 mentioned this pull request Feb 3, 2015
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
jondow72 added a commit to magi-dev/magi that referenced this pull request Mar 16, 2025
jondow72 added a commit to magi-dev/magi that referenced this pull request Mar 16, 2025
jondow72 added a commit to magi-dev/magi that referenced this pull request Mar 16, 2025
jondow72 added a commit to magi-dev/magi that referenced this pull request Mar 23, 2025
jondow72 added a commit to magi-dev/magi that referenced this pull request Mar 25, 2025
jondow72 added a commit to magi-dev/magi that referenced this pull request Mar 25, 2025
jondow72 added a commit to magi-dev/magi that referenced this pull request Mar 25, 2025
aaronmee pushed a commit to aaronmee/magi that referenced this pull request Oct 21, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.