diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml index 09f0d3cbf8..9ad90c5204 100644 --- a/.github/workflows/ci-linux.yml +++ b/.github/workflows/ci-linux.yml @@ -54,6 +54,18 @@ jobs: run: | export CC=gcc && export CXX=g++ bazel build -j ${{env.proc_num}} -c opt --copt -DHAVE_ZLIB=1 //... + + gcc-compile-with-boringssl: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: install dependences + run: | + sudo apt-get update + sudo apt-get install libibverbs-dev + - name: compile-with-boringssl + run: | + bazel build -j 12 -c opt --define with_mesalink=false --define with_glog=true --define with_thrift=true --define BRPC_WITH_BORINGSSL=true --copt -DHAVE_ZLIB=1 //... gcc-compile-with-make-all-options: runs-on: ubuntu-20.04 @@ -96,7 +108,6 @@ jobs: export CC=gcc && export CXX=g++ bazel build -j 12 -c opt --define with_mesalink=false --define with_glog=true --define with_thrift=true --copt -DHAVE_ZLIB=1 //... - clang-compile-with-make: runs-on: ubuntu-20.04 steps: @@ -138,6 +149,18 @@ jobs: export CC=clang && export CXX=clang++ bazel build -j ${{env.proc_num}} -c opt --copt -DHAVE_ZLIB=1 //... + clang-compile-with-boringssl: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: install dependences + run: | + sudo apt-get update + sudo apt-get install libibverbs-dev + - name: compile + run: | + bazel build -j ${{env.proc_num}} -c opt --define with_mesalink=false --define with_glog=true --define with_thrift=true --define BRPC_WITH_BORINGSSL=true --copt -DHAVE_ZLIB=1 //... + clang-compile-with-make-all-options: runs-on: ubuntu-20.04 steps: diff --git a/BUILD.bazel b/BUILD.bazel index 8848593a95..c2c82f9863 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -325,14 +325,15 @@ cc_library( "@com_github_gflags_gflags//:gflags", "@com_github_madler_zlib//:zlib", "@com_google_protobuf//:protobuf", - "@openssl//:crypto", - "@openssl//:ssl", ] + select({ "//bazel/config:brpc_with_glog": ["@com_github_google_glog//:glog"], "//conditions:default": [], }) + select({ "@bazel_tools//tools/osx:darwin": [":macos_lib"], "//conditions:default": [], + }) + select({ + "//bazel/config:brpc_with_boringssl": ["@boringssl//:ssl", "@boringssl//:crypto"], + "//conditions:default": ["@openssl//:ssl", "@openssl//:crypto"], }), ) diff --git a/CMakeLists.txt b/CMakeLists.txt index 66cc015783..5c06c9616b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ project(brpc C CXX) option(WITH_GLOG "With glog" OFF) option(WITH_MESALINK "With MesaLink" OFF) +option(WITH_BORINGSSL "With BoringSSL" OFF) option(DEBUG "Print debug logs" OFF) option(WITH_DEBUG_SYMBOLS "With debug symbols" ON) option(WITH_THRIFT "With thrift framed protocol supported" OFF) @@ -205,19 +206,24 @@ if(NOT PROTOC_LIB) message(FATAL_ERROR "Fail to find protoc lib") endif() -if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") - set(OPENSSL_ROOT_DIR - "/usr/local/opt/openssl" # Homebrew installed OpenSSL +if(WITH_BORINGSSL) + find_package(BoringSSL) + include_directories(${BORINGSSL_INCLUDE_DIR}) +else() + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(OPENSSL_ROOT_DIR + "/usr/local/opt/openssl" # Homebrew installed OpenSSL ) -endif() + endif() -find_package(OpenSSL) + find_package(OpenSSL) + include_directories(${OPENSSL_INCLUDE_DIR}) +endif() include_directories( ${GFLAGS_INCLUDE_PATH} ${PROTOBUF_INCLUDE_DIRS} ${LEVELDB_INCLUDE_PATH} - ${OPENSSL_INCLUDE_DIR} ) set(DYNAMIC_LIB @@ -227,14 +233,19 @@ set(DYNAMIC_LIB ${PROTOC_LIB} ${CMAKE_THREAD_LIBS_INIT} ${THRIFT_LIB} - ${OPENSSL_CRYPTO_LIBRARY} dl z) -if(WITH_MESALINK) - list(APPEND DYNAMIC_LIB ${MESALINK_LIB}) +if(WITH_BORINGSSL) + list(APPEND DYNAMIC_LIB ${BORINGSSL_SSL_LIBRARY}) + list(APPEND DYNAMIC_LIB ${BORINGSSL_CRYPTO_LIBRARY}) else() - list(APPEND DYNAMIC_LIB ${OPENSSL_SSL_LIBRARY}) + list(APPEND DYNAMIC_LIB ${OPENSSL_CRYPTO_LIBRARY}) + if(WITH_MESALINK) + list(APPEND DYNAMIC_LIB ${MESALINK_LIB}) + else() + list(APPEND DYNAMIC_LIB ${OPENSSL_SSL_LIBRARY}) + endif() endif() if(WITH_RDMA) diff --git a/WORKSPACE b/WORKSPACE index b6fda836d8..a107f0a52c 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -18,6 +18,7 @@ workspace(name = "com_github_brpc_brpc") load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") +load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") # # Constants @@ -252,7 +253,6 @@ Set-Content protobuf.bzl -Value $content -Encoding UTF8 urls = ["https://github.com/protocolbuffers/protobuf/archive/refs/tags/v3.19.1.tar.gz"], ) -# bRPC cannot use boringssl. Build openssl. http_archive( name = "openssl", # 2021-12-14T15:45:01Z build_file = "//bazel/third_party/openssl:openssl.BUILD", @@ -264,6 +264,13 @@ http_archive( ], ) +# https://github.com/google/boringssl/blob/master/INCORPORATING.md +git_repository( + name = "boringssl", # 2021-05-01T12:26:01Z + commit = "0e6b86549db4c888666512295c3ebd4fa2a402f5", # fips-20210429 + remote = "https://github.com/google/boringssl", +) + http_archive( name = "org_apache_thrift", # 2021-09-11T11:54:01Z build_file = "//bazel/third_party/thrift:thrift.BUILD", diff --git a/bazel/config/BUILD.bazel b/bazel/config/BUILD.bazel index 8b09826515..bed04d3b57 100644 --- a/bazel/config/BUILD.bazel +++ b/bazel/config/BUILD.bazel @@ -103,3 +103,9 @@ config_setting( define_values = {"BRPC_WITH_RDMA": "true"}, visibility = ["//visibility:public"], ) + +config_setting( + name = "brpc_with_boringssl", + define_values = {"BRPC_WITH_BORINGSSL": "true"}, + visibility = ["//visibility:public"], +) \ No newline at end of file diff --git a/cmake/FindBoringSSL.cmake b/cmake/FindBoringSSL.cmake new file mode 100644 index 0000000000..b475f0aa5d --- /dev/null +++ b/cmake/FindBoringSSL.cmake @@ -0,0 +1,77 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Usage of this module as follows: +# +# find_package(BORINGSSL) +# +# Variables used by this module, they can change the default behaviour and need +# to be set before calling find_package: +# +# BORINGSSL_ROOT_DIR Set this variable to the root installation of +# boringssl if the module has problems finding the +# proper installation path. +# +# Variables defined by this module: +# +# BORINGSSL_FOUND System has boringssl, include and library dirs found +# BORINGSSL_INCLUDE_DIR The boringssl include directories. +# BORINGSSL_LIBRARIES The boringssl libraries. +# BORINGSSL_CRYPTO_LIBRARY The boringssl crypto library. +# BORINGSSL_SSL_LIBRARY The boringssl ssl library. +# BORING_USE_STATIC_LIBS Whether use static library. + +if(BORING_USE_STATIC_LIBS) + set(_boringssl_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + if(MSVC) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif() +endif() + +find_path(BORINGSSL_ROOT_DIR + NAMES include/openssl/ssl.h include/openssl/base.h include/openssl/hkdf.h + HINTS ${BORINGSSL_ROOT_DIR}) + +find_path(BORINGSSL_INCLUDE_DIR + NAMES openssl/ssl.h openssl/base.h openssl/hkdf.h + HINTS ${BORINGSSL_ROOT_DIR}/include) + +find_library(BORINGSSL_SSL_LIBRARY + NAMES ssl + HINTS ${BORINGSSL_ROOT_DIR}/lib) + +find_library(BORINGSSL_CRYPTO_LIBRARY + NAMES crypto + HINTS ${BORINGSSL_ROOT_DIR}/lib) + +set(BORINGSSL_LIBRARIES ${BORINGSSL_SSL_LIBRARY} ${BORINGSSL_CRYPTO_LIBRARY} + CACHE STRING "BoringSSL SSL and crypto libraries" FORCE) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(BoringSSL DEFAULT_MSG + BORINGSSL_LIBRARIES + BORINGSSL_INCLUDE_DIR) + +mark_as_advanced( + BORINGSSL_ROOT_DIR + BORINGSSL_INCLUDE_DIR + BORINGSSL_LIBRARIES + BORINGSSL_CRYPTO_LIBRARY + BORINGSSL_SSL_LIBRARY +) + +set(CMAKE_FIND_LIBRARY_SUFFIXES ${_boringssl_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) diff --git a/src/brpc/details/ssl_helper.cpp b/src/brpc/details/ssl_helper.cpp index 81460aa99c..a02752614c 100644 --- a/src/brpc/details/ssl_helper.cpp +++ b/src/brpc/details/ssl_helper.cpp @@ -17,6 +17,7 @@ +#include #ifndef USE_MESALINK #include // recv @@ -212,7 +213,7 @@ void ExtractHostnames(X509* x, std::vector* hostnames) { STACK_OF(GENERAL_NAME)* names = (STACK_OF(GENERAL_NAME)*) X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); if (names) { - for (int i = 0; i < sk_GENERAL_NAME_num(names); i++) { + for (size_t i = 0; i < static_cast(sk_GENERAL_NAME_num(names)); i++) { char* str = NULL; GENERAL_NAME* name = sk_GENERAL_NAME_value(names, i); if (name->type == GEN_DNS) { @@ -591,14 +592,18 @@ SSL* CreateSSLSession(SSL_CTX* ctx, SocketId id, int fd, bool server_mode) { } void AddBIOBuffer(SSL* ssl, int fd, int bufsize) { - BIO* rbio = BIO_new(BIO_f_buffer()); +#if defined(OPENSSL_IS_BORINGSSL) + BIO *rbio = BIO_new(BIO_s_mem()); + BIO *wbio = BIO_new(BIO_s_mem()); +#else + BIO *rbio = BIO_new(BIO_f_buffer()); BIO_set_buffer_size(rbio, bufsize); + BIO *wbio = BIO_new(BIO_f_buffer()); + BIO_set_buffer_size(wbio, bufsize); +#endif BIO* rfd = BIO_new(BIO_s_fd()); BIO_set_fd(rfd, fd, 0); rbio = BIO_push(rbio, rfd); - - BIO* wbio = BIO_new(BIO_f_buffer()); - BIO_set_buffer_size(wbio, bufsize); BIO* wfd = BIO_new(BIO_s_fd()); BIO_set_fd(wfd, fd, 0); wbio = BIO_push(wbio, wfd); diff --git a/src/brpc/server.cpp b/src/brpc/server.cpp index c25cd5f001..99add51976 100644 --- a/src/brpc/server.cpp +++ b/src/brpc/server.cpp @@ -2246,8 +2246,9 @@ bool Server::AcceptRequest(Controller* cntl) const { #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME int Server::SSLSwitchCTXByHostname(struct ssl_st* ssl, - int* al, Server* server) { + int* al, void* se) { (void)al; + Server* server = reinterpret_cast(se); const char* hostname = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); bool strict_sni = server->_options.ssl_options().strict_sni; if (hostname == NULL) { diff --git a/src/brpc/server.h b/src/brpc/server.h index 982c6701f1..c2ba87d821 100644 --- a/src/brpc/server.h +++ b/src/brpc/server.h @@ -660,7 +660,7 @@ friend class Controller; void FreeSSLContexts(); static int SSLSwitchCTXByHostname(struct ssl_st* ssl, - int* al, Server* server); + int* al, void* se); static bool AddCertMapping(CertMaps& bg, const SSLContext& ssl_ctx); static bool RemoveCertMapping(CertMaps& bg, const SSLContext& ssl_ctx); diff --git a/src/butil/iobuf.cpp b/src/butil/iobuf.cpp index b585c92c8e..e439526606 100644 --- a/src/butil/iobuf.cpp +++ b/src/butil/iobuf.cpp @@ -38,6 +38,10 @@ #include "butil/fd_guard.h" // butil::fd_guard #include "butil/iobuf.h" +#if defined (OPENSSL_IS_BORINGSSL) +#include "butil/ssl_compat.h" // BIO_fd_non_fatal_error +#endif + namespace butil { namespace iobuf { @@ -2151,7 +2155,7 @@ bool IOBufBytesIterator::forward_one_block(const void** data, size_t* size) { return true; } -} // namespace butil +} // namespace butil void* fast_memcpy(void *__restrict dest, const void *__restrict src, size_t n) { return butil::iobuf::cp(dest, src, n); diff --git a/src/butil/ssl_compat.h b/src/butil/ssl_compat.h index 370edb0294..a42c0b4ee2 100644 --- a/src/butil/ssl_compat.h +++ b/src/butil/ssl_compat.h @@ -21,7 +21,7 @@ #include #include -/* Provide functions added in newer openssl but missing in older versions */ +/* Provide functions added in newer openssl but missing in older versions or boringssl */ #if defined(__cplusplus) || __STDC_VERSION__ >= 199901L/*C99*/ #define BRPC_INLINE inline @@ -324,7 +324,7 @@ BRPC_INLINE int RSA_bits(const RSA *r) { #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ -#if OPENSSL_VERSION_NUMBER < 0x0090801fL +#if OPENSSL_VERSION_NUMBER < 0x0090801fL || defined (OPENSSL_IS_BORINGSSL) BRPC_INLINE BIGNUM* get_rfc2409_prime_1024(BIGNUM* bn) { static const unsigned char RFC2409_PRIME_1024[] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2, @@ -516,6 +516,39 @@ BRPC_INLINE int EVP_PKEY_base_id(const EVP_PKEY *pkey) { return EVP_PKEY_type(pkey->type); } -#endif /* OPENSSL_VERSION_NUMBER < 0x0090801fL */ +#endif /* OPENSSL_VERSION_NUMBER < 0x0090801fL || OPENSSL_IS_BORINGSSL */ +#if defined(OPENSSL_IS_BORINGSSL) +BRPC_INLINE int BIO_fd_non_fatal_error(int err) { + if ( +#ifdef EWOULDBLOCK + err == EWOULDBLOCK || +#endif +#ifdef WSAEWOULDBLOCK + err == WSAEWOULDBLOCK || +#endif +#ifdef ENOTCONN + err == ENOTCONN || +#endif +#ifdef EINTR + err == EINTR || +#endif +#ifdef EAGAIN + err == EAGAIN || +#endif +#ifdef EPROTO + err == EPROTO || +#endif +#ifdef EINPROGRESS + err == EINPROGRESS || +#endif +#ifdef EALREADY + err == EALREADY || +#endif + 0) { + return 1; + } + return 0; +} +#endif /*OPENSSL_IS_BORINGSSL*/ #endif /* BUTIL_SSL_COMPAT_H */