2 * Copyright 2016 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 #include <folly/io/async/test/AsyncSSLSocketTest.h>
21 #include <folly/io/async/AsyncSSLSocket.h>
22 #include <folly/io/async/EventBase.h>
23 #include <folly/SocketAddress.h>
25 #include <folly/io/async/test/BlockingSocket.h>
28 #include <gtest/gtest.h>
34 #include <openssl/bio.h>
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <netinet/tcp.h>
39 #include <folly/io/Cursor.h>
49 uint32_t TestSSLAsyncCacheServer::asyncCallbacks_ = 0;
50 uint32_t TestSSLAsyncCacheServer::asyncLookups_ = 0;
51 uint32_t TestSSLAsyncCacheServer::lookupDelay_ = 0;
53 const char* testCert = "folly/io/async/test/certs/tests-cert.pem";
54 const char* testKey = "folly/io/async/test/certs/tests-key.pem";
55 const char* testCA = "folly/io/async/test/certs/ca-cert.pem";
57 constexpr size_t SSLClient::kMaxReadBufferSz;
58 constexpr size_t SSLClient::kMaxReadsPerEvent;
60 TestSSLServer::TestSSLServer(SSLServerAcceptCallbackBase* acb)
61 : ctx_(new folly::SSLContext),
63 socket_(folly::AsyncServerSocket::newSocket(&evb_)) {
64 // Set up the SSL context
65 ctx_->loadCertificate(testCert);
66 ctx_->loadPrivateKey(testKey);
67 ctx_->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
72 //set up the listening socket
74 socket_->getAddress(&address_);
76 socket_->addAcceptCallback(acb_, &evb_);
77 socket_->startAccepting();
79 int ret = pthread_create(&thread_, nullptr, Main, this);
83 std::cerr << "Accepting connections on " << address_ << std::endl;
86 void getfds(int fds[2]) {
87 if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) != 0) {
88 FAIL() << "failed to create socketpair: " << strerror(errno);
90 for (int idx = 0; idx < 2; ++idx) {
91 int flags = fcntl(fds[idx], F_GETFL, 0);
93 FAIL() << "failed to get flags for socket " << idx << ": "
96 if (fcntl(fds[idx], F_SETFL, flags | O_NONBLOCK) != 0) {
97 FAIL() << "failed to put socket " << idx << " in non-blocking mode: "
104 std::shared_ptr<folly::SSLContext> clientCtx,
105 std::shared_ptr<folly::SSLContext> serverCtx) {
106 clientCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
108 serverCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
109 serverCtx->loadCertificate(
111 serverCtx->loadPrivateKey(
116 EventBase* eventBase,
117 AsyncSSLSocket::UniquePtr* clientSock,
118 AsyncSSLSocket::UniquePtr* serverSock) {
119 auto clientCtx = std::make_shared<folly::SSLContext>();
120 auto serverCtx = std::make_shared<folly::SSLContext>();
123 getctx(clientCtx, serverCtx);
124 clientSock->reset(new AsyncSSLSocket(
125 clientCtx, eventBase, fds[0], false));
126 serverSock->reset(new AsyncSSLSocket(
127 serverCtx, eventBase, fds[1], true));
129 // (*clientSock)->setSendTimeout(100);
130 // (*serverSock)->setSendTimeout(100);
133 // client protocol filters
134 bool clientProtoFilterPickPony(unsigned char** client,
135 unsigned int* client_len, const unsigned char*, unsigned int ) {
136 //the protocol string in length prefixed byte string. the
137 //length byte is not included in the length
138 static unsigned char p[7] = {6,'p','o','n','i','e','s'};
144 bool clientProtoFilterPickNone(unsigned char**, unsigned int*,
145 const unsigned char*, unsigned int) {
149 std::string getFileAsBuf(const char* fileName) {
151 folly::readFile(fileName, buffer);
155 std::string getCommonName(X509* cert) {
156 X509_NAME* subject = X509_get_subject_name(cert);
158 cn.resize(ub_common_name);
159 X509_NAME_get_text_by_NID(
160 subject, NID_commonName, const_cast<char*>(cn.data()), ub_common_name);
165 * Test connecting to, writing to, reading from, and closing the
166 * connection to the SSL server.
168 TEST(AsyncSSLSocketTest, ConnectWriteReadClose) {
169 // Start listening on a local port
170 WriteCallbackBase writeCallback;
171 ReadCallback readCallback(&writeCallback);
172 HandshakeCallback handshakeCallback(&readCallback);
173 SSLServerAcceptCallback acceptCallback(&handshakeCallback);
174 TestSSLServer server(&acceptCallback);
176 // Set up SSL context.
177 std::shared_ptr<SSLContext> sslContext(new SSLContext());
178 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
179 //sslContext->loadTrustedCertificates("./trusted-ca-certificate.pem");
180 //sslContext->authenticate(true, false);
183 auto socket = std::make_shared<BlockingSocket>(server.getAddress(),
189 memset(buf, 'a', sizeof(buf));
190 socket->write(buf, sizeof(buf));
193 uint8_t readbuf[128];
194 uint32_t bytesRead = socket->readAll(readbuf, sizeof(readbuf));
195 EXPECT_EQ(bytesRead, 128);
196 EXPECT_EQ(memcmp(buf, readbuf, bytesRead), 0);
201 cerr << "ConnectWriteReadClose test completed" << endl;
205 * Test reading after server close.
207 TEST(AsyncSSLSocketTest, ReadAfterClose) {
208 // Start listening on a local port
209 WriteCallbackBase writeCallback;
210 ReadEOFCallback readCallback(&writeCallback);
211 HandshakeCallback handshakeCallback(&readCallback);
212 SSLServerAcceptCallback acceptCallback(&handshakeCallback);
213 auto server = folly::make_unique<TestSSLServer>(&acceptCallback);
215 // Set up SSL context.
216 auto sslContext = std::make_shared<SSLContext>();
217 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
220 std::make_shared<BlockingSocket>(server->getAddress(), sslContext);
223 // This should trigger an EOF on the client.
224 auto evb = handshakeCallback.getSocket()->getEventBase();
225 evb->runInEventBaseThreadAndWait([&]() { handshakeCallback.closeSocket(); });
226 std::array<uint8_t, 128> readbuf;
227 auto bytesRead = socket->read(readbuf.data(), readbuf.size());
228 EXPECT_EQ(0, bytesRead);
232 * Test bad renegotiation
234 TEST(AsyncSSLSocketTest, Renegotiate) {
236 auto clientCtx = std::make_shared<SSLContext>();
237 auto dfServerCtx = std::make_shared<SSLContext>();
238 std::array<int, 2> fds;
240 getctx(clientCtx, dfServerCtx);
242 AsyncSSLSocket::UniquePtr clientSock(
243 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
244 AsyncSSLSocket::UniquePtr serverSock(
245 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
246 SSLHandshakeClient client(std::move(clientSock), true, true);
247 RenegotiatingServer server(std::move(serverSock));
249 while (!client.handshakeSuccess_ && !client.handshakeError_) {
250 eventBase.loopOnce();
253 ASSERT_TRUE(client.handshakeSuccess_);
255 auto sslSock = std::move(client).moveSocket();
256 sslSock->detachEventBase();
257 // This is nasty, however we don't want to add support for
258 // renegotiation in AsyncSSLSocket.
259 SSL_renegotiate(const_cast<SSL*>(sslSock->getSSL()));
261 auto socket = std::make_shared<BlockingSocket>(std::move(sslSock));
263 std::thread t([&]() { eventBase.loopForever(); });
265 // Trigger the renegotiation.
266 std::array<uint8_t, 128> buf;
267 memset(buf.data(), 'a', buf.size());
269 socket->write(buf.data(), buf.size());
270 } catch (AsyncSocketException& e) {
271 LOG(INFO) << "client got error " << e.what();
273 eventBase.terminateLoopSoon();
277 ASSERT_TRUE(server.renegotiationError_);
281 * Negative test for handshakeError().
283 TEST(AsyncSSLSocketTest, HandshakeError) {
284 // Start listening on a local port
285 WriteCallbackBase writeCallback;
286 WriteErrorCallback readCallback(&writeCallback);
287 HandshakeCallback handshakeCallback(&readCallback);
288 HandshakeErrorCallback acceptCallback(&handshakeCallback);
289 TestSSLServer server(&acceptCallback);
291 // Set up SSL context.
292 std::shared_ptr<SSLContext> sslContext(new SSLContext());
293 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
296 auto socket = std::make_shared<BlockingSocket>(server.getAddress(),
303 uint8_t readbuf[128];
304 uint32_t bytesRead = socket->readAll(readbuf, sizeof(readbuf));
305 LOG(ERROR) << "readAll returned " << bytesRead << " instead of throwing";
306 } catch (AsyncSocketException &e) {
313 cerr << "HandshakeError test completed" << endl;
317 * Negative test for readError().
319 TEST(AsyncSSLSocketTest, ReadError) {
320 // Start listening on a local port
321 WriteCallbackBase writeCallback;
322 ReadErrorCallback readCallback(&writeCallback);
323 HandshakeCallback handshakeCallback(&readCallback);
324 SSLServerAcceptCallback acceptCallback(&handshakeCallback);
325 TestSSLServer server(&acceptCallback);
327 // Set up SSL context.
328 std::shared_ptr<SSLContext> sslContext(new SSLContext());
329 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
332 auto socket = std::make_shared<BlockingSocket>(server.getAddress(),
336 // write something to trigger ssl handshake
338 memset(buf, 'a', sizeof(buf));
339 socket->write(buf, sizeof(buf));
342 cerr << "ReadError test completed" << endl;
346 * Negative test for writeError().
348 TEST(AsyncSSLSocketTest, WriteError) {
349 // Start listening on a local port
350 WriteCallbackBase writeCallback;
351 WriteErrorCallback readCallback(&writeCallback);
352 HandshakeCallback handshakeCallback(&readCallback);
353 SSLServerAcceptCallback acceptCallback(&handshakeCallback);
354 TestSSLServer server(&acceptCallback);
356 // Set up SSL context.
357 std::shared_ptr<SSLContext> sslContext(new SSLContext());
358 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
361 auto socket = std::make_shared<BlockingSocket>(server.getAddress(),
365 // write something to trigger ssl handshake
367 memset(buf, 'a', sizeof(buf));
368 socket->write(buf, sizeof(buf));
371 cerr << "WriteError test completed" << endl;
375 * Test a socket with TCP_NODELAY unset.
377 TEST(AsyncSSLSocketTest, SocketWithDelay) {
378 // Start listening on a local port
379 WriteCallbackBase writeCallback;
380 ReadCallback readCallback(&writeCallback);
381 HandshakeCallback handshakeCallback(&readCallback);
382 SSLServerAcceptCallbackDelay acceptCallback(&handshakeCallback);
383 TestSSLServer server(&acceptCallback);
385 // Set up SSL context.
386 std::shared_ptr<SSLContext> sslContext(new SSLContext());
387 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
390 auto socket = std::make_shared<BlockingSocket>(server.getAddress(),
396 memset(buf, 'a', sizeof(buf));
397 socket->write(buf, sizeof(buf));
400 uint8_t readbuf[128];
401 uint32_t bytesRead = socket->readAll(readbuf, sizeof(readbuf));
402 EXPECT_EQ(bytesRead, 128);
403 EXPECT_EQ(memcmp(buf, readbuf, bytesRead), 0);
408 cerr << "SocketWithDelay test completed" << endl;
411 using NextProtocolTypePair =
412 std::pair<SSLContext::NextProtocolType, SSLContext::NextProtocolType>;
414 class NextProtocolTest : public testing::TestWithParam<NextProtocolTypePair> {
415 // For matching protos
417 void SetUp() override { getctx(clientCtx, serverCtx); }
419 void connect(bool unset = false) {
423 // unsetting NPN for any of [client, server] is enough to make NPN not
425 clientCtx->unsetNextProtocols();
428 AsyncSSLSocket::UniquePtr clientSock(
429 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
430 AsyncSSLSocket::UniquePtr serverSock(
431 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
432 client = folly::make_unique<NpnClient>(std::move(clientSock));
433 server = folly::make_unique<NpnServer>(std::move(serverSock));
438 void expectProtocol(const std::string& proto) {
439 EXPECT_NE(client->nextProtoLength, 0);
440 EXPECT_EQ(client->nextProtoLength, server->nextProtoLength);
442 memcmp(client->nextProto, server->nextProto, server->nextProtoLength),
444 string selected((const char*)client->nextProto, client->nextProtoLength);
445 EXPECT_EQ(proto, selected);
448 void expectNoProtocol() {
449 EXPECT_EQ(client->nextProtoLength, 0);
450 EXPECT_EQ(server->nextProtoLength, 0);
451 EXPECT_EQ(client->nextProto, nullptr);
452 EXPECT_EQ(server->nextProto, nullptr);
455 void expectProtocolType() {
456 if (GetParam().first == SSLContext::NextProtocolType::ANY &&
457 GetParam().second == SSLContext::NextProtocolType::ANY) {
458 EXPECT_EQ(client->protocolType, server->protocolType);
459 } else if (GetParam().first == SSLContext::NextProtocolType::ANY ||
460 GetParam().second == SSLContext::NextProtocolType::ANY) {
461 // Well not much we can say
463 expectProtocolType(GetParam());
467 void expectProtocolType(NextProtocolTypePair expected) {
468 EXPECT_EQ(client->protocolType, expected.first);
469 EXPECT_EQ(server->protocolType, expected.second);
473 std::shared_ptr<SSLContext> clientCtx{std::make_shared<SSLContext>()};
474 std::shared_ptr<SSLContext> serverCtx{std::make_shared<SSLContext>()};
476 std::unique_ptr<NpnClient> client;
477 std::unique_ptr<NpnServer> server;
480 class NextProtocolNPNOnlyTest : public NextProtocolTest {
481 // For mismatching protos
484 class NextProtocolMismatchTest : public NextProtocolTest {
485 // For mismatching protos
488 TEST_P(NextProtocolTest, NpnTestOverlap) {
489 clientCtx->setAdvertisedNextProtocols({"blub", "baz"}, GetParam().first);
490 serverCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"},
495 expectProtocol("baz");
496 expectProtocolType();
499 TEST_P(NextProtocolTest, NpnTestUnset) {
500 // Identical to above test, except that we want unset NPN before
502 clientCtx->setAdvertisedNextProtocols({"blub", "baz"}, GetParam().first);
503 serverCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"},
506 connect(true /* unset */);
508 // if alpn negotiation fails, type will appear as npn
510 EXPECT_EQ(client->protocolType, server->protocolType);
513 TEST_P(NextProtocolMismatchTest, NpnAlpnTestNoOverlap) {
514 clientCtx->setAdvertisedNextProtocols({"foo"}, GetParam().first);
515 serverCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"},
522 {SSLContext::NextProtocolType::NPN, SSLContext::NextProtocolType::NPN});
525 TEST_P(NextProtocolNPNOnlyTest, NpnTestNoOverlap) {
526 clientCtx->setAdvertisedNextProtocols({"blub"}, GetParam().first);
527 serverCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"},
532 expectProtocol("blub");
533 expectProtocolType();
536 TEST_P(NextProtocolNPNOnlyTest, NpnTestClientProtoFilterHit) {
537 clientCtx->setAdvertisedNextProtocols({"blub"}, GetParam().first);
538 clientCtx->setClientProtocolFilterCallback(clientProtoFilterPickPony);
539 serverCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"},
544 expectProtocol("ponies");
545 expectProtocolType();
548 TEST_P(NextProtocolNPNOnlyTest, NpnTestClientProtoFilterMiss) {
549 clientCtx->setAdvertisedNextProtocols({"blub"}, GetParam().first);
550 clientCtx->setClientProtocolFilterCallback(clientProtoFilterPickNone);
551 serverCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"},
556 expectProtocol("blub");
557 expectProtocolType();
560 TEST_P(NextProtocolTest, RandomizedNpnTest) {
561 // Probability that this test will fail is 2^-64, which could be considered
563 const int kTries = 64;
565 clientCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"},
567 serverCtx->setRandomizedAdvertisedNextProtocols({{1, {"foo"}}, {1, {"bar"}}},
570 std::set<string> selectedProtocols;
571 for (int i = 0; i < kTries; ++i) {
574 EXPECT_NE(client->nextProtoLength, 0);
575 EXPECT_EQ(client->nextProtoLength, server->nextProtoLength);
577 memcmp(client->nextProto, server->nextProto, server->nextProtoLength),
579 string selected((const char*)client->nextProto, client->nextProtoLength);
580 selectedProtocols.insert(selected);
581 expectProtocolType();
583 EXPECT_EQ(selectedProtocols.size(), 2);
586 INSTANTIATE_TEST_CASE_P(
589 ::testing::Values(NextProtocolTypePair(SSLContext::NextProtocolType::NPN,
590 SSLContext::NextProtocolType::NPN),
591 #if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_TLSEXT)
592 NextProtocolTypePair(SSLContext::NextProtocolType::ALPN,
593 SSLContext::NextProtocolType::ALPN),
595 NextProtocolTypePair(SSLContext::NextProtocolType::NPN,
596 SSLContext::NextProtocolType::ANY),
597 #if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_TLSEXT)
598 NextProtocolTypePair(SSLContext::NextProtocolType::ALPN,
599 SSLContext::NextProtocolType::ANY),
601 NextProtocolTypePair(SSLContext::NextProtocolType::ANY,
602 SSLContext::NextProtocolType::ANY)));
604 INSTANTIATE_TEST_CASE_P(
606 NextProtocolNPNOnlyTest,
607 ::testing::Values(NextProtocolTypePair(SSLContext::NextProtocolType::NPN,
608 SSLContext::NextProtocolType::NPN)));
610 #if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_TLSEXT)
611 INSTANTIATE_TEST_CASE_P(
613 NextProtocolMismatchTest,
614 ::testing::Values(NextProtocolTypePair(SSLContext::NextProtocolType::NPN,
615 SSLContext::NextProtocolType::ALPN),
616 NextProtocolTypePair(SSLContext::NextProtocolType::ALPN,
617 SSLContext::NextProtocolType::NPN)));
620 #ifndef OPENSSL_NO_TLSEXT
622 * 1. Client sends TLSEXT_HOSTNAME in client hello.
623 * 2. Server found a match SSL_CTX and use this SSL_CTX to
624 * continue the SSL handshake.
625 * 3. Server sends back TLSEXT_HOSTNAME in server hello.
627 TEST(AsyncSSLSocketTest, SNITestMatch) {
629 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
630 std::shared_ptr<SSLContext> dfServerCtx(new SSLContext);
631 // Use the same SSLContext to continue the handshake after
632 // tlsext_hostname match.
633 std::shared_ptr<SSLContext> hskServerCtx(dfServerCtx);
634 const std::string serverName("xyz.newdev.facebook.com");
637 getctx(clientCtx, dfServerCtx);
639 AsyncSSLSocket::UniquePtr clientSock(
640 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], serverName));
641 AsyncSSLSocket::UniquePtr serverSock(
642 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
643 SNIClient client(std::move(clientSock));
644 SNIServer server(std::move(serverSock),
651 EXPECT_TRUE(client.serverNameMatch);
652 EXPECT_TRUE(server.serverNameMatch);
656 * 1. Client sends TLSEXT_HOSTNAME in client hello.
657 * 2. Server cannot find a matching SSL_CTX and continue to use
658 * the current SSL_CTX to do the handshake.
659 * 3. Server does not send back TLSEXT_HOSTNAME in server hello.
661 TEST(AsyncSSLSocketTest, SNITestNotMatch) {
663 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
664 std::shared_ptr<SSLContext> dfServerCtx(new SSLContext);
665 // Use the same SSLContext to continue the handshake after
666 // tlsext_hostname match.
667 std::shared_ptr<SSLContext> hskServerCtx(dfServerCtx);
668 const std::string clientRequestingServerName("foo.com");
669 const std::string serverExpectedServerName("xyz.newdev.facebook.com");
673 getctx(clientCtx, dfServerCtx);
675 AsyncSSLSocket::UniquePtr clientSock(
676 new AsyncSSLSocket(clientCtx,
679 clientRequestingServerName));
680 AsyncSSLSocket::UniquePtr serverSock(
681 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
682 SNIClient client(std::move(clientSock));
683 SNIServer server(std::move(serverSock),
686 serverExpectedServerName);
690 EXPECT_TRUE(!client.serverNameMatch);
691 EXPECT_TRUE(!server.serverNameMatch);
694 * 1. Client sends TLSEXT_HOSTNAME in client hello.
695 * 2. We then change the serverName.
696 * 3. We expect that we get 'false' as the result for serNameMatch.
699 TEST(AsyncSSLSocketTest, SNITestChangeServerName) {
701 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
702 std::shared_ptr<SSLContext> dfServerCtx(new SSLContext);
703 // Use the same SSLContext to continue the handshake after
704 // tlsext_hostname match.
705 std::shared_ptr<SSLContext> hskServerCtx(dfServerCtx);
706 const std::string serverName("xyz.newdev.facebook.com");
709 getctx(clientCtx, dfServerCtx);
711 AsyncSSLSocket::UniquePtr clientSock(
712 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], serverName));
713 //Change the server name
714 std::string newName("new.com");
715 clientSock->setServerName(newName);
716 AsyncSSLSocket::UniquePtr serverSock(
717 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
718 SNIClient client(std::move(clientSock));
719 SNIServer server(std::move(serverSock),
726 EXPECT_TRUE(!client.serverNameMatch);
730 * 1. Client does not send TLSEXT_HOSTNAME in client hello.
731 * 2. Server does not send back TLSEXT_HOSTNAME in server hello.
733 TEST(AsyncSSLSocketTest, SNITestClientHelloNoHostname) {
735 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
736 std::shared_ptr<SSLContext> dfServerCtx(new SSLContext);
737 // Use the same SSLContext to continue the handshake after
738 // tlsext_hostname match.
739 std::shared_ptr<SSLContext> hskServerCtx(dfServerCtx);
740 const std::string serverExpectedServerName("xyz.newdev.facebook.com");
744 getctx(clientCtx, dfServerCtx);
746 AsyncSSLSocket::UniquePtr clientSock(
747 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
748 AsyncSSLSocket::UniquePtr serverSock(
749 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
750 SNIClient client(std::move(clientSock));
751 SNIServer server(std::move(serverSock),
754 serverExpectedServerName);
758 EXPECT_TRUE(!client.serverNameMatch);
759 EXPECT_TRUE(!server.serverNameMatch);
764 * Test SSL client socket
766 TEST(AsyncSSLSocketTest, SSLClientTest) {
767 // Start listening on a local port
768 WriteCallbackBase writeCallback;
769 ReadCallback readCallback(&writeCallback);
770 HandshakeCallback handshakeCallback(&readCallback);
771 SSLServerAcceptCallbackDelay acceptCallback(&handshakeCallback);
772 TestSSLServer server(&acceptCallback);
776 auto client = std::make_shared<SSLClient>(&eventBase, server.getAddress(), 1);
779 EventBaseAborter eba(&eventBase, 3000);
782 EXPECT_EQ(client->getMiss(), 1);
783 EXPECT_EQ(client->getHit(), 0);
785 cerr << "SSLClientTest test completed" << endl;
790 * Test SSL client socket session re-use
792 TEST(AsyncSSLSocketTest, SSLClientTestReuse) {
793 // Start listening on a local port
794 WriteCallbackBase writeCallback;
795 ReadCallback readCallback(&writeCallback);
796 HandshakeCallback handshakeCallback(&readCallback);
797 SSLServerAcceptCallbackDelay acceptCallback(&handshakeCallback);
798 TestSSLServer server(&acceptCallback);
803 std::make_shared<SSLClient>(&eventBase, server.getAddress(), 10);
806 EventBaseAborter eba(&eventBase, 3000);
809 EXPECT_EQ(client->getMiss(), 1);
810 EXPECT_EQ(client->getHit(), 9);
812 cerr << "SSLClientTestReuse test completed" << endl;
816 * Test SSL client socket timeout
818 TEST(AsyncSSLSocketTest, SSLClientTimeoutTest) {
819 // Start listening on a local port
820 EmptyReadCallback readCallback;
821 HandshakeCallback handshakeCallback(&readCallback,
822 HandshakeCallback::EXPECT_ERROR);
823 HandshakeTimeoutCallback acceptCallback(&handshakeCallback);
824 TestSSLServer server(&acceptCallback);
829 std::make_shared<SSLClient>(&eventBase, server.getAddress(), 1, 10);
830 client->connect(true /* write before connect completes */);
831 EventBaseAborter eba(&eventBase, 3000);
835 // This is checking that the connectError callback precedes any queued
836 // writeError callbacks. This matches AsyncSocket's behavior
837 EXPECT_EQ(client->getWriteAfterConnectErrors(), 1);
838 EXPECT_EQ(client->getErrors(), 1);
839 EXPECT_EQ(client->getMiss(), 0);
840 EXPECT_EQ(client->getHit(), 0);
842 cerr << "SSLClientTimeoutTest test completed" << endl;
847 * Test SSL server async cache
849 TEST(AsyncSSLSocketTest, SSLServerAsyncCacheTest) {
850 // Start listening on a local port
851 WriteCallbackBase writeCallback;
852 ReadCallback readCallback(&writeCallback);
853 HandshakeCallback handshakeCallback(&readCallback);
854 SSLServerAsyncCacheAcceptCallback acceptCallback(&handshakeCallback);
855 TestSSLAsyncCacheServer server(&acceptCallback);
860 std::make_shared<SSLClient>(&eventBase, server.getAddress(), 10, 500);
863 EventBaseAborter eba(&eventBase, 3000);
866 EXPECT_EQ(server.getAsyncCallbacks(), 18);
867 EXPECT_EQ(server.getAsyncLookups(), 9);
868 EXPECT_EQ(client->getMiss(), 10);
869 EXPECT_EQ(client->getHit(), 0);
871 cerr << "SSLServerAsyncCacheTest test completed" << endl;
876 * Test SSL server accept timeout with cache path
878 TEST(AsyncSSLSocketTest, SSLServerTimeoutTest) {
879 // Start listening on a local port
880 WriteCallbackBase writeCallback;
881 ReadCallback readCallback(&writeCallback);
882 EmptyReadCallback clientReadCallback;
883 HandshakeCallback handshakeCallback(&readCallback);
884 SSLServerAcceptCallback acceptCallback(&handshakeCallback, 50);
885 TestSSLAsyncCacheServer server(&acceptCallback);
889 // only do a TCP connect
890 std::shared_ptr<AsyncSocket> sock = AsyncSocket::newSocket(&eventBase);
891 sock->connect(nullptr, server.getAddress());
892 clientReadCallback.tcpSocket_ = sock;
893 sock->setReadCB(&clientReadCallback);
895 EventBaseAborter eba(&eventBase, 3000);
898 EXPECT_EQ(readCallback.state, STATE_WAITING);
900 cerr << "SSLServerTimeoutTest test completed" << endl;
904 * Test SSL server accept timeout with cache path
906 TEST(AsyncSSLSocketTest, SSLServerAsyncCacheTimeoutTest) {
907 // Start listening on a local port
908 WriteCallbackBase writeCallback;
909 ReadCallback readCallback(&writeCallback);
910 HandshakeCallback handshakeCallback(&readCallback);
911 SSLServerAsyncCacheAcceptCallback acceptCallback(&handshakeCallback, 50);
912 TestSSLAsyncCacheServer server(&acceptCallback);
916 auto client = std::make_shared<SSLClient>(&eventBase, server.getAddress(), 2);
919 EventBaseAborter eba(&eventBase, 3000);
922 EXPECT_EQ(server.getAsyncCallbacks(), 1);
923 EXPECT_EQ(server.getAsyncLookups(), 1);
924 EXPECT_EQ(client->getErrors(), 1);
925 EXPECT_EQ(client->getMiss(), 1);
926 EXPECT_EQ(client->getHit(), 0);
928 cerr << "SSLServerAsyncCacheTimeoutTest test completed" << endl;
932 * Test SSL server accept timeout with cache path
934 TEST(AsyncSSLSocketTest, SSLServerCacheCloseTest) {
935 // Start listening on a local port
936 WriteCallbackBase writeCallback;
937 ReadCallback readCallback(&writeCallback);
938 HandshakeCallback handshakeCallback(&readCallback,
939 HandshakeCallback::EXPECT_ERROR);
940 SSLServerAsyncCacheAcceptCallback acceptCallback(&handshakeCallback);
941 TestSSLAsyncCacheServer server(&acceptCallback, 500);
946 std::make_shared<SSLClient>(&eventBase, server.getAddress(), 2, 100);
949 EventBaseAborter eba(&eventBase, 3000);
952 server.getEventBase().runInEventBaseThread([&handshakeCallback]{
953 handshakeCallback.closeSocket();});
954 // give time for the cache lookup to come back and find it closed
955 handshakeCallback.waitForHandshake();
957 EXPECT_EQ(server.getAsyncCallbacks(), 1);
958 EXPECT_EQ(server.getAsyncLookups(), 1);
959 EXPECT_EQ(client->getErrors(), 1);
960 EXPECT_EQ(client->getMiss(), 1);
961 EXPECT_EQ(client->getHit(), 0);
963 cerr << "SSLServerCacheCloseTest test completed" << endl;
967 * Verify Client Ciphers obtained using SSL MSG Callback.
969 TEST(AsyncSSLSocketTest, SSLParseClientHelloSuccess) {
971 auto clientCtx = std::make_shared<SSLContext>();
972 auto serverCtx = std::make_shared<SSLContext>();
973 serverCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
974 serverCtx->ciphers("RSA:!SHA:!NULL:!SHA256@STRENGTH");
975 serverCtx->loadPrivateKey(testKey);
976 serverCtx->loadCertificate(testCert);
977 serverCtx->loadTrustedCertificates(testCA);
978 serverCtx->loadClientCAList(testCA);
980 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
981 clientCtx->ciphers("RC4-SHA:AES128-SHA:AES256-SHA:RC4-MD5");
982 clientCtx->loadPrivateKey(testKey);
983 clientCtx->loadCertificate(testCert);
984 clientCtx->loadTrustedCertificates(testCA);
989 AsyncSSLSocket::UniquePtr clientSock(
990 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
991 AsyncSSLSocket::UniquePtr serverSock(
992 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
994 SSLHandshakeClient client(std::move(clientSock), true, true);
995 SSLHandshakeServerParseClientHello server(std::move(serverSock), true, true);
999 EXPECT_EQ(server.clientCiphers_,
1000 "RC4-SHA:AES128-SHA:AES256-SHA:RC4-MD5:00ff");
1001 EXPECT_TRUE(client.handshakeVerify_);
1002 EXPECT_TRUE(client.handshakeSuccess_);
1003 EXPECT_TRUE(!client.handshakeError_);
1004 EXPECT_TRUE(server.handshakeVerify_);
1005 EXPECT_TRUE(server.handshakeSuccess_);
1006 EXPECT_TRUE(!server.handshakeError_);
1009 TEST(AsyncSSLSocketTest, SSLParseClientHelloOnePacket) {
1010 EventBase eventBase;
1011 auto ctx = std::make_shared<SSLContext>();
1017 uint8_t majorVersion = 18;
1018 uint8_t minorVersion = 25;
1020 // Create callback buf
1021 auto buf = IOBuf::create(bufLen);
1022 buf->append(bufLen);
1023 folly::io::RWPrivateCursor cursor(buf.get());
1024 cursor.write<uint8_t>(SSL3_MT_CLIENT_HELLO);
1025 cursor.write<uint16_t>(0);
1026 cursor.write<uint8_t>(38);
1027 cursor.write<uint8_t>(majorVersion);
1028 cursor.write<uint8_t>(minorVersion);
1030 cursor.write<uint32_t>(0);
1032 SSL* ssl = ctx->createSSL();
1033 SCOPE_EXIT { SSL_free(ssl); };
1034 AsyncSSLSocket::UniquePtr sock(
1035 new AsyncSSLSocket(ctx, &eventBase, fds[0], true));
1036 sock->enableClientHelloParsing();
1038 // Test client hello parsing in one packet
1039 AsyncSSLSocket::clientHelloParsingCallback(
1040 0, 0, SSL3_RT_HANDSHAKE, buf->data(), buf->length(), ssl, sock.get());
1043 auto parsedClientHello = sock->getClientHelloInfo();
1044 EXPECT_TRUE(parsedClientHello != nullptr);
1045 EXPECT_EQ(parsedClientHello->clientHelloMajorVersion_, majorVersion);
1046 EXPECT_EQ(parsedClientHello->clientHelloMinorVersion_, minorVersion);
1049 TEST(AsyncSSLSocketTest, SSLParseClientHelloTwoPackets) {
1050 EventBase eventBase;
1051 auto ctx = std::make_shared<SSLContext>();
1057 uint8_t majorVersion = 18;
1058 uint8_t minorVersion = 25;
1060 // Create callback buf
1061 auto buf = IOBuf::create(bufLen);
1062 buf->append(bufLen);
1063 folly::io::RWPrivateCursor cursor(buf.get());
1064 cursor.write<uint8_t>(SSL3_MT_CLIENT_HELLO);
1065 cursor.write<uint16_t>(0);
1066 cursor.write<uint8_t>(38);
1067 cursor.write<uint8_t>(majorVersion);
1068 cursor.write<uint8_t>(minorVersion);
1070 cursor.write<uint32_t>(0);
1072 SSL* ssl = ctx->createSSL();
1073 SCOPE_EXIT { SSL_free(ssl); };
1074 AsyncSSLSocket::UniquePtr sock(
1075 new AsyncSSLSocket(ctx, &eventBase, fds[0], true));
1076 sock->enableClientHelloParsing();
1078 // Test parsing with two packets with first packet size < 3
1079 auto bufCopy = folly::IOBuf::copyBuffer(buf->data(), 2);
1080 AsyncSSLSocket::clientHelloParsingCallback(
1081 0, 0, SSL3_RT_HANDSHAKE, bufCopy->data(), bufCopy->length(),
1084 bufCopy = folly::IOBuf::copyBuffer(buf->data() + 2, buf->length() - 2);
1085 AsyncSSLSocket::clientHelloParsingCallback(
1086 0, 0, SSL3_RT_HANDSHAKE, bufCopy->data(), bufCopy->length(),
1090 auto parsedClientHello = sock->getClientHelloInfo();
1091 EXPECT_TRUE(parsedClientHello != nullptr);
1092 EXPECT_EQ(parsedClientHello->clientHelloMajorVersion_, majorVersion);
1093 EXPECT_EQ(parsedClientHello->clientHelloMinorVersion_, minorVersion);
1096 TEST(AsyncSSLSocketTest, SSLParseClientHelloMultiplePackets) {
1097 EventBase eventBase;
1098 auto ctx = std::make_shared<SSLContext>();
1104 uint8_t majorVersion = 18;
1105 uint8_t minorVersion = 25;
1107 // Create callback buf
1108 auto buf = IOBuf::create(bufLen);
1109 buf->append(bufLen);
1110 folly::io::RWPrivateCursor cursor(buf.get());
1111 cursor.write<uint8_t>(SSL3_MT_CLIENT_HELLO);
1112 cursor.write<uint16_t>(0);
1113 cursor.write<uint8_t>(38);
1114 cursor.write<uint8_t>(majorVersion);
1115 cursor.write<uint8_t>(minorVersion);
1117 cursor.write<uint32_t>(0);
1119 SSL* ssl = ctx->createSSL();
1120 SCOPE_EXIT { SSL_free(ssl); };
1121 AsyncSSLSocket::UniquePtr sock(
1122 new AsyncSSLSocket(ctx, &eventBase, fds[0], true));
1123 sock->enableClientHelloParsing();
1125 // Test parsing with multiple small packets
1126 for (uint64_t i = 0; i < buf->length(); i += 3) {
1127 auto bufCopy = folly::IOBuf::copyBuffer(
1128 buf->data() + i, std::min((uint64_t)3, buf->length() - i));
1129 AsyncSSLSocket::clientHelloParsingCallback(
1130 0, 0, SSL3_RT_HANDSHAKE, bufCopy->data(), bufCopy->length(),
1135 auto parsedClientHello = sock->getClientHelloInfo();
1136 EXPECT_TRUE(parsedClientHello != nullptr);
1137 EXPECT_EQ(parsedClientHello->clientHelloMajorVersion_, majorVersion);
1138 EXPECT_EQ(parsedClientHello->clientHelloMinorVersion_, minorVersion);
1142 * Verify sucessful behavior of SSL certificate validation.
1144 TEST(AsyncSSLSocketTest, SSLHandshakeValidationSuccess) {
1145 EventBase eventBase;
1146 auto clientCtx = std::make_shared<SSLContext>();
1147 auto dfServerCtx = std::make_shared<SSLContext>();
1151 getctx(clientCtx, dfServerCtx);
1153 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1154 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1156 AsyncSSLSocket::UniquePtr clientSock(
1157 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1158 AsyncSSLSocket::UniquePtr serverSock(
1159 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1161 SSLHandshakeClient client(std::move(clientSock), true, true);
1162 clientCtx->loadTrustedCertificates(testCA);
1164 SSLHandshakeServer server(std::move(serverSock), true, true);
1168 EXPECT_TRUE(client.handshakeVerify_);
1169 EXPECT_TRUE(client.handshakeSuccess_);
1170 EXPECT_TRUE(!client.handshakeError_);
1171 EXPECT_LE(0, client.handshakeTime.count());
1172 EXPECT_TRUE(!server.handshakeVerify_);
1173 EXPECT_TRUE(server.handshakeSuccess_);
1174 EXPECT_TRUE(!server.handshakeError_);
1175 EXPECT_LE(0, server.handshakeTime.count());
1179 * Verify that the client's verification callback is able to fail SSL
1180 * connection establishment.
1182 TEST(AsyncSSLSocketTest, SSLHandshakeValidationFailure) {
1183 EventBase eventBase;
1184 auto clientCtx = std::make_shared<SSLContext>();
1185 auto dfServerCtx = std::make_shared<SSLContext>();
1189 getctx(clientCtx, dfServerCtx);
1191 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1192 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1194 AsyncSSLSocket::UniquePtr clientSock(
1195 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1196 AsyncSSLSocket::UniquePtr serverSock(
1197 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1199 SSLHandshakeClient client(std::move(clientSock), true, false);
1200 clientCtx->loadTrustedCertificates(testCA);
1202 SSLHandshakeServer server(std::move(serverSock), true, true);
1206 EXPECT_TRUE(client.handshakeVerify_);
1207 EXPECT_TRUE(!client.handshakeSuccess_);
1208 EXPECT_TRUE(client.handshakeError_);
1209 EXPECT_LE(0, client.handshakeTime.count());
1210 EXPECT_TRUE(!server.handshakeVerify_);
1211 EXPECT_TRUE(!server.handshakeSuccess_);
1212 EXPECT_TRUE(server.handshakeError_);
1213 EXPECT_LE(0, server.handshakeTime.count());
1217 * Verify that the options in SSLContext can be overridden in
1218 * sslConnect/Accept.i.e specifying that no validation should be performed
1219 * allows an otherwise-invalid certificate to be accepted and doesn't fire
1220 * the validation callback.
1222 TEST(AsyncSSLSocketTest, OverrideSSLCtxDisableVerify) {
1223 EventBase eventBase;
1224 auto clientCtx = std::make_shared<SSLContext>();
1225 auto dfServerCtx = std::make_shared<SSLContext>();
1229 getctx(clientCtx, dfServerCtx);
1231 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1232 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1234 AsyncSSLSocket::UniquePtr clientSock(
1235 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1236 AsyncSSLSocket::UniquePtr serverSock(
1237 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1239 SSLHandshakeClientNoVerify client(std::move(clientSock), false, false);
1240 clientCtx->loadTrustedCertificates(testCA);
1242 SSLHandshakeServerNoVerify server(std::move(serverSock), false, false);
1246 EXPECT_TRUE(!client.handshakeVerify_);
1247 EXPECT_TRUE(client.handshakeSuccess_);
1248 EXPECT_TRUE(!client.handshakeError_);
1249 EXPECT_LE(0, client.handshakeTime.count());
1250 EXPECT_TRUE(!server.handshakeVerify_);
1251 EXPECT_TRUE(server.handshakeSuccess_);
1252 EXPECT_TRUE(!server.handshakeError_);
1253 EXPECT_LE(0, server.handshakeTime.count());
1257 * Verify that the options in SSLContext can be overridden in
1258 * sslConnect/Accept. Enable verification even if context says otherwise.
1259 * Test requireClientCert with client cert
1261 TEST(AsyncSSLSocketTest, OverrideSSLCtxEnableVerify) {
1262 EventBase eventBase;
1263 auto clientCtx = std::make_shared<SSLContext>();
1264 auto serverCtx = std::make_shared<SSLContext>();
1265 serverCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1266 serverCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1267 serverCtx->loadPrivateKey(testKey);
1268 serverCtx->loadCertificate(testCert);
1269 serverCtx->loadTrustedCertificates(testCA);
1270 serverCtx->loadClientCAList(testCA);
1272 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1273 clientCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1274 clientCtx->loadPrivateKey(testKey);
1275 clientCtx->loadCertificate(testCert);
1276 clientCtx->loadTrustedCertificates(testCA);
1281 AsyncSSLSocket::UniquePtr clientSock(
1282 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1283 AsyncSSLSocket::UniquePtr serverSock(
1284 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
1286 SSLHandshakeClientDoVerify client(std::move(clientSock), true, true);
1287 SSLHandshakeServerDoVerify server(std::move(serverSock), true, true);
1291 EXPECT_TRUE(client.handshakeVerify_);
1292 EXPECT_TRUE(client.handshakeSuccess_);
1293 EXPECT_FALSE(client.handshakeError_);
1294 EXPECT_LE(0, client.handshakeTime.count());
1295 EXPECT_TRUE(server.handshakeVerify_);
1296 EXPECT_TRUE(server.handshakeSuccess_);
1297 EXPECT_FALSE(server.handshakeError_);
1298 EXPECT_LE(0, server.handshakeTime.count());
1302 * Verify that the client's verification callback is able to override
1303 * the preverification failure and allow a successful connection.
1305 TEST(AsyncSSLSocketTest, SSLHandshakeValidationOverride) {
1306 EventBase eventBase;
1307 auto clientCtx = std::make_shared<SSLContext>();
1308 auto dfServerCtx = std::make_shared<SSLContext>();
1312 getctx(clientCtx, dfServerCtx);
1314 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1315 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1317 AsyncSSLSocket::UniquePtr clientSock(
1318 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1319 AsyncSSLSocket::UniquePtr serverSock(
1320 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1322 SSLHandshakeClient client(std::move(clientSock), false, true);
1323 SSLHandshakeServer server(std::move(serverSock), true, true);
1327 EXPECT_TRUE(client.handshakeVerify_);
1328 EXPECT_TRUE(client.handshakeSuccess_);
1329 EXPECT_TRUE(!client.handshakeError_);
1330 EXPECT_LE(0, client.handshakeTime.count());
1331 EXPECT_TRUE(!server.handshakeVerify_);
1332 EXPECT_TRUE(server.handshakeSuccess_);
1333 EXPECT_TRUE(!server.handshakeError_);
1334 EXPECT_LE(0, server.handshakeTime.count());
1338 * Verify that specifying that no validation should be performed allows an
1339 * otherwise-invalid certificate to be accepted and doesn't fire the validation
1342 TEST(AsyncSSLSocketTest, SSLHandshakeValidationSkip) {
1343 EventBase eventBase;
1344 auto clientCtx = std::make_shared<SSLContext>();
1345 auto dfServerCtx = std::make_shared<SSLContext>();
1349 getctx(clientCtx, dfServerCtx);
1351 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1352 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1354 AsyncSSLSocket::UniquePtr clientSock(
1355 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1356 AsyncSSLSocket::UniquePtr serverSock(
1357 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1359 SSLHandshakeClient client(std::move(clientSock), false, false);
1360 SSLHandshakeServer server(std::move(serverSock), false, false);
1364 EXPECT_TRUE(!client.handshakeVerify_);
1365 EXPECT_TRUE(client.handshakeSuccess_);
1366 EXPECT_TRUE(!client.handshakeError_);
1367 EXPECT_LE(0, client.handshakeTime.count());
1368 EXPECT_TRUE(!server.handshakeVerify_);
1369 EXPECT_TRUE(server.handshakeSuccess_);
1370 EXPECT_TRUE(!server.handshakeError_);
1371 EXPECT_LE(0, server.handshakeTime.count());
1375 * Test requireClientCert with client cert
1377 TEST(AsyncSSLSocketTest, ClientCertHandshakeSuccess) {
1378 EventBase eventBase;
1379 auto clientCtx = std::make_shared<SSLContext>();
1380 auto serverCtx = std::make_shared<SSLContext>();
1381 serverCtx->setVerificationOption(
1382 SSLContext::SSLVerifyPeerEnum::VERIFY_REQ_CLIENT_CERT);
1383 serverCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1384 serverCtx->loadPrivateKey(testKey);
1385 serverCtx->loadCertificate(testCert);
1386 serverCtx->loadTrustedCertificates(testCA);
1387 serverCtx->loadClientCAList(testCA);
1389 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1390 clientCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1391 clientCtx->loadPrivateKey(testKey);
1392 clientCtx->loadCertificate(testCert);
1393 clientCtx->loadTrustedCertificates(testCA);
1398 AsyncSSLSocket::UniquePtr clientSock(
1399 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1400 AsyncSSLSocket::UniquePtr serverSock(
1401 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
1403 SSLHandshakeClient client(std::move(clientSock), true, true);
1404 SSLHandshakeServer server(std::move(serverSock), true, true);
1408 EXPECT_TRUE(client.handshakeVerify_);
1409 EXPECT_TRUE(client.handshakeSuccess_);
1410 EXPECT_FALSE(client.handshakeError_);
1411 EXPECT_LE(0, client.handshakeTime.count());
1412 EXPECT_TRUE(server.handshakeVerify_);
1413 EXPECT_TRUE(server.handshakeSuccess_);
1414 EXPECT_FALSE(server.handshakeError_);
1415 EXPECT_LE(0, server.handshakeTime.count());
1420 * Test requireClientCert with no client cert
1422 TEST(AsyncSSLSocketTest, NoClientCertHandshakeError) {
1423 EventBase eventBase;
1424 auto clientCtx = std::make_shared<SSLContext>();
1425 auto serverCtx = std::make_shared<SSLContext>();
1426 serverCtx->setVerificationOption(
1427 SSLContext::SSLVerifyPeerEnum::VERIFY_REQ_CLIENT_CERT);
1428 serverCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1429 serverCtx->loadPrivateKey(testKey);
1430 serverCtx->loadCertificate(testCert);
1431 serverCtx->loadTrustedCertificates(testCA);
1432 serverCtx->loadClientCAList(testCA);
1433 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1434 clientCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1439 AsyncSSLSocket::UniquePtr clientSock(
1440 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1441 AsyncSSLSocket::UniquePtr serverSock(
1442 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
1444 SSLHandshakeClient client(std::move(clientSock), false, false);
1445 SSLHandshakeServer server(std::move(serverSock), false, false);
1449 EXPECT_FALSE(server.handshakeVerify_);
1450 EXPECT_FALSE(server.handshakeSuccess_);
1451 EXPECT_TRUE(server.handshakeError_);
1452 EXPECT_LE(0, client.handshakeTime.count());
1453 EXPECT_LE(0, server.handshakeTime.count());
1456 TEST(AsyncSSLSocketTest, LoadCertFromMemory) {
1457 auto cert = getFileAsBuf(testCert);
1458 auto key = getFileAsBuf(testKey);
1460 ssl::BioUniquePtr certBio(BIO_new(BIO_s_mem()));
1461 BIO_write(certBio.get(), cert.data(), cert.size());
1462 ssl::BioUniquePtr keyBio(BIO_new(BIO_s_mem()));
1463 BIO_write(keyBio.get(), key.data(), key.size());
1465 // Create SSL structs from buffers to get properties
1466 ssl::X509UniquePtr certStruct(
1467 PEM_read_bio_X509(certBio.get(), nullptr, nullptr, nullptr));
1468 ssl::EvpPkeyUniquePtr keyStruct(
1469 PEM_read_bio_PrivateKey(keyBio.get(), nullptr, nullptr, nullptr));
1473 auto origCommonName = getCommonName(certStruct.get());
1474 auto origKeySize = EVP_PKEY_bits(keyStruct.get());
1475 certStruct = nullptr;
1476 keyStruct = nullptr;
1478 auto ctx = std::make_shared<SSLContext>();
1479 ctx->loadPrivateKeyFromBufferPEM(key);
1480 ctx->loadCertificateFromBufferPEM(cert);
1481 ctx->loadTrustedCertificates(testCA);
1483 ssl::SSLUniquePtr ssl(ctx->createSSL());
1485 auto newCert = SSL_get_certificate(ssl.get());
1486 auto newKey = SSL_get_privatekey(ssl.get());
1488 // Get properties from SSL struct
1489 auto newCommonName = getCommonName(newCert);
1490 auto newKeySize = EVP_PKEY_bits(newKey);
1492 // Check that the key and cert have the expected properties
1493 EXPECT_EQ(origCommonName, newCommonName);
1494 EXPECT_EQ(origKeySize, newKeySize);
1497 TEST(AsyncSSLSocketTest, MinWriteSizeTest) {
1500 // Set up SSL context.
1501 auto sslContext = std::make_shared<SSLContext>();
1502 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1504 // create SSL socket
1505 AsyncSSLSocket::UniquePtr socket(new AsyncSSLSocket(sslContext, &eb));
1507 EXPECT_EQ(1500, socket->getMinWriteSize());
1509 socket->setMinWriteSize(0);
1510 EXPECT_EQ(0, socket->getMinWriteSize());
1511 socket->setMinWriteSize(50000);
1512 EXPECT_EQ(50000, socket->getMinWriteSize());
1515 class ReadCallbackTerminator : public ReadCallback {
1517 ReadCallbackTerminator(EventBase* base, WriteCallbackBase *wcb)
1521 // Do not write data back, terminate the loop.
1522 void readDataAvailable(size_t len) noexcept override {
1523 std::cerr << "readDataAvailable, len " << len << std::endl;
1525 currentBuffer.length = len;
1527 buffers.push_back(currentBuffer);
1528 currentBuffer.reset();
1529 state = STATE_SUCCEEDED;
1531 socket_->setReadCB(nullptr);
1532 base_->terminateLoopSoon();
1540 * Test a full unencrypted codepath
1542 TEST(AsyncSSLSocketTest, UnencryptedTest) {
1545 auto clientCtx = std::make_shared<folly::SSLContext>();
1546 auto serverCtx = std::make_shared<folly::SSLContext>();
1549 getctx(clientCtx, serverCtx);
1550 auto client = AsyncSSLSocket::newSocket(
1551 clientCtx, &base, fds[0], false, true);
1552 auto server = AsyncSSLSocket::newSocket(
1553 serverCtx, &base, fds[1], true, true);
1555 ReadCallbackTerminator readCallback(&base, nullptr);
1556 server->setReadCB(&readCallback);
1557 readCallback.setSocket(server);
1560 memset(buf, 'a', sizeof(buf));
1561 client->write(nullptr, buf, sizeof(buf));
1563 // Check that bytes are unencrypted
1565 EXPECT_EQ(1, recv(fds[1], &c, 1, MSG_PEEK));
1568 EventBaseAborter eba(&base, 3000);
1571 EXPECT_EQ(1, readCallback.buffers.size());
1572 EXPECT_EQ(AsyncSSLSocket::STATE_UNENCRYPTED, client->getSSLState());
1574 server->setReadCB(&readCallback);
1577 server->sslAccept(nullptr);
1578 client->sslConn(nullptr);
1580 // Do NOT wait for handshake, writing should be queued and happen after
1582 client->write(nullptr, buf, sizeof(buf));
1584 // Check that bytes are *not* unencrypted
1586 EXPECT_EQ(1, recv(fds[1], &c2, 1, MSG_PEEK));
1592 EXPECT_EQ(2, readCallback.buffers.size());
1593 EXPECT_EQ(AsyncSSLSocket::STATE_ESTABLISHED, client->getSSLState());
1596 TEST(AsyncSSLSocketTest, ConnResetErrorString) {
1597 // Start listening on a local port
1598 WriteCallbackBase writeCallback;
1599 WriteErrorCallback readCallback(&writeCallback);
1600 HandshakeCallback handshakeCallback(&readCallback,
1601 HandshakeCallback::EXPECT_ERROR);
1602 SSLServerAcceptCallback acceptCallback(&handshakeCallback);
1603 TestSSLServer server(&acceptCallback);
1605 auto socket = std::make_shared<BlockingSocket>(server.getAddress(), nullptr);
1607 uint8_t buf[3] = {0x16, 0x03, 0x01};
1608 socket->write(buf, sizeof(buf));
1609 socket->closeWithReset();
1611 handshakeCallback.waitForHandshake();
1613 handshakeCallback.errorString_.find("Network error"), std::string::npos);
1614 EXPECT_NE(handshakeCallback.errorString_.find("104"), std::string::npos);
1617 TEST(AsyncSSLSocketTest, ConnEOFErrorString) {
1618 // Start listening on a local port
1619 WriteCallbackBase writeCallback;
1620 WriteErrorCallback readCallback(&writeCallback);
1621 HandshakeCallback handshakeCallback(&readCallback,
1622 HandshakeCallback::EXPECT_ERROR);
1623 SSLServerAcceptCallback acceptCallback(&handshakeCallback);
1624 TestSSLServer server(&acceptCallback);
1626 auto socket = std::make_shared<BlockingSocket>(server.getAddress(), nullptr);
1628 uint8_t buf[3] = {0x16, 0x03, 0x01};
1629 socket->write(buf, sizeof(buf));
1632 handshakeCallback.waitForHandshake();
1634 handshakeCallback.errorString_.find("Connection EOF"), std::string::npos);
1635 EXPECT_NE(handshakeCallback.errorString_.find("EOF"), std::string::npos);
1638 TEST(AsyncSSLSocketTest, ConnOpenSSLErrorString) {
1639 // Start listening on a local port
1640 WriteCallbackBase writeCallback;
1641 WriteErrorCallback readCallback(&writeCallback);
1642 HandshakeCallback handshakeCallback(&readCallback,
1643 HandshakeCallback::EXPECT_ERROR);
1644 SSLServerAcceptCallback acceptCallback(&handshakeCallback);
1645 TestSSLServer server(&acceptCallback);
1647 auto socket = std::make_shared<BlockingSocket>(server.getAddress(), nullptr);
1649 uint8_t buf[256] = {0x16, 0x03};
1650 memset(buf + 2, 'a', sizeof(buf) - 2);
1651 socket->write(buf, sizeof(buf));
1654 handshakeCallback.waitForHandshake();
1655 EXPECT_NE(handshakeCallback.errorString_.find("SSL routines"),
1657 EXPECT_NE(handshakeCallback.errorString_.find("unknown protocol"),
1663 ///////////////////////////////////////////////////////////////////////////
1664 // init_unit_test_suite
1665 ///////////////////////////////////////////////////////////////////////////
1667 struct Initializer {
1669 signal(SIGPIPE, SIG_IGN);
1672 Initializer initializer;