-
Notifications
You must be signed in to change notification settings - Fork 73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace OpenSSL dependency with pinned BoringSSL #1599
Conversation
Co-authored-by: 766C6164 <valterdaw@gmail.com>
FC_ASSERT( BN_num_bytes( order ) == static_cast<int>(bin.data_size()) ); | ||
FC_ASSERT( BN_bn2bin( order, (unsigned char*) bin.data() ) == static_cast<int>(bin.data_size()) ); | ||
FC_ASSERT( BN_num_bytes( order ) == bin.data_size() ); | ||
FC_ASSERT( BN_bn2bin( order, (unsigned char*) bin.data() ) == bin.data_size() ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are a good example of while BoringSSL is a drop in replacement, it isn't without slight differences. A warning was introduced here because BoringSSL returns a size_t
while OpenSSL returned an int
.
RAND_bytes((uint8_t*)ret.my->_key.data(), sizeof(ret.my->_key.data())); | ||
} while(!secp256k1_ec_seckey_verify(detail::_get_context(), (const uint8_t*)ret.my->_key.data())); | ||
return ret; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change requires special attention during review. BoringSSL does not support the K1 curve. We've previously transitioned to using libsecp256k1 for all things K1... except for private key generation as performed here.
_key
is a private_key_secret
,
private_key_secret _key; |
and private_key_secret
is a fc::sha256
,
typedef fc::sha256 private_key_secret; |
The original code in this PR is probably incorrect and does not generate 32 random bytes, which would be a disaster.
@@ -7,6 +7,8 @@ set(BN256_INSTALL_COMPONENT "dev") | |||
|
|||
set( Boost_USE_MULTITHREADED ON ) | |||
set( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" ) | |||
# don't include boost mysql library as it does a find_package(OpenSSL) thus finding the system openssl which could conflict with the bundled boringssl | |||
set( BOOST_EXCLUDE_LIBRARIES "mysql" ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is something we'll need to be mindful of on boost bumps (or really any bundled dependency).
I think it would be nicer to check in these generated files into our fork of BoringSSL (at least keeping the workflow test that checked-in files match newly generated ones), and to use BoringSSL as a submodule in Leap. |
That seems reasonable, let me play with that and see if there are any downsides. |
@greg7mdp I'm not sure how to best accomplish that. The primary problem here is that the Obviously we could change One possibility is to utilize two submodules. We keep the close-to-upstream boringssl as it is now, but then have a new " |
This is a little awkward, but I think this is preferable to adding all the generated files to leap itself, and I can't think of a better way to do it. I'm curious to hear what others think. |
I think main goals would be simple to upgrade in the future and fast to check out. This approach seems to achieve those. |
Okay, I've migrated the generated build files to |
Historically leap has used OpenSSL for TLS support and various crypto primitives (such as SHA256 and R1 key math). TLS support was removed a while ago leaving just the crypto primitives. Still, even with the rather limited usage, we'd like to avoid depending on system provided libraries for consensus bits, or at least "mathy" consensus bits, as these libraries may unexpectedly change some nuance out from under us resulting in consensus failure. A good example of such a change occurred in openssl 3.0.4 (that did not affect Leap).
Because we no longer directly depend on a TLS library as part of our build, we can pin these crypto primitives to a specific point in time without fear of TLS security flaws in the future. Using BoringSSL as a pinned drop in replacement appears to be a great fit. BoringSSL is designed to be simply submoduled in and static linked against. Also, BoringSSL is a fork of OpenSSL so its behavior and API is likely to be the same as existing OpenSSL usage making it less risky than wholesale replacement and refactor with a different library.
This PR builds on #1233 with some changes, notably:
We now maintain our own fork of BoringSSL. While using upstream directly is nice, the trade off of that approach is that it's harder to audit the changes to the Python generation script. Since #1277 + #1255 will require modifying BoringSSL anyways, the fork seems inevitable. Keep in mind that,
So we are simply using yesterday's HEAD for the fork.
While BoringSSL really can simply be "dropped in" as a submodule that comes with a catch that a recent version of Go is required to build. We don't want that. Thus we end up with something I consider really ugly: committing post processed files in to our repository. We will simply have to tolerate this, as it's just how BoringSSL works,
To make it worse, the generated files must be placed directly outside of the
src
submodule directory. I would have liked to place these files in to agenerated
directory to more cleanly delineate the generated files from non-generated files, but alas without hacking up thegenerated_build_files.py
script more that doesn't seem possible.I've tried to mitigate this ugliness a little by adding a small test in the workflow that regenerates the intermediate files and will fail if the files don't match what is committed. An example of failure can be found, https://github.com/AntelopeIO/leap/actions/runs/6091633748/job/16528533086
Also, as a reviewer note, the first commit in the PR contains the changes before running the
make regenerate_boringssl
target, and the third commit contains those generated files added to the repo. Ultimately the changes outside that third commit are quite minimal.