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>
24 #include <folly/portability/Unistd.h>
26 #include <folly/io/async/test/BlockingSocket.h>
29 #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 // Note: the behavior changed in the ANY/ANY case in OpenSSL 1.0.2h, this test
526 // will fail on 1.0.2 before that.
527 TEST_P(NextProtocolTest, NpnTestNoOverlap) {
528 clientCtx->setAdvertisedNextProtocols({"blub"}, GetParam().first);
529 serverCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"},
534 if (GetParam().first == SSLContext::NextProtocolType::ALPN ||
535 GetParam().second == SSLContext::NextProtocolType::ALPN) {
536 // This is arguably incorrect behavior since RFC7301 states an ALPN protocol
537 // mismatch should result in a fatal alert, but this is OpenSSL's current
538 // behavior and we want to know if it changes.
541 expectProtocol("blub");
543 {SSLContext::NextProtocolType::NPN, SSLContext::NextProtocolType::NPN});
547 TEST_P(NextProtocolNPNOnlyTest, NpnTestClientProtoFilterHit) {
548 clientCtx->setAdvertisedNextProtocols({"blub"}, GetParam().first);
549 clientCtx->setClientProtocolFilterCallback(clientProtoFilterPickPony);
550 serverCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"},
555 expectProtocol("ponies");
556 expectProtocolType();
559 TEST_P(NextProtocolNPNOnlyTest, NpnTestClientProtoFilterMiss) {
560 clientCtx->setAdvertisedNextProtocols({"blub"}, GetParam().first);
561 clientCtx->setClientProtocolFilterCallback(clientProtoFilterPickNone);
562 serverCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"},
567 expectProtocol("blub");
568 expectProtocolType();
571 TEST_P(NextProtocolTest, RandomizedNpnTest) {
572 // Probability that this test will fail is 2^-64, which could be considered
574 const int kTries = 64;
576 clientCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"},
578 serverCtx->setRandomizedAdvertisedNextProtocols({{1, {"foo"}}, {1, {"bar"}}},
581 std::set<string> selectedProtocols;
582 for (int i = 0; i < kTries; ++i) {
585 EXPECT_NE(client->nextProtoLength, 0);
586 EXPECT_EQ(client->nextProtoLength, server->nextProtoLength);
588 memcmp(client->nextProto, server->nextProto, server->nextProtoLength),
590 string selected((const char*)client->nextProto, client->nextProtoLength);
591 selectedProtocols.insert(selected);
592 expectProtocolType();
594 EXPECT_EQ(selectedProtocols.size(), 2);
597 INSTANTIATE_TEST_CASE_P(
601 NextProtocolTypePair(
602 SSLContext::NextProtocolType::NPN,
603 SSLContext::NextProtocolType::NPN),
604 #if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_TLSEXT)
605 NextProtocolTypePair(
606 SSLContext::NextProtocolType::ALPN,
607 SSLContext::NextProtocolType::ALPN),
608 NextProtocolTypePair(
609 SSLContext::NextProtocolType::ALPN,
610 SSLContext::NextProtocolType::ANY),
611 NextProtocolTypePair(
612 SSLContext::NextProtocolType::ANY,
613 SSLContext::NextProtocolType::ALPN),
615 NextProtocolTypePair(
616 SSLContext::NextProtocolType::NPN,
617 SSLContext::NextProtocolType::ANY),
618 NextProtocolTypePair(
619 SSLContext::NextProtocolType::ANY,
620 SSLContext::NextProtocolType::ANY)));
622 INSTANTIATE_TEST_CASE_P(
624 NextProtocolNPNOnlyTest,
625 ::testing::Values(NextProtocolTypePair(SSLContext::NextProtocolType::NPN,
626 SSLContext::NextProtocolType::NPN)));
628 #if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_TLSEXT)
629 INSTANTIATE_TEST_CASE_P(
631 NextProtocolMismatchTest,
632 ::testing::Values(NextProtocolTypePair(SSLContext::NextProtocolType::NPN,
633 SSLContext::NextProtocolType::ALPN),
634 NextProtocolTypePair(SSLContext::NextProtocolType::ALPN,
635 SSLContext::NextProtocolType::NPN)));
638 #ifndef OPENSSL_NO_TLSEXT
640 * 1. Client sends TLSEXT_HOSTNAME in client hello.
641 * 2. Server found a match SSL_CTX and use this SSL_CTX to
642 * continue the SSL handshake.
643 * 3. Server sends back TLSEXT_HOSTNAME in server hello.
645 TEST(AsyncSSLSocketTest, SNITestMatch) {
647 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
648 std::shared_ptr<SSLContext> dfServerCtx(new SSLContext);
649 // Use the same SSLContext to continue the handshake after
650 // tlsext_hostname match.
651 std::shared_ptr<SSLContext> hskServerCtx(dfServerCtx);
652 const std::string serverName("xyz.newdev.facebook.com");
655 getctx(clientCtx, dfServerCtx);
657 AsyncSSLSocket::UniquePtr clientSock(
658 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], serverName));
659 AsyncSSLSocket::UniquePtr serverSock(
660 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
661 SNIClient client(std::move(clientSock));
662 SNIServer server(std::move(serverSock),
669 EXPECT_TRUE(client.serverNameMatch);
670 EXPECT_TRUE(server.serverNameMatch);
674 * 1. Client sends TLSEXT_HOSTNAME in client hello.
675 * 2. Server cannot find a matching SSL_CTX and continue to use
676 * the current SSL_CTX to do the handshake.
677 * 3. Server does not send back TLSEXT_HOSTNAME in server hello.
679 TEST(AsyncSSLSocketTest, SNITestNotMatch) {
681 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
682 std::shared_ptr<SSLContext> dfServerCtx(new SSLContext);
683 // Use the same SSLContext to continue the handshake after
684 // tlsext_hostname match.
685 std::shared_ptr<SSLContext> hskServerCtx(dfServerCtx);
686 const std::string clientRequestingServerName("foo.com");
687 const std::string serverExpectedServerName("xyz.newdev.facebook.com");
691 getctx(clientCtx, dfServerCtx);
693 AsyncSSLSocket::UniquePtr clientSock(
694 new AsyncSSLSocket(clientCtx,
697 clientRequestingServerName));
698 AsyncSSLSocket::UniquePtr serverSock(
699 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
700 SNIClient client(std::move(clientSock));
701 SNIServer server(std::move(serverSock),
704 serverExpectedServerName);
708 EXPECT_TRUE(!client.serverNameMatch);
709 EXPECT_TRUE(!server.serverNameMatch);
712 * 1. Client sends TLSEXT_HOSTNAME in client hello.
713 * 2. We then change the serverName.
714 * 3. We expect that we get 'false' as the result for serNameMatch.
717 TEST(AsyncSSLSocketTest, SNITestChangeServerName) {
719 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
720 std::shared_ptr<SSLContext> dfServerCtx(new SSLContext);
721 // Use the same SSLContext to continue the handshake after
722 // tlsext_hostname match.
723 std::shared_ptr<SSLContext> hskServerCtx(dfServerCtx);
724 const std::string serverName("xyz.newdev.facebook.com");
727 getctx(clientCtx, dfServerCtx);
729 AsyncSSLSocket::UniquePtr clientSock(
730 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], serverName));
731 //Change the server name
732 std::string newName("new.com");
733 clientSock->setServerName(newName);
734 AsyncSSLSocket::UniquePtr serverSock(
735 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
736 SNIClient client(std::move(clientSock));
737 SNIServer server(std::move(serverSock),
744 EXPECT_TRUE(!client.serverNameMatch);
748 * 1. Client does not send TLSEXT_HOSTNAME in client hello.
749 * 2. Server does not send back TLSEXT_HOSTNAME in server hello.
751 TEST(AsyncSSLSocketTest, SNITestClientHelloNoHostname) {
753 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
754 std::shared_ptr<SSLContext> dfServerCtx(new SSLContext);
755 // Use the same SSLContext to continue the handshake after
756 // tlsext_hostname match.
757 std::shared_ptr<SSLContext> hskServerCtx(dfServerCtx);
758 const std::string serverExpectedServerName("xyz.newdev.facebook.com");
762 getctx(clientCtx, dfServerCtx);
764 AsyncSSLSocket::UniquePtr clientSock(
765 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
766 AsyncSSLSocket::UniquePtr serverSock(
767 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
768 SNIClient client(std::move(clientSock));
769 SNIServer server(std::move(serverSock),
772 serverExpectedServerName);
776 EXPECT_TRUE(!client.serverNameMatch);
777 EXPECT_TRUE(!server.serverNameMatch);
782 * Test SSL client socket
784 TEST(AsyncSSLSocketTest, SSLClientTest) {
785 // Start listening on a local port
786 WriteCallbackBase writeCallback;
787 ReadCallback readCallback(&writeCallback);
788 HandshakeCallback handshakeCallback(&readCallback);
789 SSLServerAcceptCallbackDelay acceptCallback(&handshakeCallback);
790 TestSSLServer server(&acceptCallback);
794 auto client = std::make_shared<SSLClient>(&eventBase, server.getAddress(), 1);
797 EventBaseAborter eba(&eventBase, 3000);
800 EXPECT_EQ(client->getMiss(), 1);
801 EXPECT_EQ(client->getHit(), 0);
803 cerr << "SSLClientTest test completed" << endl;
808 * Test SSL client socket session re-use
810 TEST(AsyncSSLSocketTest, SSLClientTestReuse) {
811 // Start listening on a local port
812 WriteCallbackBase writeCallback;
813 ReadCallback readCallback(&writeCallback);
814 HandshakeCallback handshakeCallback(&readCallback);
815 SSLServerAcceptCallbackDelay acceptCallback(&handshakeCallback);
816 TestSSLServer server(&acceptCallback);
821 std::make_shared<SSLClient>(&eventBase, server.getAddress(), 10);
824 EventBaseAborter eba(&eventBase, 3000);
827 EXPECT_EQ(client->getMiss(), 1);
828 EXPECT_EQ(client->getHit(), 9);
830 cerr << "SSLClientTestReuse test completed" << endl;
834 * Test SSL client socket timeout
836 TEST(AsyncSSLSocketTest, SSLClientTimeoutTest) {
837 // Start listening on a local port
838 EmptyReadCallback readCallback;
839 HandshakeCallback handshakeCallback(&readCallback,
840 HandshakeCallback::EXPECT_ERROR);
841 HandshakeTimeoutCallback acceptCallback(&handshakeCallback);
842 TestSSLServer server(&acceptCallback);
847 std::make_shared<SSLClient>(&eventBase, server.getAddress(), 1, 10);
848 client->connect(true /* write before connect completes */);
849 EventBaseAborter eba(&eventBase, 3000);
853 // This is checking that the connectError callback precedes any queued
854 // writeError callbacks. This matches AsyncSocket's behavior
855 EXPECT_EQ(client->getWriteAfterConnectErrors(), 1);
856 EXPECT_EQ(client->getErrors(), 1);
857 EXPECT_EQ(client->getMiss(), 0);
858 EXPECT_EQ(client->getHit(), 0);
860 cerr << "SSLClientTimeoutTest test completed" << endl;
865 * Test SSL server async cache
867 TEST(AsyncSSLSocketTest, SSLServerAsyncCacheTest) {
868 // Start listening on a local port
869 WriteCallbackBase writeCallback;
870 ReadCallback readCallback(&writeCallback);
871 HandshakeCallback handshakeCallback(&readCallback);
872 SSLServerAsyncCacheAcceptCallback acceptCallback(&handshakeCallback);
873 TestSSLAsyncCacheServer server(&acceptCallback);
878 std::make_shared<SSLClient>(&eventBase, server.getAddress(), 10, 500);
881 EventBaseAborter eba(&eventBase, 3000);
884 EXPECT_EQ(server.getAsyncCallbacks(), 18);
885 EXPECT_EQ(server.getAsyncLookups(), 9);
886 EXPECT_EQ(client->getMiss(), 10);
887 EXPECT_EQ(client->getHit(), 0);
889 cerr << "SSLServerAsyncCacheTest test completed" << endl;
894 * Test SSL server accept timeout with cache path
896 TEST(AsyncSSLSocketTest, SSLServerTimeoutTest) {
897 // Start listening on a local port
898 WriteCallbackBase writeCallback;
899 ReadCallback readCallback(&writeCallback);
900 EmptyReadCallback clientReadCallback;
901 HandshakeCallback handshakeCallback(&readCallback);
902 SSLServerAcceptCallback acceptCallback(&handshakeCallback, 50);
903 TestSSLAsyncCacheServer server(&acceptCallback);
907 // only do a TCP connect
908 std::shared_ptr<AsyncSocket> sock = AsyncSocket::newSocket(&eventBase);
909 sock->connect(nullptr, server.getAddress());
910 clientReadCallback.tcpSocket_ = sock;
911 sock->setReadCB(&clientReadCallback);
913 EventBaseAborter eba(&eventBase, 3000);
916 EXPECT_EQ(readCallback.state, STATE_WAITING);
918 cerr << "SSLServerTimeoutTest test completed" << endl;
922 * Test SSL server accept timeout with cache path
924 TEST(AsyncSSLSocketTest, SSLServerAsyncCacheTimeoutTest) {
925 // Start listening on a local port
926 WriteCallbackBase writeCallback;
927 ReadCallback readCallback(&writeCallback);
928 HandshakeCallback handshakeCallback(&readCallback);
929 SSLServerAsyncCacheAcceptCallback acceptCallback(&handshakeCallback, 50);
930 TestSSLAsyncCacheServer server(&acceptCallback);
934 auto client = std::make_shared<SSLClient>(&eventBase, server.getAddress(), 2);
937 EventBaseAborter eba(&eventBase, 3000);
940 EXPECT_EQ(server.getAsyncCallbacks(), 1);
941 EXPECT_EQ(server.getAsyncLookups(), 1);
942 EXPECT_EQ(client->getErrors(), 1);
943 EXPECT_EQ(client->getMiss(), 1);
944 EXPECT_EQ(client->getHit(), 0);
946 cerr << "SSLServerAsyncCacheTimeoutTest test completed" << endl;
950 * Test SSL server accept timeout with cache path
952 TEST(AsyncSSLSocketTest, SSLServerCacheCloseTest) {
953 // Start listening on a local port
954 WriteCallbackBase writeCallback;
955 ReadCallback readCallback(&writeCallback);
956 HandshakeCallback handshakeCallback(&readCallback,
957 HandshakeCallback::EXPECT_ERROR);
958 SSLServerAsyncCacheAcceptCallback acceptCallback(&handshakeCallback);
959 TestSSLAsyncCacheServer server(&acceptCallback, 500);
964 std::make_shared<SSLClient>(&eventBase, server.getAddress(), 2, 100);
967 EventBaseAborter eba(&eventBase, 3000);
970 server.getEventBase().runInEventBaseThread([&handshakeCallback]{
971 handshakeCallback.closeSocket();});
972 // give time for the cache lookup to come back and find it closed
973 handshakeCallback.waitForHandshake();
975 EXPECT_EQ(server.getAsyncCallbacks(), 1);
976 EXPECT_EQ(server.getAsyncLookups(), 1);
977 EXPECT_EQ(client->getErrors(), 1);
978 EXPECT_EQ(client->getMiss(), 1);
979 EXPECT_EQ(client->getHit(), 0);
981 cerr << "SSLServerCacheCloseTest test completed" << endl;
985 * Verify Client Ciphers obtained using SSL MSG Callback.
987 TEST(AsyncSSLSocketTest, SSLParseClientHelloSuccess) {
989 auto clientCtx = std::make_shared<SSLContext>();
990 auto serverCtx = std::make_shared<SSLContext>();
991 serverCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
992 serverCtx->ciphers("RSA:!SHA:!NULL:!SHA256@STRENGTH");
993 serverCtx->loadPrivateKey(testKey);
994 serverCtx->loadCertificate(testCert);
995 serverCtx->loadTrustedCertificates(testCA);
996 serverCtx->loadClientCAList(testCA);
998 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
999 clientCtx->ciphers("RC4-SHA:AES128-SHA:AES256-SHA:RC4-MD5");
1000 clientCtx->loadPrivateKey(testKey);
1001 clientCtx->loadCertificate(testCert);
1002 clientCtx->loadTrustedCertificates(testCA);
1007 AsyncSSLSocket::UniquePtr clientSock(
1008 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1009 AsyncSSLSocket::UniquePtr serverSock(
1010 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
1012 SSLHandshakeClient client(std::move(clientSock), true, true);
1013 SSLHandshakeServerParseClientHello server(std::move(serverSock), true, true);
1017 EXPECT_EQ(server.clientCiphers_,
1018 "RC4-SHA:AES128-SHA:AES256-SHA:RC4-MD5:00ff");
1019 EXPECT_TRUE(client.handshakeVerify_);
1020 EXPECT_TRUE(client.handshakeSuccess_);
1021 EXPECT_TRUE(!client.handshakeError_);
1022 EXPECT_TRUE(server.handshakeVerify_);
1023 EXPECT_TRUE(server.handshakeSuccess_);
1024 EXPECT_TRUE(!server.handshakeError_);
1027 TEST(AsyncSSLSocketTest, SSLParseClientHelloOnePacket) {
1028 EventBase eventBase;
1029 auto ctx = std::make_shared<SSLContext>();
1035 uint8_t majorVersion = 18;
1036 uint8_t minorVersion = 25;
1038 // Create callback buf
1039 auto buf = IOBuf::create(bufLen);
1040 buf->append(bufLen);
1041 folly::io::RWPrivateCursor cursor(buf.get());
1042 cursor.write<uint8_t>(SSL3_MT_CLIENT_HELLO);
1043 cursor.write<uint16_t>(0);
1044 cursor.write<uint8_t>(38);
1045 cursor.write<uint8_t>(majorVersion);
1046 cursor.write<uint8_t>(minorVersion);
1048 cursor.write<uint32_t>(0);
1050 SSL* ssl = ctx->createSSL();
1051 SCOPE_EXIT { SSL_free(ssl); };
1052 AsyncSSLSocket::UniquePtr sock(
1053 new AsyncSSLSocket(ctx, &eventBase, fds[0], true));
1054 sock->enableClientHelloParsing();
1056 // Test client hello parsing in one packet
1057 AsyncSSLSocket::clientHelloParsingCallback(
1058 0, 0, SSL3_RT_HANDSHAKE, buf->data(), buf->length(), ssl, sock.get());
1061 auto parsedClientHello = sock->getClientHelloInfo();
1062 EXPECT_TRUE(parsedClientHello != nullptr);
1063 EXPECT_EQ(parsedClientHello->clientHelloMajorVersion_, majorVersion);
1064 EXPECT_EQ(parsedClientHello->clientHelloMinorVersion_, minorVersion);
1067 TEST(AsyncSSLSocketTest, SSLParseClientHelloTwoPackets) {
1068 EventBase eventBase;
1069 auto ctx = std::make_shared<SSLContext>();
1075 uint8_t majorVersion = 18;
1076 uint8_t minorVersion = 25;
1078 // Create callback buf
1079 auto buf = IOBuf::create(bufLen);
1080 buf->append(bufLen);
1081 folly::io::RWPrivateCursor cursor(buf.get());
1082 cursor.write<uint8_t>(SSL3_MT_CLIENT_HELLO);
1083 cursor.write<uint16_t>(0);
1084 cursor.write<uint8_t>(38);
1085 cursor.write<uint8_t>(majorVersion);
1086 cursor.write<uint8_t>(minorVersion);
1088 cursor.write<uint32_t>(0);
1090 SSL* ssl = ctx->createSSL();
1091 SCOPE_EXIT { SSL_free(ssl); };
1092 AsyncSSLSocket::UniquePtr sock(
1093 new AsyncSSLSocket(ctx, &eventBase, fds[0], true));
1094 sock->enableClientHelloParsing();
1096 // Test parsing with two packets with first packet size < 3
1097 auto bufCopy = folly::IOBuf::copyBuffer(buf->data(), 2);
1098 AsyncSSLSocket::clientHelloParsingCallback(
1099 0, 0, SSL3_RT_HANDSHAKE, bufCopy->data(), bufCopy->length(),
1102 bufCopy = folly::IOBuf::copyBuffer(buf->data() + 2, buf->length() - 2);
1103 AsyncSSLSocket::clientHelloParsingCallback(
1104 0, 0, SSL3_RT_HANDSHAKE, bufCopy->data(), bufCopy->length(),
1108 auto parsedClientHello = sock->getClientHelloInfo();
1109 EXPECT_TRUE(parsedClientHello != nullptr);
1110 EXPECT_EQ(parsedClientHello->clientHelloMajorVersion_, majorVersion);
1111 EXPECT_EQ(parsedClientHello->clientHelloMinorVersion_, minorVersion);
1114 TEST(AsyncSSLSocketTest, SSLParseClientHelloMultiplePackets) {
1115 EventBase eventBase;
1116 auto ctx = std::make_shared<SSLContext>();
1122 uint8_t majorVersion = 18;
1123 uint8_t minorVersion = 25;
1125 // Create callback buf
1126 auto buf = IOBuf::create(bufLen);
1127 buf->append(bufLen);
1128 folly::io::RWPrivateCursor cursor(buf.get());
1129 cursor.write<uint8_t>(SSL3_MT_CLIENT_HELLO);
1130 cursor.write<uint16_t>(0);
1131 cursor.write<uint8_t>(38);
1132 cursor.write<uint8_t>(majorVersion);
1133 cursor.write<uint8_t>(minorVersion);
1135 cursor.write<uint32_t>(0);
1137 SSL* ssl = ctx->createSSL();
1138 SCOPE_EXIT { SSL_free(ssl); };
1139 AsyncSSLSocket::UniquePtr sock(
1140 new AsyncSSLSocket(ctx, &eventBase, fds[0], true));
1141 sock->enableClientHelloParsing();
1143 // Test parsing with multiple small packets
1144 for (uint64_t i = 0; i < buf->length(); i += 3) {
1145 auto bufCopy = folly::IOBuf::copyBuffer(
1146 buf->data() + i, std::min((uint64_t)3, buf->length() - i));
1147 AsyncSSLSocket::clientHelloParsingCallback(
1148 0, 0, SSL3_RT_HANDSHAKE, bufCopy->data(), bufCopy->length(),
1153 auto parsedClientHello = sock->getClientHelloInfo();
1154 EXPECT_TRUE(parsedClientHello != nullptr);
1155 EXPECT_EQ(parsedClientHello->clientHelloMajorVersion_, majorVersion);
1156 EXPECT_EQ(parsedClientHello->clientHelloMinorVersion_, minorVersion);
1160 * Verify sucessful behavior of SSL certificate validation.
1162 TEST(AsyncSSLSocketTest, SSLHandshakeValidationSuccess) {
1163 EventBase eventBase;
1164 auto clientCtx = std::make_shared<SSLContext>();
1165 auto dfServerCtx = std::make_shared<SSLContext>();
1169 getctx(clientCtx, dfServerCtx);
1171 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1172 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1174 AsyncSSLSocket::UniquePtr clientSock(
1175 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1176 AsyncSSLSocket::UniquePtr serverSock(
1177 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1179 SSLHandshakeClient client(std::move(clientSock), true, true);
1180 clientCtx->loadTrustedCertificates(testCA);
1182 SSLHandshakeServer server(std::move(serverSock), true, true);
1186 EXPECT_TRUE(client.handshakeVerify_);
1187 EXPECT_TRUE(client.handshakeSuccess_);
1188 EXPECT_TRUE(!client.handshakeError_);
1189 EXPECT_LE(0, client.handshakeTime.count());
1190 EXPECT_TRUE(!server.handshakeVerify_);
1191 EXPECT_TRUE(server.handshakeSuccess_);
1192 EXPECT_TRUE(!server.handshakeError_);
1193 EXPECT_LE(0, server.handshakeTime.count());
1197 * Verify that the client's verification callback is able to fail SSL
1198 * connection establishment.
1200 TEST(AsyncSSLSocketTest, SSLHandshakeValidationFailure) {
1201 EventBase eventBase;
1202 auto clientCtx = std::make_shared<SSLContext>();
1203 auto dfServerCtx = std::make_shared<SSLContext>();
1207 getctx(clientCtx, dfServerCtx);
1209 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1210 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1212 AsyncSSLSocket::UniquePtr clientSock(
1213 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1214 AsyncSSLSocket::UniquePtr serverSock(
1215 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1217 SSLHandshakeClient client(std::move(clientSock), true, false);
1218 clientCtx->loadTrustedCertificates(testCA);
1220 SSLHandshakeServer server(std::move(serverSock), true, true);
1224 EXPECT_TRUE(client.handshakeVerify_);
1225 EXPECT_TRUE(!client.handshakeSuccess_);
1226 EXPECT_TRUE(client.handshakeError_);
1227 EXPECT_LE(0, client.handshakeTime.count());
1228 EXPECT_TRUE(!server.handshakeVerify_);
1229 EXPECT_TRUE(!server.handshakeSuccess_);
1230 EXPECT_TRUE(server.handshakeError_);
1231 EXPECT_LE(0, server.handshakeTime.count());
1235 * Verify that the options in SSLContext can be overridden in
1236 * sslConnect/Accept.i.e specifying that no validation should be performed
1237 * allows an otherwise-invalid certificate to be accepted and doesn't fire
1238 * the validation callback.
1240 TEST(AsyncSSLSocketTest, OverrideSSLCtxDisableVerify) {
1241 EventBase eventBase;
1242 auto clientCtx = std::make_shared<SSLContext>();
1243 auto dfServerCtx = std::make_shared<SSLContext>();
1247 getctx(clientCtx, dfServerCtx);
1249 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1250 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1252 AsyncSSLSocket::UniquePtr clientSock(
1253 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1254 AsyncSSLSocket::UniquePtr serverSock(
1255 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1257 SSLHandshakeClientNoVerify client(std::move(clientSock), false, false);
1258 clientCtx->loadTrustedCertificates(testCA);
1260 SSLHandshakeServerNoVerify server(std::move(serverSock), false, false);
1264 EXPECT_TRUE(!client.handshakeVerify_);
1265 EXPECT_TRUE(client.handshakeSuccess_);
1266 EXPECT_TRUE(!client.handshakeError_);
1267 EXPECT_LE(0, client.handshakeTime.count());
1268 EXPECT_TRUE(!server.handshakeVerify_);
1269 EXPECT_TRUE(server.handshakeSuccess_);
1270 EXPECT_TRUE(!server.handshakeError_);
1271 EXPECT_LE(0, server.handshakeTime.count());
1275 * Verify that the options in SSLContext can be overridden in
1276 * sslConnect/Accept. Enable verification even if context says otherwise.
1277 * Test requireClientCert with client cert
1279 TEST(AsyncSSLSocketTest, OverrideSSLCtxEnableVerify) {
1280 EventBase eventBase;
1281 auto clientCtx = std::make_shared<SSLContext>();
1282 auto serverCtx = std::make_shared<SSLContext>();
1283 serverCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1284 serverCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1285 serverCtx->loadPrivateKey(testKey);
1286 serverCtx->loadCertificate(testCert);
1287 serverCtx->loadTrustedCertificates(testCA);
1288 serverCtx->loadClientCAList(testCA);
1290 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1291 clientCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1292 clientCtx->loadPrivateKey(testKey);
1293 clientCtx->loadCertificate(testCert);
1294 clientCtx->loadTrustedCertificates(testCA);
1299 AsyncSSLSocket::UniquePtr clientSock(
1300 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1301 AsyncSSLSocket::UniquePtr serverSock(
1302 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
1304 SSLHandshakeClientDoVerify client(std::move(clientSock), true, true);
1305 SSLHandshakeServerDoVerify server(std::move(serverSock), true, true);
1309 EXPECT_TRUE(client.handshakeVerify_);
1310 EXPECT_TRUE(client.handshakeSuccess_);
1311 EXPECT_FALSE(client.handshakeError_);
1312 EXPECT_LE(0, client.handshakeTime.count());
1313 EXPECT_TRUE(server.handshakeVerify_);
1314 EXPECT_TRUE(server.handshakeSuccess_);
1315 EXPECT_FALSE(server.handshakeError_);
1316 EXPECT_LE(0, server.handshakeTime.count());
1320 * Verify that the client's verification callback is able to override
1321 * the preverification failure and allow a successful connection.
1323 TEST(AsyncSSLSocketTest, SSLHandshakeValidationOverride) {
1324 EventBase eventBase;
1325 auto clientCtx = std::make_shared<SSLContext>();
1326 auto dfServerCtx = std::make_shared<SSLContext>();
1330 getctx(clientCtx, dfServerCtx);
1332 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1333 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1335 AsyncSSLSocket::UniquePtr clientSock(
1336 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1337 AsyncSSLSocket::UniquePtr serverSock(
1338 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1340 SSLHandshakeClient client(std::move(clientSock), false, true);
1341 SSLHandshakeServer server(std::move(serverSock), true, true);
1345 EXPECT_TRUE(client.handshakeVerify_);
1346 EXPECT_TRUE(client.handshakeSuccess_);
1347 EXPECT_TRUE(!client.handshakeError_);
1348 EXPECT_LE(0, client.handshakeTime.count());
1349 EXPECT_TRUE(!server.handshakeVerify_);
1350 EXPECT_TRUE(server.handshakeSuccess_);
1351 EXPECT_TRUE(!server.handshakeError_);
1352 EXPECT_LE(0, server.handshakeTime.count());
1356 * Verify that specifying that no validation should be performed allows an
1357 * otherwise-invalid certificate to be accepted and doesn't fire the validation
1360 TEST(AsyncSSLSocketTest, SSLHandshakeValidationSkip) {
1361 EventBase eventBase;
1362 auto clientCtx = std::make_shared<SSLContext>();
1363 auto dfServerCtx = std::make_shared<SSLContext>();
1367 getctx(clientCtx, dfServerCtx);
1369 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1370 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1372 AsyncSSLSocket::UniquePtr clientSock(
1373 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1374 AsyncSSLSocket::UniquePtr serverSock(
1375 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1377 SSLHandshakeClient client(std::move(clientSock), false, false);
1378 SSLHandshakeServer server(std::move(serverSock), false, false);
1382 EXPECT_TRUE(!client.handshakeVerify_);
1383 EXPECT_TRUE(client.handshakeSuccess_);
1384 EXPECT_TRUE(!client.handshakeError_);
1385 EXPECT_LE(0, client.handshakeTime.count());
1386 EXPECT_TRUE(!server.handshakeVerify_);
1387 EXPECT_TRUE(server.handshakeSuccess_);
1388 EXPECT_TRUE(!server.handshakeError_);
1389 EXPECT_LE(0, server.handshakeTime.count());
1393 * Test requireClientCert with client cert
1395 TEST(AsyncSSLSocketTest, ClientCertHandshakeSuccess) {
1396 EventBase eventBase;
1397 auto clientCtx = std::make_shared<SSLContext>();
1398 auto serverCtx = std::make_shared<SSLContext>();
1399 serverCtx->setVerificationOption(
1400 SSLContext::SSLVerifyPeerEnum::VERIFY_REQ_CLIENT_CERT);
1401 serverCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1402 serverCtx->loadPrivateKey(testKey);
1403 serverCtx->loadCertificate(testCert);
1404 serverCtx->loadTrustedCertificates(testCA);
1405 serverCtx->loadClientCAList(testCA);
1407 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1408 clientCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1409 clientCtx->loadPrivateKey(testKey);
1410 clientCtx->loadCertificate(testCert);
1411 clientCtx->loadTrustedCertificates(testCA);
1416 AsyncSSLSocket::UniquePtr clientSock(
1417 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1418 AsyncSSLSocket::UniquePtr serverSock(
1419 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
1421 SSLHandshakeClient client(std::move(clientSock), true, true);
1422 SSLHandshakeServer server(std::move(serverSock), true, true);
1426 EXPECT_TRUE(client.handshakeVerify_);
1427 EXPECT_TRUE(client.handshakeSuccess_);
1428 EXPECT_FALSE(client.handshakeError_);
1429 EXPECT_LE(0, client.handshakeTime.count());
1430 EXPECT_TRUE(server.handshakeVerify_);
1431 EXPECT_TRUE(server.handshakeSuccess_);
1432 EXPECT_FALSE(server.handshakeError_);
1433 EXPECT_LE(0, server.handshakeTime.count());
1438 * Test requireClientCert with no client cert
1440 TEST(AsyncSSLSocketTest, NoClientCertHandshakeError) {
1441 EventBase eventBase;
1442 auto clientCtx = std::make_shared<SSLContext>();
1443 auto serverCtx = std::make_shared<SSLContext>();
1444 serverCtx->setVerificationOption(
1445 SSLContext::SSLVerifyPeerEnum::VERIFY_REQ_CLIENT_CERT);
1446 serverCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1447 serverCtx->loadPrivateKey(testKey);
1448 serverCtx->loadCertificate(testCert);
1449 serverCtx->loadTrustedCertificates(testCA);
1450 serverCtx->loadClientCAList(testCA);
1451 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1452 clientCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1457 AsyncSSLSocket::UniquePtr clientSock(
1458 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1459 AsyncSSLSocket::UniquePtr serverSock(
1460 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
1462 SSLHandshakeClient client(std::move(clientSock), false, false);
1463 SSLHandshakeServer server(std::move(serverSock), false, false);
1467 EXPECT_FALSE(server.handshakeVerify_);
1468 EXPECT_FALSE(server.handshakeSuccess_);
1469 EXPECT_TRUE(server.handshakeError_);
1470 EXPECT_LE(0, client.handshakeTime.count());
1471 EXPECT_LE(0, server.handshakeTime.count());
1474 TEST(AsyncSSLSocketTest, LoadCertFromMemory) {
1475 auto cert = getFileAsBuf(testCert);
1476 auto key = getFileAsBuf(testKey);
1478 ssl::BioUniquePtr certBio(BIO_new(BIO_s_mem()));
1479 BIO_write(certBio.get(), cert.data(), cert.size());
1480 ssl::BioUniquePtr keyBio(BIO_new(BIO_s_mem()));
1481 BIO_write(keyBio.get(), key.data(), key.size());
1483 // Create SSL structs from buffers to get properties
1484 ssl::X509UniquePtr certStruct(
1485 PEM_read_bio_X509(certBio.get(), nullptr, nullptr, nullptr));
1486 ssl::EvpPkeyUniquePtr keyStruct(
1487 PEM_read_bio_PrivateKey(keyBio.get(), nullptr, nullptr, nullptr));
1491 auto origCommonName = getCommonName(certStruct.get());
1492 auto origKeySize = EVP_PKEY_bits(keyStruct.get());
1493 certStruct = nullptr;
1494 keyStruct = nullptr;
1496 auto ctx = std::make_shared<SSLContext>();
1497 ctx->loadPrivateKeyFromBufferPEM(key);
1498 ctx->loadCertificateFromBufferPEM(cert);
1499 ctx->loadTrustedCertificates(testCA);
1501 ssl::SSLUniquePtr ssl(ctx->createSSL());
1503 auto newCert = SSL_get_certificate(ssl.get());
1504 auto newKey = SSL_get_privatekey(ssl.get());
1506 // Get properties from SSL struct
1507 auto newCommonName = getCommonName(newCert);
1508 auto newKeySize = EVP_PKEY_bits(newKey);
1510 // Check that the key and cert have the expected properties
1511 EXPECT_EQ(origCommonName, newCommonName);
1512 EXPECT_EQ(origKeySize, newKeySize);
1515 TEST(AsyncSSLSocketTest, MinWriteSizeTest) {
1518 // Set up SSL context.
1519 auto sslContext = std::make_shared<SSLContext>();
1520 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1522 // create SSL socket
1523 AsyncSSLSocket::UniquePtr socket(new AsyncSSLSocket(sslContext, &eb));
1525 EXPECT_EQ(1500, socket->getMinWriteSize());
1527 socket->setMinWriteSize(0);
1528 EXPECT_EQ(0, socket->getMinWriteSize());
1529 socket->setMinWriteSize(50000);
1530 EXPECT_EQ(50000, socket->getMinWriteSize());
1533 class ReadCallbackTerminator : public ReadCallback {
1535 ReadCallbackTerminator(EventBase* base, WriteCallbackBase *wcb)
1539 // Do not write data back, terminate the loop.
1540 void readDataAvailable(size_t len) noexcept override {
1541 std::cerr << "readDataAvailable, len " << len << std::endl;
1543 currentBuffer.length = len;
1545 buffers.push_back(currentBuffer);
1546 currentBuffer.reset();
1547 state = STATE_SUCCEEDED;
1549 socket_->setReadCB(nullptr);
1550 base_->terminateLoopSoon();
1558 * Test a full unencrypted codepath
1560 TEST(AsyncSSLSocketTest, UnencryptedTest) {
1563 auto clientCtx = std::make_shared<folly::SSLContext>();
1564 auto serverCtx = std::make_shared<folly::SSLContext>();
1567 getctx(clientCtx, serverCtx);
1568 auto client = AsyncSSLSocket::newSocket(
1569 clientCtx, &base, fds[0], false, true);
1570 auto server = AsyncSSLSocket::newSocket(
1571 serverCtx, &base, fds[1], true, true);
1573 ReadCallbackTerminator readCallback(&base, nullptr);
1574 server->setReadCB(&readCallback);
1575 readCallback.setSocket(server);
1578 memset(buf, 'a', sizeof(buf));
1579 client->write(nullptr, buf, sizeof(buf));
1581 // Check that bytes are unencrypted
1583 EXPECT_EQ(1, recv(fds[1], &c, 1, MSG_PEEK));
1586 EventBaseAborter eba(&base, 3000);
1589 EXPECT_EQ(1, readCallback.buffers.size());
1590 EXPECT_EQ(AsyncSSLSocket::STATE_UNENCRYPTED, client->getSSLState());
1592 server->setReadCB(&readCallback);
1595 server->sslAccept(nullptr);
1596 client->sslConn(nullptr);
1598 // Do NOT wait for handshake, writing should be queued and happen after
1600 client->write(nullptr, buf, sizeof(buf));
1602 // Check that bytes are *not* unencrypted
1604 EXPECT_EQ(1, recv(fds[1], &c2, 1, MSG_PEEK));
1610 EXPECT_EQ(2, readCallback.buffers.size());
1611 EXPECT_EQ(AsyncSSLSocket::STATE_ESTABLISHED, client->getSSLState());
1614 TEST(AsyncSSLSocketTest, ConnResetErrorString) {
1615 // Start listening on a local port
1616 WriteCallbackBase writeCallback;
1617 WriteErrorCallback readCallback(&writeCallback);
1618 HandshakeCallback handshakeCallback(&readCallback,
1619 HandshakeCallback::EXPECT_ERROR);
1620 SSLServerAcceptCallback acceptCallback(&handshakeCallback);
1621 TestSSLServer server(&acceptCallback);
1623 auto socket = std::make_shared<BlockingSocket>(server.getAddress(), nullptr);
1625 uint8_t buf[3] = {0x16, 0x03, 0x01};
1626 socket->write(buf, sizeof(buf));
1627 socket->closeWithReset();
1629 handshakeCallback.waitForHandshake();
1631 handshakeCallback.errorString_.find("Network error"), std::string::npos);
1632 EXPECT_NE(handshakeCallback.errorString_.find("104"), std::string::npos);
1635 TEST(AsyncSSLSocketTest, ConnEOFErrorString) {
1636 // Start listening on a local port
1637 WriteCallbackBase writeCallback;
1638 WriteErrorCallback readCallback(&writeCallback);
1639 HandshakeCallback handshakeCallback(&readCallback,
1640 HandshakeCallback::EXPECT_ERROR);
1641 SSLServerAcceptCallback acceptCallback(&handshakeCallback);
1642 TestSSLServer server(&acceptCallback);
1644 auto socket = std::make_shared<BlockingSocket>(server.getAddress(), nullptr);
1646 uint8_t buf[3] = {0x16, 0x03, 0x01};
1647 socket->write(buf, sizeof(buf));
1650 handshakeCallback.waitForHandshake();
1652 handshakeCallback.errorString_.find("Connection EOF"), std::string::npos);
1653 EXPECT_NE(handshakeCallback.errorString_.find("EOF"), std::string::npos);
1656 TEST(AsyncSSLSocketTest, ConnOpenSSLErrorString) {
1657 // Start listening on a local port
1658 WriteCallbackBase writeCallback;
1659 WriteErrorCallback readCallback(&writeCallback);
1660 HandshakeCallback handshakeCallback(&readCallback,
1661 HandshakeCallback::EXPECT_ERROR);
1662 SSLServerAcceptCallback acceptCallback(&handshakeCallback);
1663 TestSSLServer server(&acceptCallback);
1665 auto socket = std::make_shared<BlockingSocket>(server.getAddress(), nullptr);
1667 uint8_t buf[256] = {0x16, 0x03};
1668 memset(buf + 2, 'a', sizeof(buf) - 2);
1669 socket->write(buf, sizeof(buf));
1672 handshakeCallback.waitForHandshake();
1673 EXPECT_NE(handshakeCallback.errorString_.find("SSL routines"),
1675 EXPECT_NE(handshakeCallback.errorString_.find("unknown protocol"),
1681 ///////////////////////////////////////////////////////////////////////////
1682 // init_unit_test_suite
1683 ///////////////////////////////////////////////////////////////////////////
1685 struct Initializer {
1687 signal(SIGPIPE, SIG_IGN);
1690 Initializer initializer;