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 * Negative test for handshakeError().
207 TEST(AsyncSSLSocketTest, HandshakeError) {
208 // Start listening on a local port
209 WriteCallbackBase writeCallback;
210 ReadCallback readCallback(&writeCallback);
211 HandshakeCallback handshakeCallback(&readCallback);
212 HandshakeErrorCallback acceptCallback(&handshakeCallback);
213 TestSSLServer server(&acceptCallback);
215 // Set up SSL context.
216 std::shared_ptr<SSLContext> sslContext(new SSLContext());
217 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
220 auto socket = std::make_shared<BlockingSocket>(server.getAddress(),
227 uint8_t readbuf[128];
228 uint32_t bytesRead = socket->readAll(readbuf, sizeof(readbuf));
229 LOG(ERROR) << "readAll returned " << bytesRead << " instead of throwing";
230 } catch (AsyncSocketException &e) {
237 cerr << "HandshakeError test completed" << endl;
241 * Negative test for readError().
243 TEST(AsyncSSLSocketTest, ReadError) {
244 // Start listening on a local port
245 WriteCallbackBase writeCallback;
246 ReadErrorCallback readCallback(&writeCallback);
247 HandshakeCallback handshakeCallback(&readCallback);
248 SSLServerAcceptCallback acceptCallback(&handshakeCallback);
249 TestSSLServer server(&acceptCallback);
251 // Set up SSL context.
252 std::shared_ptr<SSLContext> sslContext(new SSLContext());
253 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
256 auto socket = std::make_shared<BlockingSocket>(server.getAddress(),
260 // write something to trigger ssl handshake
262 memset(buf, 'a', sizeof(buf));
263 socket->write(buf, sizeof(buf));
266 cerr << "ReadError test completed" << endl;
270 * Negative test for writeError().
272 TEST(AsyncSSLSocketTest, WriteError) {
273 // Start listening on a local port
274 WriteCallbackBase writeCallback;
275 WriteErrorCallback readCallback(&writeCallback);
276 HandshakeCallback handshakeCallback(&readCallback);
277 SSLServerAcceptCallback acceptCallback(&handshakeCallback);
278 TestSSLServer server(&acceptCallback);
280 // Set up SSL context.
281 std::shared_ptr<SSLContext> sslContext(new SSLContext());
282 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
285 auto socket = std::make_shared<BlockingSocket>(server.getAddress(),
289 // write something to trigger ssl handshake
291 memset(buf, 'a', sizeof(buf));
292 socket->write(buf, sizeof(buf));
295 cerr << "WriteError test completed" << endl;
299 * Test a socket with TCP_NODELAY unset.
301 TEST(AsyncSSLSocketTest, SocketWithDelay) {
302 // Start listening on a local port
303 WriteCallbackBase writeCallback;
304 ReadCallback readCallback(&writeCallback);
305 HandshakeCallback handshakeCallback(&readCallback);
306 SSLServerAcceptCallbackDelay acceptCallback(&handshakeCallback);
307 TestSSLServer server(&acceptCallback);
309 // Set up SSL context.
310 std::shared_ptr<SSLContext> sslContext(new SSLContext());
311 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
314 auto socket = std::make_shared<BlockingSocket>(server.getAddress(),
320 memset(buf, 'a', sizeof(buf));
321 socket->write(buf, sizeof(buf));
324 uint8_t readbuf[128];
325 uint32_t bytesRead = socket->readAll(readbuf, sizeof(readbuf));
326 EXPECT_EQ(bytesRead, 128);
327 EXPECT_EQ(memcmp(buf, readbuf, bytesRead), 0);
332 cerr << "SocketWithDelay test completed" << endl;
335 using NextProtocolTypePair =
336 std::pair<SSLContext::NextProtocolType, SSLContext::NextProtocolType>;
338 class NextProtocolTest : public testing::TestWithParam<NextProtocolTypePair> {
339 // For matching protos
341 void SetUp() override { getctx(clientCtx, serverCtx); }
343 void connect(bool unset = false) {
347 // unsetting NPN for any of [client, server] is enough to make NPN not
349 clientCtx->unsetNextProtocols();
352 AsyncSSLSocket::UniquePtr clientSock(
353 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
354 AsyncSSLSocket::UniquePtr serverSock(
355 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
356 client = folly::make_unique<NpnClient>(std::move(clientSock));
357 server = folly::make_unique<NpnServer>(std::move(serverSock));
362 void expectProtocol(const std::string& proto) {
363 EXPECT_NE(client->nextProtoLength, 0);
364 EXPECT_EQ(client->nextProtoLength, server->nextProtoLength);
366 memcmp(client->nextProto, server->nextProto, server->nextProtoLength),
368 string selected((const char*)client->nextProto, client->nextProtoLength);
369 EXPECT_EQ(proto, selected);
372 void expectNoProtocol() {
373 EXPECT_EQ(client->nextProtoLength, 0);
374 EXPECT_EQ(server->nextProtoLength, 0);
375 EXPECT_EQ(client->nextProto, nullptr);
376 EXPECT_EQ(server->nextProto, nullptr);
379 void expectProtocolType() {
380 if (GetParam().first == SSLContext::NextProtocolType::ANY &&
381 GetParam().second == SSLContext::NextProtocolType::ANY) {
382 EXPECT_EQ(client->protocolType, server->protocolType);
383 } else if (GetParam().first == SSLContext::NextProtocolType::ANY ||
384 GetParam().second == SSLContext::NextProtocolType::ANY) {
385 // Well not much we can say
387 expectProtocolType(GetParam());
391 void expectProtocolType(NextProtocolTypePair expected) {
392 EXPECT_EQ(client->protocolType, expected.first);
393 EXPECT_EQ(server->protocolType, expected.second);
397 std::shared_ptr<SSLContext> clientCtx{std::make_shared<SSLContext>()};
398 std::shared_ptr<SSLContext> serverCtx{std::make_shared<SSLContext>()};
400 std::unique_ptr<NpnClient> client;
401 std::unique_ptr<NpnServer> server;
404 class NextProtocolNPNOnlyTest : public NextProtocolTest {
405 // For mismatching protos
408 class NextProtocolMismatchTest : public NextProtocolTest {
409 // For mismatching protos
412 TEST_P(NextProtocolTest, NpnTestOverlap) {
413 clientCtx->setAdvertisedNextProtocols({"blub", "baz"}, GetParam().first);
414 serverCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"},
419 expectProtocol("baz");
420 expectProtocolType();
423 TEST_P(NextProtocolTest, NpnTestUnset) {
424 // Identical to above test, except that we want unset NPN before
426 clientCtx->setAdvertisedNextProtocols({"blub", "baz"}, GetParam().first);
427 serverCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"},
430 connect(true /* unset */);
432 // if alpn negotiation fails, type will appear as npn
434 EXPECT_EQ(client->protocolType, server->protocolType);
437 TEST_P(NextProtocolMismatchTest, NpnAlpnTestNoOverlap) {
438 clientCtx->setAdvertisedNextProtocols({"foo"}, GetParam().first);
439 serverCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"},
446 {SSLContext::NextProtocolType::NPN, SSLContext::NextProtocolType::NPN});
449 TEST_P(NextProtocolNPNOnlyTest, NpnTestNoOverlap) {
450 clientCtx->setAdvertisedNextProtocols({"blub"}, GetParam().first);
451 serverCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"},
456 expectProtocol("blub");
457 expectProtocolType();
460 TEST_P(NextProtocolNPNOnlyTest, NpnTestClientProtoFilterHit) {
461 clientCtx->setAdvertisedNextProtocols({"blub"}, GetParam().first);
462 clientCtx->setClientProtocolFilterCallback(clientProtoFilterPickPony);
463 serverCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"},
468 expectProtocol("ponies");
469 expectProtocolType();
472 TEST_P(NextProtocolNPNOnlyTest, NpnTestClientProtoFilterMiss) {
473 clientCtx->setAdvertisedNextProtocols({"blub"}, GetParam().first);
474 clientCtx->setClientProtocolFilterCallback(clientProtoFilterPickNone);
475 serverCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"},
480 expectProtocol("blub");
481 expectProtocolType();
484 TEST_P(NextProtocolTest, RandomizedNpnTest) {
485 // Probability that this test will fail is 2^-64, which could be considered
487 const int kTries = 64;
489 clientCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"},
491 serverCtx->setRandomizedAdvertisedNextProtocols({{1, {"foo"}}, {1, {"bar"}}},
494 std::set<string> selectedProtocols;
495 for (int i = 0; i < kTries; ++i) {
498 EXPECT_NE(client->nextProtoLength, 0);
499 EXPECT_EQ(client->nextProtoLength, server->nextProtoLength);
501 memcmp(client->nextProto, server->nextProto, server->nextProtoLength),
503 string selected((const char*)client->nextProto, client->nextProtoLength);
504 selectedProtocols.insert(selected);
505 expectProtocolType();
507 EXPECT_EQ(selectedProtocols.size(), 2);
510 INSTANTIATE_TEST_CASE_P(
513 ::testing::Values(NextProtocolTypePair(SSLContext::NextProtocolType::NPN,
514 SSLContext::NextProtocolType::NPN),
515 #if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_TLSEXT)
516 NextProtocolTypePair(SSLContext::NextProtocolType::ALPN,
517 SSLContext::NextProtocolType::ALPN),
519 NextProtocolTypePair(SSLContext::NextProtocolType::NPN,
520 SSLContext::NextProtocolType::ANY),
521 #if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_TLSEXT)
522 NextProtocolTypePair(SSLContext::NextProtocolType::ALPN,
523 SSLContext::NextProtocolType::ANY),
525 NextProtocolTypePair(SSLContext::NextProtocolType::ANY,
526 SSLContext::NextProtocolType::ANY)));
528 INSTANTIATE_TEST_CASE_P(
530 NextProtocolNPNOnlyTest,
531 ::testing::Values(NextProtocolTypePair(SSLContext::NextProtocolType::NPN,
532 SSLContext::NextProtocolType::NPN)));
534 #if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_TLSEXT)
535 INSTANTIATE_TEST_CASE_P(
537 NextProtocolMismatchTest,
538 ::testing::Values(NextProtocolTypePair(SSLContext::NextProtocolType::NPN,
539 SSLContext::NextProtocolType::ALPN),
540 NextProtocolTypePair(SSLContext::NextProtocolType::ALPN,
541 SSLContext::NextProtocolType::NPN)));
544 #ifndef OPENSSL_NO_TLSEXT
546 * 1. Client sends TLSEXT_HOSTNAME in client hello.
547 * 2. Server found a match SSL_CTX and use this SSL_CTX to
548 * continue the SSL handshake.
549 * 3. Server sends back TLSEXT_HOSTNAME in server hello.
551 TEST(AsyncSSLSocketTest, SNITestMatch) {
553 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
554 std::shared_ptr<SSLContext> dfServerCtx(new SSLContext);
555 // Use the same SSLContext to continue the handshake after
556 // tlsext_hostname match.
557 std::shared_ptr<SSLContext> hskServerCtx(dfServerCtx);
558 const std::string serverName("xyz.newdev.facebook.com");
561 getctx(clientCtx, dfServerCtx);
563 AsyncSSLSocket::UniquePtr clientSock(
564 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], serverName));
565 AsyncSSLSocket::UniquePtr serverSock(
566 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
567 SNIClient client(std::move(clientSock));
568 SNIServer server(std::move(serverSock),
575 EXPECT_TRUE(client.serverNameMatch);
576 EXPECT_TRUE(server.serverNameMatch);
580 * 1. Client sends TLSEXT_HOSTNAME in client hello.
581 * 2. Server cannot find a matching SSL_CTX and continue to use
582 * the current SSL_CTX to do the handshake.
583 * 3. Server does not send back TLSEXT_HOSTNAME in server hello.
585 TEST(AsyncSSLSocketTest, SNITestNotMatch) {
587 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
588 std::shared_ptr<SSLContext> dfServerCtx(new SSLContext);
589 // Use the same SSLContext to continue the handshake after
590 // tlsext_hostname match.
591 std::shared_ptr<SSLContext> hskServerCtx(dfServerCtx);
592 const std::string clientRequestingServerName("foo.com");
593 const std::string serverExpectedServerName("xyz.newdev.facebook.com");
597 getctx(clientCtx, dfServerCtx);
599 AsyncSSLSocket::UniquePtr clientSock(
600 new AsyncSSLSocket(clientCtx,
603 clientRequestingServerName));
604 AsyncSSLSocket::UniquePtr serverSock(
605 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
606 SNIClient client(std::move(clientSock));
607 SNIServer server(std::move(serverSock),
610 serverExpectedServerName);
614 EXPECT_TRUE(!client.serverNameMatch);
615 EXPECT_TRUE(!server.serverNameMatch);
618 * 1. Client sends TLSEXT_HOSTNAME in client hello.
619 * 2. We then change the serverName.
620 * 3. We expect that we get 'false' as the result for serNameMatch.
623 TEST(AsyncSSLSocketTest, SNITestChangeServerName) {
625 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
626 std::shared_ptr<SSLContext> dfServerCtx(new SSLContext);
627 // Use the same SSLContext to continue the handshake after
628 // tlsext_hostname match.
629 std::shared_ptr<SSLContext> hskServerCtx(dfServerCtx);
630 const std::string serverName("xyz.newdev.facebook.com");
633 getctx(clientCtx, dfServerCtx);
635 AsyncSSLSocket::UniquePtr clientSock(
636 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], serverName));
637 //Change the server name
638 std::string newName("new.com");
639 clientSock->setServerName(newName);
640 AsyncSSLSocket::UniquePtr serverSock(
641 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
642 SNIClient client(std::move(clientSock));
643 SNIServer server(std::move(serverSock),
650 EXPECT_TRUE(!client.serverNameMatch);
654 * 1. Client does not send TLSEXT_HOSTNAME in client hello.
655 * 2. Server does not send back TLSEXT_HOSTNAME in server hello.
657 TEST(AsyncSSLSocketTest, SNITestClientHelloNoHostname) {
659 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
660 std::shared_ptr<SSLContext> dfServerCtx(new SSLContext);
661 // Use the same SSLContext to continue the handshake after
662 // tlsext_hostname match.
663 std::shared_ptr<SSLContext> hskServerCtx(dfServerCtx);
664 const std::string serverExpectedServerName("xyz.newdev.facebook.com");
668 getctx(clientCtx, dfServerCtx);
670 AsyncSSLSocket::UniquePtr clientSock(
671 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
672 AsyncSSLSocket::UniquePtr serverSock(
673 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
674 SNIClient client(std::move(clientSock));
675 SNIServer server(std::move(serverSock),
678 serverExpectedServerName);
682 EXPECT_TRUE(!client.serverNameMatch);
683 EXPECT_TRUE(!server.serverNameMatch);
688 * Test SSL client socket
690 TEST(AsyncSSLSocketTest, SSLClientTest) {
691 // Start listening on a local port
692 WriteCallbackBase writeCallback;
693 ReadCallback readCallback(&writeCallback);
694 HandshakeCallback handshakeCallback(&readCallback);
695 SSLServerAcceptCallbackDelay acceptCallback(&handshakeCallback);
696 TestSSLServer server(&acceptCallback);
700 auto client = std::make_shared<SSLClient>(&eventBase, server.getAddress(), 1);
703 EventBaseAborter eba(&eventBase, 3000);
706 EXPECT_EQ(client->getMiss(), 1);
707 EXPECT_EQ(client->getHit(), 0);
709 cerr << "SSLClientTest test completed" << endl;
714 * Test SSL client socket session re-use
716 TEST(AsyncSSLSocketTest, SSLClientTestReuse) {
717 // Start listening on a local port
718 WriteCallbackBase writeCallback;
719 ReadCallback readCallback(&writeCallback);
720 HandshakeCallback handshakeCallback(&readCallback);
721 SSLServerAcceptCallbackDelay acceptCallback(&handshakeCallback);
722 TestSSLServer server(&acceptCallback);
727 std::make_shared<SSLClient>(&eventBase, server.getAddress(), 10);
730 EventBaseAborter eba(&eventBase, 3000);
733 EXPECT_EQ(client->getMiss(), 1);
734 EXPECT_EQ(client->getHit(), 9);
736 cerr << "SSLClientTestReuse test completed" << endl;
740 * Test SSL client socket timeout
742 TEST(AsyncSSLSocketTest, SSLClientTimeoutTest) {
743 // Start listening on a local port
744 EmptyReadCallback readCallback;
745 HandshakeCallback handshakeCallback(&readCallback,
746 HandshakeCallback::EXPECT_ERROR);
747 HandshakeTimeoutCallback acceptCallback(&handshakeCallback);
748 TestSSLServer server(&acceptCallback);
753 std::make_shared<SSLClient>(&eventBase, server.getAddress(), 1, 10);
754 client->connect(true /* write before connect completes */);
755 EventBaseAborter eba(&eventBase, 3000);
759 // This is checking that the connectError callback precedes any queued
760 // writeError callbacks. This matches AsyncSocket's behavior
761 EXPECT_EQ(client->getWriteAfterConnectErrors(), 1);
762 EXPECT_EQ(client->getErrors(), 1);
763 EXPECT_EQ(client->getMiss(), 0);
764 EXPECT_EQ(client->getHit(), 0);
766 cerr << "SSLClientTimeoutTest test completed" << endl;
771 * Test SSL server async cache
773 TEST(AsyncSSLSocketTest, SSLServerAsyncCacheTest) {
774 // Start listening on a local port
775 WriteCallbackBase writeCallback;
776 ReadCallback readCallback(&writeCallback);
777 HandshakeCallback handshakeCallback(&readCallback);
778 SSLServerAsyncCacheAcceptCallback acceptCallback(&handshakeCallback);
779 TestSSLAsyncCacheServer server(&acceptCallback);
784 std::make_shared<SSLClient>(&eventBase, server.getAddress(), 10, 500);
787 EventBaseAborter eba(&eventBase, 3000);
790 EXPECT_EQ(server.getAsyncCallbacks(), 18);
791 EXPECT_EQ(server.getAsyncLookups(), 9);
792 EXPECT_EQ(client->getMiss(), 10);
793 EXPECT_EQ(client->getHit(), 0);
795 cerr << "SSLServerAsyncCacheTest test completed" << endl;
800 * Test SSL server accept timeout with cache path
802 TEST(AsyncSSLSocketTest, SSLServerTimeoutTest) {
803 // Start listening on a local port
804 WriteCallbackBase writeCallback;
805 ReadCallback readCallback(&writeCallback);
806 EmptyReadCallback clientReadCallback;
807 HandshakeCallback handshakeCallback(&readCallback);
808 SSLServerAcceptCallback acceptCallback(&handshakeCallback, 50);
809 TestSSLAsyncCacheServer server(&acceptCallback);
813 // only do a TCP connect
814 std::shared_ptr<AsyncSocket> sock = AsyncSocket::newSocket(&eventBase);
815 sock->connect(nullptr, server.getAddress());
816 clientReadCallback.tcpSocket_ = sock;
817 sock->setReadCB(&clientReadCallback);
819 EventBaseAborter eba(&eventBase, 3000);
822 EXPECT_EQ(readCallback.state, STATE_WAITING);
824 cerr << "SSLServerTimeoutTest test completed" << endl;
828 * Test SSL server accept timeout with cache path
830 TEST(AsyncSSLSocketTest, SSLServerAsyncCacheTimeoutTest) {
831 // Start listening on a local port
832 WriteCallbackBase writeCallback;
833 ReadCallback readCallback(&writeCallback);
834 HandshakeCallback handshakeCallback(&readCallback);
835 SSLServerAsyncCacheAcceptCallback acceptCallback(&handshakeCallback, 50);
836 TestSSLAsyncCacheServer server(&acceptCallback);
840 auto client = std::make_shared<SSLClient>(&eventBase, server.getAddress(), 2);
843 EventBaseAborter eba(&eventBase, 3000);
846 EXPECT_EQ(server.getAsyncCallbacks(), 1);
847 EXPECT_EQ(server.getAsyncLookups(), 1);
848 EXPECT_EQ(client->getErrors(), 1);
849 EXPECT_EQ(client->getMiss(), 1);
850 EXPECT_EQ(client->getHit(), 0);
852 cerr << "SSLServerAsyncCacheTimeoutTest test completed" << endl;
856 * Test SSL server accept timeout with cache path
858 TEST(AsyncSSLSocketTest, SSLServerCacheCloseTest) {
859 // Start listening on a local port
860 WriteCallbackBase writeCallback;
861 ReadCallback readCallback(&writeCallback);
862 HandshakeCallback handshakeCallback(&readCallback,
863 HandshakeCallback::EXPECT_ERROR);
864 SSLServerAsyncCacheAcceptCallback acceptCallback(&handshakeCallback);
865 TestSSLAsyncCacheServer server(&acceptCallback, 500);
870 std::make_shared<SSLClient>(&eventBase, server.getAddress(), 2, 100);
873 EventBaseAborter eba(&eventBase, 3000);
876 server.getEventBase().runInEventBaseThread([&handshakeCallback]{
877 handshakeCallback.closeSocket();});
878 // give time for the cache lookup to come back and find it closed
879 handshakeCallback.waitForHandshake();
881 EXPECT_EQ(server.getAsyncCallbacks(), 1);
882 EXPECT_EQ(server.getAsyncLookups(), 1);
883 EXPECT_EQ(client->getErrors(), 1);
884 EXPECT_EQ(client->getMiss(), 1);
885 EXPECT_EQ(client->getHit(), 0);
887 cerr << "SSLServerCacheCloseTest test completed" << endl;
891 * Verify Client Ciphers obtained using SSL MSG Callback.
893 TEST(AsyncSSLSocketTest, SSLParseClientHelloSuccess) {
895 auto clientCtx = std::make_shared<SSLContext>();
896 auto serverCtx = std::make_shared<SSLContext>();
897 serverCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
898 serverCtx->ciphers("RSA:!SHA:!NULL:!SHA256@STRENGTH");
899 serverCtx->loadPrivateKey(testKey);
900 serverCtx->loadCertificate(testCert);
901 serverCtx->loadTrustedCertificates(testCA);
902 serverCtx->loadClientCAList(testCA);
904 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
905 clientCtx->ciphers("RC4-SHA:AES128-SHA:AES256-SHA:RC4-MD5");
906 clientCtx->loadPrivateKey(testKey);
907 clientCtx->loadCertificate(testCert);
908 clientCtx->loadTrustedCertificates(testCA);
913 AsyncSSLSocket::UniquePtr clientSock(
914 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
915 AsyncSSLSocket::UniquePtr serverSock(
916 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
918 SSLHandshakeClient client(std::move(clientSock), true, true);
919 SSLHandshakeServerParseClientHello server(std::move(serverSock), true, true);
923 EXPECT_EQ(server.clientCiphers_,
924 "RC4-SHA:AES128-SHA:AES256-SHA:RC4-MD5:00ff");
925 EXPECT_TRUE(client.handshakeVerify_);
926 EXPECT_TRUE(client.handshakeSuccess_);
927 EXPECT_TRUE(!client.handshakeError_);
928 EXPECT_TRUE(server.handshakeVerify_);
929 EXPECT_TRUE(server.handshakeSuccess_);
930 EXPECT_TRUE(!server.handshakeError_);
933 TEST(AsyncSSLSocketTest, SSLParseClientHelloOnePacket) {
935 auto ctx = std::make_shared<SSLContext>();
941 uint8_t majorVersion = 18;
942 uint8_t minorVersion = 25;
944 // Create callback buf
945 auto buf = IOBuf::create(bufLen);
947 folly::io::RWPrivateCursor cursor(buf.get());
948 cursor.write<uint8_t>(SSL3_MT_CLIENT_HELLO);
949 cursor.write<uint16_t>(0);
950 cursor.write<uint8_t>(38);
951 cursor.write<uint8_t>(majorVersion);
952 cursor.write<uint8_t>(minorVersion);
954 cursor.write<uint32_t>(0);
956 SSL* ssl = ctx->createSSL();
957 SCOPE_EXIT { SSL_free(ssl); };
958 AsyncSSLSocket::UniquePtr sock(
959 new AsyncSSLSocket(ctx, &eventBase, fds[0], true));
960 sock->enableClientHelloParsing();
962 // Test client hello parsing in one packet
963 AsyncSSLSocket::clientHelloParsingCallback(
964 0, 0, SSL3_RT_HANDSHAKE, buf->data(), buf->length(), ssl, sock.get());
967 auto parsedClientHello = sock->getClientHelloInfo();
968 EXPECT_TRUE(parsedClientHello != nullptr);
969 EXPECT_EQ(parsedClientHello->clientHelloMajorVersion_, majorVersion);
970 EXPECT_EQ(parsedClientHello->clientHelloMinorVersion_, minorVersion);
973 TEST(AsyncSSLSocketTest, SSLParseClientHelloTwoPackets) {
975 auto ctx = std::make_shared<SSLContext>();
981 uint8_t majorVersion = 18;
982 uint8_t minorVersion = 25;
984 // Create callback buf
985 auto buf = IOBuf::create(bufLen);
987 folly::io::RWPrivateCursor cursor(buf.get());
988 cursor.write<uint8_t>(SSL3_MT_CLIENT_HELLO);
989 cursor.write<uint16_t>(0);
990 cursor.write<uint8_t>(38);
991 cursor.write<uint8_t>(majorVersion);
992 cursor.write<uint8_t>(minorVersion);
994 cursor.write<uint32_t>(0);
996 SSL* ssl = ctx->createSSL();
997 SCOPE_EXIT { SSL_free(ssl); };
998 AsyncSSLSocket::UniquePtr sock(
999 new AsyncSSLSocket(ctx, &eventBase, fds[0], true));
1000 sock->enableClientHelloParsing();
1002 // Test parsing with two packets with first packet size < 3
1003 auto bufCopy = folly::IOBuf::copyBuffer(buf->data(), 2);
1004 AsyncSSLSocket::clientHelloParsingCallback(
1005 0, 0, SSL3_RT_HANDSHAKE, bufCopy->data(), bufCopy->length(),
1008 bufCopy = folly::IOBuf::copyBuffer(buf->data() + 2, buf->length() - 2);
1009 AsyncSSLSocket::clientHelloParsingCallback(
1010 0, 0, SSL3_RT_HANDSHAKE, bufCopy->data(), bufCopy->length(),
1014 auto parsedClientHello = sock->getClientHelloInfo();
1015 EXPECT_TRUE(parsedClientHello != nullptr);
1016 EXPECT_EQ(parsedClientHello->clientHelloMajorVersion_, majorVersion);
1017 EXPECT_EQ(parsedClientHello->clientHelloMinorVersion_, minorVersion);
1020 TEST(AsyncSSLSocketTest, SSLParseClientHelloMultiplePackets) {
1021 EventBase eventBase;
1022 auto ctx = std::make_shared<SSLContext>();
1028 uint8_t majorVersion = 18;
1029 uint8_t minorVersion = 25;
1031 // Create callback buf
1032 auto buf = IOBuf::create(bufLen);
1033 buf->append(bufLen);
1034 folly::io::RWPrivateCursor cursor(buf.get());
1035 cursor.write<uint8_t>(SSL3_MT_CLIENT_HELLO);
1036 cursor.write<uint16_t>(0);
1037 cursor.write<uint8_t>(38);
1038 cursor.write<uint8_t>(majorVersion);
1039 cursor.write<uint8_t>(minorVersion);
1041 cursor.write<uint32_t>(0);
1043 SSL* ssl = ctx->createSSL();
1044 SCOPE_EXIT { SSL_free(ssl); };
1045 AsyncSSLSocket::UniquePtr sock(
1046 new AsyncSSLSocket(ctx, &eventBase, fds[0], true));
1047 sock->enableClientHelloParsing();
1049 // Test parsing with multiple small packets
1050 for (uint64_t i = 0; i < buf->length(); i += 3) {
1051 auto bufCopy = folly::IOBuf::copyBuffer(
1052 buf->data() + i, std::min((uint64_t)3, buf->length() - i));
1053 AsyncSSLSocket::clientHelloParsingCallback(
1054 0, 0, SSL3_RT_HANDSHAKE, bufCopy->data(), bufCopy->length(),
1059 auto parsedClientHello = sock->getClientHelloInfo();
1060 EXPECT_TRUE(parsedClientHello != nullptr);
1061 EXPECT_EQ(parsedClientHello->clientHelloMajorVersion_, majorVersion);
1062 EXPECT_EQ(parsedClientHello->clientHelloMinorVersion_, minorVersion);
1066 * Verify sucessful behavior of SSL certificate validation.
1068 TEST(AsyncSSLSocketTest, SSLHandshakeValidationSuccess) {
1069 EventBase eventBase;
1070 auto clientCtx = std::make_shared<SSLContext>();
1071 auto dfServerCtx = std::make_shared<SSLContext>();
1075 getctx(clientCtx, dfServerCtx);
1077 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1078 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1080 AsyncSSLSocket::UniquePtr clientSock(
1081 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1082 AsyncSSLSocket::UniquePtr serverSock(
1083 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1085 SSLHandshakeClient client(std::move(clientSock), true, true);
1086 clientCtx->loadTrustedCertificates(testCA);
1088 SSLHandshakeServer server(std::move(serverSock), true, true);
1092 EXPECT_TRUE(client.handshakeVerify_);
1093 EXPECT_TRUE(client.handshakeSuccess_);
1094 EXPECT_TRUE(!client.handshakeError_);
1095 EXPECT_LE(0, client.handshakeTime.count());
1096 EXPECT_TRUE(!server.handshakeVerify_);
1097 EXPECT_TRUE(server.handshakeSuccess_);
1098 EXPECT_TRUE(!server.handshakeError_);
1099 EXPECT_LE(0, server.handshakeTime.count());
1103 * Verify that the client's verification callback is able to fail SSL
1104 * connection establishment.
1106 TEST(AsyncSSLSocketTest, SSLHandshakeValidationFailure) {
1107 EventBase eventBase;
1108 auto clientCtx = std::make_shared<SSLContext>();
1109 auto dfServerCtx = std::make_shared<SSLContext>();
1113 getctx(clientCtx, dfServerCtx);
1115 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1116 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1118 AsyncSSLSocket::UniquePtr clientSock(
1119 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1120 AsyncSSLSocket::UniquePtr serverSock(
1121 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1123 SSLHandshakeClient client(std::move(clientSock), true, false);
1124 clientCtx->loadTrustedCertificates(testCA);
1126 SSLHandshakeServer server(std::move(serverSock), true, true);
1130 EXPECT_TRUE(client.handshakeVerify_);
1131 EXPECT_TRUE(!client.handshakeSuccess_);
1132 EXPECT_TRUE(client.handshakeError_);
1133 EXPECT_LE(0, client.handshakeTime.count());
1134 EXPECT_TRUE(!server.handshakeVerify_);
1135 EXPECT_TRUE(!server.handshakeSuccess_);
1136 EXPECT_TRUE(server.handshakeError_);
1137 EXPECT_LE(0, server.handshakeTime.count());
1141 * Verify that the options in SSLContext can be overridden in
1142 * sslConnect/Accept.i.e specifying that no validation should be performed
1143 * allows an otherwise-invalid certificate to be accepted and doesn't fire
1144 * the validation callback.
1146 TEST(AsyncSSLSocketTest, OverrideSSLCtxDisableVerify) {
1147 EventBase eventBase;
1148 auto clientCtx = std::make_shared<SSLContext>();
1149 auto dfServerCtx = std::make_shared<SSLContext>();
1153 getctx(clientCtx, dfServerCtx);
1155 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1156 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1158 AsyncSSLSocket::UniquePtr clientSock(
1159 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1160 AsyncSSLSocket::UniquePtr serverSock(
1161 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1163 SSLHandshakeClientNoVerify client(std::move(clientSock), false, false);
1164 clientCtx->loadTrustedCertificates(testCA);
1166 SSLHandshakeServerNoVerify server(std::move(serverSock), false, false);
1170 EXPECT_TRUE(!client.handshakeVerify_);
1171 EXPECT_TRUE(client.handshakeSuccess_);
1172 EXPECT_TRUE(!client.handshakeError_);
1173 EXPECT_LE(0, client.handshakeTime.count());
1174 EXPECT_TRUE(!server.handshakeVerify_);
1175 EXPECT_TRUE(server.handshakeSuccess_);
1176 EXPECT_TRUE(!server.handshakeError_);
1177 EXPECT_LE(0, server.handshakeTime.count());
1181 * Verify that the options in SSLContext can be overridden in
1182 * sslConnect/Accept. Enable verification even if context says otherwise.
1183 * Test requireClientCert with client cert
1185 TEST(AsyncSSLSocketTest, OverrideSSLCtxEnableVerify) {
1186 EventBase eventBase;
1187 auto clientCtx = std::make_shared<SSLContext>();
1188 auto serverCtx = std::make_shared<SSLContext>();
1189 serverCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1190 serverCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1191 serverCtx->loadPrivateKey(testKey);
1192 serverCtx->loadCertificate(testCert);
1193 serverCtx->loadTrustedCertificates(testCA);
1194 serverCtx->loadClientCAList(testCA);
1196 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1197 clientCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1198 clientCtx->loadPrivateKey(testKey);
1199 clientCtx->loadCertificate(testCert);
1200 clientCtx->loadTrustedCertificates(testCA);
1205 AsyncSSLSocket::UniquePtr clientSock(
1206 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1207 AsyncSSLSocket::UniquePtr serverSock(
1208 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
1210 SSLHandshakeClientDoVerify client(std::move(clientSock), true, true);
1211 SSLHandshakeServerDoVerify server(std::move(serverSock), true, true);
1215 EXPECT_TRUE(client.handshakeVerify_);
1216 EXPECT_TRUE(client.handshakeSuccess_);
1217 EXPECT_FALSE(client.handshakeError_);
1218 EXPECT_LE(0, client.handshakeTime.count());
1219 EXPECT_TRUE(server.handshakeVerify_);
1220 EXPECT_TRUE(server.handshakeSuccess_);
1221 EXPECT_FALSE(server.handshakeError_);
1222 EXPECT_LE(0, server.handshakeTime.count());
1226 * Verify that the client's verification callback is able to override
1227 * the preverification failure and allow a successful connection.
1229 TEST(AsyncSSLSocketTest, SSLHandshakeValidationOverride) {
1230 EventBase eventBase;
1231 auto clientCtx = std::make_shared<SSLContext>();
1232 auto dfServerCtx = std::make_shared<SSLContext>();
1236 getctx(clientCtx, dfServerCtx);
1238 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1239 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1241 AsyncSSLSocket::UniquePtr clientSock(
1242 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1243 AsyncSSLSocket::UniquePtr serverSock(
1244 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1246 SSLHandshakeClient client(std::move(clientSock), false, true);
1247 SSLHandshakeServer server(std::move(serverSock), true, true);
1251 EXPECT_TRUE(client.handshakeVerify_);
1252 EXPECT_TRUE(client.handshakeSuccess_);
1253 EXPECT_TRUE(!client.handshakeError_);
1254 EXPECT_LE(0, client.handshakeTime.count());
1255 EXPECT_TRUE(!server.handshakeVerify_);
1256 EXPECT_TRUE(server.handshakeSuccess_);
1257 EXPECT_TRUE(!server.handshakeError_);
1258 EXPECT_LE(0, server.handshakeTime.count());
1262 * Verify that specifying that no validation should be performed allows an
1263 * otherwise-invalid certificate to be accepted and doesn't fire the validation
1266 TEST(AsyncSSLSocketTest, SSLHandshakeValidationSkip) {
1267 EventBase eventBase;
1268 auto clientCtx = std::make_shared<SSLContext>();
1269 auto dfServerCtx = std::make_shared<SSLContext>();
1273 getctx(clientCtx, dfServerCtx);
1275 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1276 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1278 AsyncSSLSocket::UniquePtr clientSock(
1279 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1280 AsyncSSLSocket::UniquePtr serverSock(
1281 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1283 SSLHandshakeClient client(std::move(clientSock), false, false);
1284 SSLHandshakeServer server(std::move(serverSock), false, false);
1288 EXPECT_TRUE(!client.handshakeVerify_);
1289 EXPECT_TRUE(client.handshakeSuccess_);
1290 EXPECT_TRUE(!client.handshakeError_);
1291 EXPECT_LE(0, client.handshakeTime.count());
1292 EXPECT_TRUE(!server.handshakeVerify_);
1293 EXPECT_TRUE(server.handshakeSuccess_);
1294 EXPECT_TRUE(!server.handshakeError_);
1295 EXPECT_LE(0, server.handshakeTime.count());
1299 * Test requireClientCert with client cert
1301 TEST(AsyncSSLSocketTest, ClientCertHandshakeSuccess) {
1302 EventBase eventBase;
1303 auto clientCtx = std::make_shared<SSLContext>();
1304 auto serverCtx = std::make_shared<SSLContext>();
1305 serverCtx->setVerificationOption(
1306 SSLContext::SSLVerifyPeerEnum::VERIFY_REQ_CLIENT_CERT);
1307 serverCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1308 serverCtx->loadPrivateKey(testKey);
1309 serverCtx->loadCertificate(testCert);
1310 serverCtx->loadTrustedCertificates(testCA);
1311 serverCtx->loadClientCAList(testCA);
1313 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1314 clientCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1315 clientCtx->loadPrivateKey(testKey);
1316 clientCtx->loadCertificate(testCert);
1317 clientCtx->loadTrustedCertificates(testCA);
1322 AsyncSSLSocket::UniquePtr clientSock(
1323 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1324 AsyncSSLSocket::UniquePtr serverSock(
1325 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
1327 SSLHandshakeClient client(std::move(clientSock), true, true);
1328 SSLHandshakeServer server(std::move(serverSock), true, true);
1332 EXPECT_TRUE(client.handshakeVerify_);
1333 EXPECT_TRUE(client.handshakeSuccess_);
1334 EXPECT_FALSE(client.handshakeError_);
1335 EXPECT_LE(0, client.handshakeTime.count());
1336 EXPECT_TRUE(server.handshakeVerify_);
1337 EXPECT_TRUE(server.handshakeSuccess_);
1338 EXPECT_FALSE(server.handshakeError_);
1339 EXPECT_LE(0, server.handshakeTime.count());
1344 * Test requireClientCert with no client cert
1346 TEST(AsyncSSLSocketTest, NoClientCertHandshakeError) {
1347 EventBase eventBase;
1348 auto clientCtx = std::make_shared<SSLContext>();
1349 auto serverCtx = std::make_shared<SSLContext>();
1350 serverCtx->setVerificationOption(
1351 SSLContext::SSLVerifyPeerEnum::VERIFY_REQ_CLIENT_CERT);
1352 serverCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1353 serverCtx->loadPrivateKey(testKey);
1354 serverCtx->loadCertificate(testCert);
1355 serverCtx->loadTrustedCertificates(testCA);
1356 serverCtx->loadClientCAList(testCA);
1357 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1358 clientCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1363 AsyncSSLSocket::UniquePtr clientSock(
1364 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1365 AsyncSSLSocket::UniquePtr serverSock(
1366 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
1368 SSLHandshakeClient client(std::move(clientSock), false, false);
1369 SSLHandshakeServer server(std::move(serverSock), false, false);
1373 EXPECT_FALSE(server.handshakeVerify_);
1374 EXPECT_FALSE(server.handshakeSuccess_);
1375 EXPECT_TRUE(server.handshakeError_);
1376 EXPECT_LE(0, client.handshakeTime.count());
1377 EXPECT_LE(0, server.handshakeTime.count());
1380 TEST(AsyncSSLSocketTest, LoadCertFromMemory) {
1381 auto cert = getFileAsBuf(testCert);
1382 auto key = getFileAsBuf(testKey);
1384 ssl::BioUniquePtr certBio(BIO_new(BIO_s_mem()));
1385 BIO_write(certBio.get(), cert.data(), cert.size());
1386 ssl::BioUniquePtr keyBio(BIO_new(BIO_s_mem()));
1387 BIO_write(keyBio.get(), key.data(), key.size());
1389 // Create SSL structs from buffers to get properties
1390 ssl::X509UniquePtr certStruct(
1391 PEM_read_bio_X509(certBio.get(), nullptr, nullptr, nullptr));
1392 ssl::EvpPkeyUniquePtr keyStruct(
1393 PEM_read_bio_PrivateKey(keyBio.get(), nullptr, nullptr, nullptr));
1397 auto origCommonName = getCommonName(certStruct.get());
1398 auto origKeySize = EVP_PKEY_bits(keyStruct.get());
1399 certStruct = nullptr;
1400 keyStruct = nullptr;
1402 auto ctx = std::make_shared<SSLContext>();
1403 ctx->loadPrivateKeyFromBufferPEM(key);
1404 ctx->loadCertificateFromBufferPEM(cert);
1405 ctx->loadTrustedCertificates(testCA);
1407 ssl::SSLUniquePtr ssl(ctx->createSSL());
1409 auto newCert = SSL_get_certificate(ssl.get());
1410 auto newKey = SSL_get_privatekey(ssl.get());
1412 // Get properties from SSL struct
1413 auto newCommonName = getCommonName(newCert);
1414 auto newKeySize = EVP_PKEY_bits(newKey);
1416 // Check that the key and cert have the expected properties
1417 EXPECT_EQ(origCommonName, newCommonName);
1418 EXPECT_EQ(origKeySize, newKeySize);
1421 TEST(AsyncSSLSocketTest, MinWriteSizeTest) {
1424 // Set up SSL context.
1425 auto sslContext = std::make_shared<SSLContext>();
1426 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1428 // create SSL socket
1429 AsyncSSLSocket::UniquePtr socket(new AsyncSSLSocket(sslContext, &eb));
1431 EXPECT_EQ(1500, socket->getMinWriteSize());
1433 socket->setMinWriteSize(0);
1434 EXPECT_EQ(0, socket->getMinWriteSize());
1435 socket->setMinWriteSize(50000);
1436 EXPECT_EQ(50000, socket->getMinWriteSize());
1439 class ReadCallbackTerminator : public ReadCallback {
1441 ReadCallbackTerminator(EventBase* base, WriteCallbackBase *wcb)
1445 // Do not write data back, terminate the loop.
1446 void readDataAvailable(size_t len) noexcept override {
1447 std::cerr << "readDataAvailable, len " << len << std::endl;
1449 currentBuffer.length = len;
1451 buffers.push_back(currentBuffer);
1452 currentBuffer.reset();
1453 state = STATE_SUCCEEDED;
1455 socket_->setReadCB(nullptr);
1456 base_->terminateLoopSoon();
1464 * Test a full unencrypted codepath
1466 TEST(AsyncSSLSocketTest, UnencryptedTest) {
1469 auto clientCtx = std::make_shared<folly::SSLContext>();
1470 auto serverCtx = std::make_shared<folly::SSLContext>();
1473 getctx(clientCtx, serverCtx);
1474 auto client = AsyncSSLSocket::newSocket(
1475 clientCtx, &base, fds[0], false, true);
1476 auto server = AsyncSSLSocket::newSocket(
1477 serverCtx, &base, fds[1], true, true);
1479 ReadCallbackTerminator readCallback(&base, nullptr);
1480 server->setReadCB(&readCallback);
1481 readCallback.setSocket(server);
1484 memset(buf, 'a', sizeof(buf));
1485 client->write(nullptr, buf, sizeof(buf));
1487 // Check that bytes are unencrypted
1489 EXPECT_EQ(1, recv(fds[1], &c, 1, MSG_PEEK));
1492 EventBaseAborter eba(&base, 3000);
1495 EXPECT_EQ(1, readCallback.buffers.size());
1496 EXPECT_EQ(AsyncSSLSocket::STATE_UNENCRYPTED, client->getSSLState());
1498 server->setReadCB(&readCallback);
1501 server->sslAccept(nullptr);
1502 client->sslConn(nullptr);
1504 // Do NOT wait for handshake, writing should be queued and happen after
1506 client->write(nullptr, buf, sizeof(buf));
1508 // Check that bytes are *not* unencrypted
1510 EXPECT_EQ(1, recv(fds[1], &c2, 1, MSG_PEEK));
1516 EXPECT_EQ(2, readCallback.buffers.size());
1517 EXPECT_EQ(AsyncSSLSocket::STATE_ESTABLISHED, client->getSSLState());
1520 TEST(AsyncSSLSocketTest, ConnResetErrorString) {
1521 // Start listening on a local port
1522 WriteCallbackBase writeCallback;
1523 WriteErrorCallback readCallback(&writeCallback);
1524 HandshakeCallback handshakeCallback(&readCallback,
1525 HandshakeCallback::EXPECT_ERROR);
1526 SSLServerAcceptCallback acceptCallback(&handshakeCallback);
1527 TestSSLServer server(&acceptCallback);
1529 auto socket = std::make_shared<BlockingSocket>(server.getAddress(), nullptr);
1531 uint8_t buf[3] = {0x16, 0x03, 0x01};
1532 socket->write(buf, sizeof(buf));
1533 socket->closeWithReset();
1535 handshakeCallback.waitForHandshake();
1536 EXPECT_NE(handshakeCallback.errorString_.find("SSL_ERROR_SYSCALL"),
1538 EXPECT_NE(handshakeCallback.errorString_.find("104"), std::string::npos);
1541 TEST(AsyncSSLSocketTest, ConnEOFErrorString) {
1542 // Start listening on a local port
1543 WriteCallbackBase writeCallback;
1544 WriteErrorCallback readCallback(&writeCallback);
1545 HandshakeCallback handshakeCallback(&readCallback,
1546 HandshakeCallback::EXPECT_ERROR);
1547 SSLServerAcceptCallback acceptCallback(&handshakeCallback);
1548 TestSSLServer server(&acceptCallback);
1550 auto socket = std::make_shared<BlockingSocket>(server.getAddress(), nullptr);
1552 uint8_t buf[3] = {0x16, 0x03, 0x01};
1553 socket->write(buf, sizeof(buf));
1556 handshakeCallback.waitForHandshake();
1557 EXPECT_NE(handshakeCallback.errorString_.find("SSL_ERROR_SYSCALL"),
1559 EXPECT_NE(handshakeCallback.errorString_.find("EOF"), std::string::npos);
1562 TEST(AsyncSSLSocketTest, ConnOpenSSLErrorString) {
1563 // Start listening on a local port
1564 WriteCallbackBase writeCallback;
1565 WriteErrorCallback readCallback(&writeCallback);
1566 HandshakeCallback handshakeCallback(&readCallback,
1567 HandshakeCallback::EXPECT_ERROR);
1568 SSLServerAcceptCallback acceptCallback(&handshakeCallback);
1569 TestSSLServer server(&acceptCallback);
1571 auto socket = std::make_shared<BlockingSocket>(server.getAddress(), nullptr);
1573 uint8_t buf[256] = {0x16, 0x03};
1574 memset(buf + 2, 'a', sizeof(buf) - 2);
1575 socket->write(buf, sizeof(buf));
1578 handshakeCallback.waitForHandshake();
1579 EXPECT_NE(handshakeCallback.errorString_.find("SSL routines"),
1581 EXPECT_NE(handshakeCallback.errorString_.find("unknown protocol"),
1587 ///////////////////////////////////////////////////////////////////////////
1588 // init_unit_test_suite
1589 ///////////////////////////////////////////////////////////////////////////
1591 struct Initializer {
1593 signal(SIGPIPE, SIG_IGN);
1596 Initializer initializer;