Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/brpc/details/ssl_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ static int ParseSSLProtocols(const std::string& str_protocol) {
protocol_flag |= TLSv1_1;
} else if (strncasecmp(protocol.data(), "TLSv1.2", protocol.size()) == 0) {
protocol_flag |= TLSv1_2;
} else if (strncasecmp(protocol.data(), "TLSv1.3", protocol.size()) == 0) {
protocol_flag |= TLSv1_3;
} else {
LOG(ERROR) << "Unknown SSL protocol=" << protocol;
return -1;
Expand Down Expand Up @@ -443,6 +445,12 @@ static int SetSSLOptions(SSL_CTX* ctx, const std::string& ciphers,
ssloptions |= SSL_OP_NO_TLSv1_2;
}
#endif // SSL_OP_NO_TLSv1_2

#ifdef SSL_OP_NO_TLSv1_3
if (!(protocols & TLSv1_3)) {
ssloptions |= SSL_OP_NO_TLSv1_3;
}
#endif // SSL_OP_NO_TLSv1_3
SSL_CTX_set_options(ctx, ssloptions);

long sslmode = SSL_MODE_ENABLE_PARTIAL_WRITE
Expand Down Expand Up @@ -585,7 +593,7 @@ SSL_CTX* CreateServerSSLContext(const std::string& certificate,
return NULL;
}

int protocols = TLSv1 | TLSv1_1 | TLSv1_2;
int protocols = TLSv1 | TLSv1_1 | TLSv1_2 | TLSv1_3;
if (!options.disable_ssl3) {
protocols |= SSLv3;
}
Expand Down
1 change: 1 addition & 0 deletions src/brpc/details/ssl_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ enum SSLProtocol {
TLSv1 = 1 << 1,
TLSv1_1 = 1 << 2,
TLSv1_2 = 1 << 3,
TLSv1_3 = 1 << 4,
};

struct FreeSSLCTX {
Expand Down
2 changes: 1 addition & 1 deletion src/brpc/ssl_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ VerifyOptions::VerifyOptions()

ChannelSSLOptions::ChannelSSLOptions()
: ciphers("DEFAULT")
, protocols("TLSv1, TLSv1.1, TLSv1.2")
, protocols("TLSv1, TLSv1.1, TLSv1.2, TLSv1.3")
{}

ServerSSLOptions::ServerSSLOptions()
Expand Down
4 changes: 2 additions & 2 deletions src/brpc/ssl_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ struct ChannelSSLOptions {
std::string ciphers;

// SSL protocols used for SSL handshake, separated by comma.
// Available protocols: SSLv3, TLSv1, TLSv1.1, TLSv1.2
// Default: TLSv1, TLSv1.1, TLSv1.2
// Available protocols: SSLv3, TLSv1, TLSv1.1, TLSv1.2, TLSv1.3
// Default: TLSv1, TLSv1.1, TLSv1.2, TLSv1.3
std::string protocols;

// When set, fill this into the SNI extension field during handshake,
Expand Down
66 changes: 66 additions & 0 deletions test/brpc_ssl_unittest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "brpc/channel.h"
#include "brpc/socket_map.h"
#include "brpc/controller.h"
#include "brpc/details/ssl_helper.h"
#include "echo.pb.h"

namespace brpc {
Expand Down Expand Up @@ -497,3 +498,68 @@ TEST_F(SSLTest, ssl_perf) {
close(clifd);
close(servfd);
}


#ifdef TLS1_3_VERSION

void* tls13_do_handshake(void* arg) {
SSL* ssl = (SSL*)arg;
EXPECT_EQ(1, SSL_do_handshake(ssl));
return NULL;
}

TEST_F(SSLTest, tls13_protocol_string) {
// Same style as ssl_perf: direct SSL handshake, no SocketMap / socket internals.
const butil::EndPoint ep(butil::IP_ANY, 8613);
butil::fd_guard listenfd(butil::tcp_listen(ep));
ASSERT_GT(listenfd, 0);
int clifd = tcp_connect(ep, NULL);
ASSERT_GT(clifd, 0);
int servfd = accept(listenfd, NULL, NULL);
ASSERT_GT(servfd, 0);

brpc::ChannelSSLOptions opt;
opt.protocols = "TLSv1.3";
SSL_CTX* cli_ctx = brpc::CreateClientSSLContext(opt);
ASSERT_NE(nullptr, cli_ctx);
SSL_CTX* serv_ctx =
brpc::CreateServerSSLContext("cert1.crt", "cert1.key",
brpc::SSLOptions(), NULL, NULL);
ASSERT_NE(nullptr, serv_ctx);
SSL* cli_ssl = brpc::CreateSSLSession(cli_ctx, 0, clifd, false);
#if defined(SSL_CTRL_SET_TLSEXT_HOSTNAME) || defined(USE_MESALINK)
SSL_set_tlsext_host_name(cli_ssl, "localhost");
#endif
SSL* serv_ssl = brpc::CreateSSLSession(serv_ctx, 0, servfd, true);
ASSERT_NE(nullptr, cli_ssl);
ASSERT_NE(nullptr, serv_ssl);
pthread_t cpid;
pthread_t spid;
ASSERT_EQ(0, pthread_create(&cpid, NULL, tls13_do_handshake, cli_ssl));
ASSERT_EQ(0, pthread_create(&spid, NULL, tls13_do_handshake, serv_ssl));
ASSERT_EQ(0, pthread_join(cpid, NULL));
ASSERT_EQ(0, pthread_join(spid, NULL));

const char* version = SSL_get_version(cli_ssl);
ASSERT_TRUE(version != NULL);
EXPECT_STREQ("TLSv1.3", version) << "negotiated protocol=" << version;

SSL_free(cli_ssl);
SSL_free(serv_ssl);
SSL_CTX_free(cli_ctx);
SSL_CTX_free(serv_ctx);
close(clifd);
close(servfd);
}

#else // TLS1_3_VERSION

TEST_F(SSLTest, tls13_protocol_string) {
brpc::ChannelSSLOptions opt;
opt.protocols = "TLSv1.3";
SSL_CTX* ctx = brpc::CreateClientSSLContext(opt);
ASSERT_TRUE(ctx != NULL);
SSL_CTX_free(ctx);
}

#endif // TLS1_3_VERSION
Loading