Skip to content

Commit ce58581

Browse files
neilxxxxxlairongzeng
andauthored
feat:Support for TLSv1.3 (#3319)
* feat:Support for TLSv1.3 * Align other UTs in this file --------- Co-authored-by: lairongzeng <lairongzeng@bigo.sg>
1 parent a4ddf97 commit ce58581

5 files changed

Lines changed: 67 additions & 68 deletions

File tree

src/brpc/details/ssl_helper.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ static int ParseSSLProtocols(const std::string& str_protocol) {
8686
protocol_flag |= TLSv1_1;
8787
} else if (strncasecmp(protocol.data(), "TLSv1.2", protocol.size()) == 0) {
8888
protocol_flag |= TLSv1_2;
89+
} else if (strncasecmp(protocol.data(), "TLSv1.3", protocol.size()) == 0) {
90+
protocol_flag |= TLSv1_3;
8991
} else {
9092
LOG(ERROR) << "Unknown SSL protocol=" << protocol;
9193
return -1;
@@ -443,6 +445,12 @@ static int SetSSLOptions(SSL_CTX* ctx, const std::string& ciphers,
443445
ssloptions |= SSL_OP_NO_TLSv1_2;
444446
}
445447
#endif // SSL_OP_NO_TLSv1_2
448+
449+
#ifdef SSL_OP_NO_TLSv1_3
450+
if (!(protocols & TLSv1_3)) {
451+
ssloptions |= SSL_OP_NO_TLSv1_3;
452+
}
453+
#endif // SSL_OP_NO_TLSv1_3
446454
SSL_CTX_set_options(ctx, ssloptions);
447455

448456
long sslmode = SSL_MODE_ENABLE_PARTIAL_WRITE
@@ -585,7 +593,7 @@ SSL_CTX* CreateServerSSLContext(const std::string& certificate,
585593
return NULL;
586594
}
587595

588-
int protocols = TLSv1 | TLSv1_1 | TLSv1_2;
596+
int protocols = TLSv1 | TLSv1_1 | TLSv1_2 | TLSv1_3;
589597
if (!options.disable_ssl3) {
590598
protocols |= SSLv3;
591599
}

src/brpc/details/ssl_helper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ enum SSLProtocol {
5353
TLSv1 = 1 << 1,
5454
TLSv1_1 = 1 << 2,
5555
TLSv1_2 = 1 << 3,
56+
TLSv1_3 = 1 << 4,
5657
};
5758

5859
struct FreeSSLCTX {

src/brpc/ssl_options.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ VerifyOptions::VerifyOptions()
2727

2828
ChannelSSLOptions::ChannelSSLOptions()
2929
: ciphers("DEFAULT")
30-
, protocols("TLSv1, TLSv1.1, TLSv1.2")
30+
, protocols("TLSv1, TLSv1.1, TLSv1.2, TLSv1.3")
3131
{}
3232

3333
ServerSSLOptions::ServerSSLOptions()

src/brpc/ssl_options.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ struct ChannelSSLOptions {
7979
std::string ciphers;
8080

8181
// SSL protocols used for SSL handshake, separated by comma.
82-
// Available protocols: SSLv3, TLSv1, TLSv1.1, TLSv1.2
83-
// Default: TLSv1, TLSv1.1, TLSv1.2
82+
// Available protocols: SSLv3, TLSv1, TLSv1.1, TLSv1.2, TLSv1.3
83+
// Default: TLSv1, TLSv1.1, TLSv1.2, TLSv1.3
8484
std::string protocols;
8585

8686
// When set, fill this into the SNI extension field during handshake,

test/brpc_ssl_unittest.cpp

Lines changed: 54 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "brpc/channel.h"
3636
#include "brpc/socket_map.h"
3737
#include "brpc/controller.h"
38+
#include "brpc/details/ssl_helper.h"
3839
#include "echo.pb.h"
3940

4041
namespace brpc {
@@ -498,78 +499,67 @@ TEST_F(SSLTest, ssl_perf) {
498499
close(servfd);
499500
}
500501

501-
struct AbruptCloseArgs { int listenfd; };
502-
503-
static void* abrupt_close_server(void* arg) {
504-
AbruptCloseArgs* a = (AbruptCloseArgs*)arg;
505-
int connfd = accept(a->listenfd, NULL, NULL);
506-
if (connfd < 0) return NULL;
507-
SSL_CTX* ctx = brpc::CreateServerSSLContext(
508-
"cert1.crt", "cert1.key", brpc::SSLOptions(), NULL, NULL);
509-
SSL* ssl = brpc::CreateSSLSession(ctx, 0, connfd, true);
510-
if (ssl) { SSL_do_handshake(ssl); SSL_free(ssl); }
511-
close(connfd);
502+
503+
#ifdef TLS1_3_VERSION
504+
505+
void* tls13_do_handshake(void* arg) {
506+
SSL* ssl = (SSL*)arg;
507+
EXPECT_EQ(1, SSL_do_handshake(ssl));
512508
return NULL;
513509
}
514510

515-
TEST_F(SSLTest, ssl_unexpected_eof) {
516-
// Verify that Socket::DoRead() returns -1 with errno=ESSL when the
517-
// remote side closes the TCP connection without sending close_notify.
518-
// Without the fix, DoRead() returns 0, causing error_code=0 to
519-
// propagate to Controller::SetFailed() which triggers CHECK(false).
520-
521-
const int port = 5962;
522-
butil::EndPoint ep(butil::IP_ANY, port);
511+
TEST_F(SSLTest, tls13_protocol_string) {
512+
// Same style as ssl_perf: direct SSL handshake, no SocketMap / socket internals.
513+
const butil::EndPoint ep(butil::IP_ANY, 8613);
523514
butil::fd_guard listenfd(butil::tcp_listen(ep));
524515
ASSERT_GT(listenfd, 0);
516+
int clifd = tcp_connect(ep, NULL);
517+
ASSERT_GT(clifd, 0);
518+
int servfd = accept(listenfd, NULL, NULL);
519+
ASSERT_GT(servfd, 0);
525520

526-
AbruptCloseArgs server_args = { listenfd };
527-
pthread_t server_tid;
528-
ASSERT_EQ(0, pthread_create(&server_tid, NULL, abrupt_close_server,
529-
&server_args));
530-
531-
brpc::Protocol dummy_protocol = {
532-
brpc::policy::ParseRpcMessage, brpc::SerializeRequestDefault,
533-
brpc::policy::PackRpcRequest, NULL, ProcessResponse,
534-
NULL, NULL, NULL, brpc::CONNECTION_TYPE_ALL, "ssl_ut_eof"
535-
};
536-
ASSERT_EQ(0, RegisterProtocol((brpc::ProtocolType)31, dummy_protocol));
537-
538-
brpc::InputMessageHandler dummy_handler = {
539-
dummy_protocol.parse, dummy_protocol.process_response,
540-
NULL, NULL, dummy_protocol.name
541-
};
542-
brpc::InputMessenger messenger;
543-
ASSERT_EQ(0, messenger.AddHandler(dummy_handler));
544-
545-
brpc::SocketOptions socket_options;
546-
butil::EndPoint server_ep(butil::IP_ANY, port);
547-
socket_options.remote_side = server_ep;
548-
socket_options.connect_on_create = true;
549-
// Do NOT set on_edge_triggered_events — we will call DoRead manually.
550-
socket_options.user = &messenger;
551-
552-
brpc::ChannelSSLOptions ssl_options;
553-
SSL_CTX* raw_ctx = brpc::CreateClientSSLContext(ssl_options);
554-
ASSERT_NE(nullptr, raw_ctx);
555-
std::shared_ptr<brpc::SocketSSLContext> ssl_ctx =
556-
std::make_shared<brpc::SocketSSLContext>();
557-
ssl_ctx->raw_ctx = raw_ctx;
558-
socket_options.initial_ssl_ctx = ssl_ctx;
521+
brpc::ChannelSSLOptions opt;
522+
opt.protocols = "TLSv1.3";
523+
SSL_CTX* cli_ctx = brpc::CreateClientSSLContext(opt);
524+
ASSERT_NE(nullptr, cli_ctx);
525+
SSL_CTX* serv_ctx =
526+
brpc::CreateServerSSLContext("cert1.crt", "cert1.key",
527+
brpc::SSLOptions(), NULL, NULL);
528+
ASSERT_NE(nullptr, serv_ctx);
529+
SSL* cli_ssl = brpc::CreateSSLSession(cli_ctx, 0, clifd, false);
530+
#if defined(SSL_CTRL_SET_TLSEXT_HOSTNAME) || defined(USE_MESALINK)
531+
SSL_set_tlsext_host_name(cli_ssl, "localhost");
532+
#endif
533+
SSL* serv_ssl = brpc::CreateSSLSession(serv_ctx, 0, servfd, true);
534+
ASSERT_NE(nullptr, cli_ssl);
535+
ASSERT_NE(nullptr, serv_ssl);
536+
pthread_t cpid;
537+
pthread_t spid;
538+
ASSERT_EQ(0, pthread_create(&cpid, NULL, tls13_do_handshake, cli_ssl));
539+
ASSERT_EQ(0, pthread_create(&spid, NULL, tls13_do_handshake, serv_ssl));
540+
ASSERT_EQ(0, pthread_join(cpid, NULL));
541+
ASSERT_EQ(0, pthread_join(spid, NULL));
559542

560-
brpc::SocketId socket_id;
561-
ASSERT_EQ(0, brpc::Socket::Create(socket_options, &socket_id));
562-
brpc::SocketUniquePtr ptr;
563-
ASSERT_EQ(0, brpc::Socket::Address(socket_id, &ptr));
543+
const char* version = SSL_get_version(cli_ssl);
544+
ASSERT_TRUE(version != NULL);
545+
EXPECT_STREQ("TLSv1.3", version) << "negotiated protocol=" << version;
564546

565-
// Wait for server to close the connection without close_notify.
566-
pthread_join(server_tid, NULL);
567-
usleep(50000);
547+
SSL_free(cli_ssl);
548+
SSL_free(serv_ssl);
549+
SSL_CTX_free(cli_ctx);
550+
SSL_CTX_free(serv_ctx);
551+
close(clifd);
552+
close(servfd);
553+
}
568554

569-
// DoRead should detect the unexpected EOF and return -1 with errno=ESSL.
570-
ssize_t nr = ptr->DoRead(1024);
571-
EXPECT_EQ(-1, nr);
572-
EXPECT_EQ(brpc::ESSL, errno);
555+
#else // TLS1_3_VERSION
573556

574-
ptr->SetFailed();
557+
TEST_F(SSLTest, tls13_protocol_string) {
558+
brpc::ChannelSSLOptions opt;
559+
opt.protocols = "TLSv1.3";
560+
SSL_CTX* ctx = brpc::CreateClientSSLContext(opt);
561+
ASSERT_TRUE(ctx != NULL);
562+
SSL_CTX_free(ctx);
575563
}
564+
565+
#endif // TLS1_3_VERSION

0 commit comments

Comments
 (0)