proxygen
SSLSessionTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2016-present Facebook, Inc.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 #include <folly/ssl/SSLSession.h>
21 
22 #include <memory>
23 
24 using namespace std;
25 using namespace testing;
27 
28 namespace folly {
29 
30 void getfds(int fds[2]) {
31  if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) != 0) {
32  LOG(ERROR) << "failed to create socketpair: " << errnoStr(errno);
33  }
34  for (int idx = 0; idx < 2; ++idx) {
35  int flags = fcntl(fds[idx], F_GETFL, 0);
36  if (flags == -1) {
37  LOG(ERROR) << "failed to get flags for socket " << idx << ": "
38  << errnoStr(errno);
39  }
40  if (fcntl(fds[idx], F_SETFL, flags | O_NONBLOCK) != 0) {
41  LOG(ERROR) << "failed to put socket " << idx
42  << " in non-blocking mode: " << errnoStr(errno);
43  }
44  }
45 }
46 
47 void getctx(
48  std::shared_ptr<folly::SSLContext> clientCtx,
49  std::shared_ptr<folly::SSLContext> serverCtx) {
50  clientCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
51 
52  serverCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
53  serverCtx->loadCertificate(kTestCert);
54  serverCtx->loadPrivateKey(kTestKey);
55 }
56 
57 class SSLSessionTest : public testing::Test {
58  public:
59  void SetUp() override {
60  clientCtx.reset(new folly::SSLContext());
61  dfServerCtx.reset(new folly::SSLContext());
62  hskServerCtx.reset(new folly::SSLContext());
63  serverName = "xyz.newdev.facebook.com";
64  getctx(clientCtx, dfServerCtx);
65  }
66 
67  void TearDown() override {}
68 
70  std::shared_ptr<SSLContext> clientCtx;
71  std::shared_ptr<SSLContext> dfServerCtx;
72  // Use the same SSLContext to continue the handshake after
73  // tlsext_hostname match.
74  std::shared_ptr<SSLContext> hskServerCtx;
76 };
77 
84 TEST_F(SSLSessionTest, BasicTest) {
85  std::unique_ptr<SSLSession> sess;
86 
87  {
88  int fds[2];
89  getfds(fds);
90  AsyncSSLSocket::UniquePtr clientSock(
91  new AsyncSSLSocket(clientCtx, &eventBase, fds[0], serverName));
92  auto clientPtr = clientSock.get();
93  AsyncSSLSocket::UniquePtr serverSock(
94  new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
95  SSLHandshakeClient client(std::move(clientSock), false, false);
97  std::move(serverSock), false, false);
98 
99  eventBase.loop();
101 
102  sess = std::make_unique<SSLSession>(clientPtr->getSSLSession());
103  ASSERT_NE(sess.get(), nullptr);
104  }
105 
106  {
107  int fds[2];
108  getfds(fds);
109  AsyncSSLSocket::UniquePtr clientSock(
110  new AsyncSSLSocket(clientCtx, &eventBase, fds[0], serverName));
111  auto clientPtr = clientSock.get();
112  clientSock->setSSLSession(sess->getRawSSLSessionDangerous(), true);
113  AsyncSSLSocket::UniquePtr serverSock(
114  new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
115  SSLHandshakeClient client(std::move(clientSock), false, false);
117  std::move(serverSock), false, false);
118 
119  eventBase.loop();
121  ASSERT_TRUE(clientPtr->getSSLSessionReused());
122  }
123 }
124 TEST_F(SSLSessionTest, SerializeDeserializeTest) {
125  std::string sessiondata;
126 
127  {
128  int fds[2];
129  getfds(fds);
130  AsyncSSLSocket::UniquePtr clientSock(
131  new AsyncSSLSocket(clientCtx, &eventBase, fds[0], serverName));
132  auto clientPtr = clientSock.get();
133  AsyncSSLSocket::UniquePtr serverSock(
134  new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
135  SSLHandshakeClient client(std::move(clientSock), false, false);
137  std::move(serverSock), false, false);
138 
139  eventBase.loop();
141 
142  std::unique_ptr<SSLSession> sess =
143  std::make_unique<SSLSession>(clientPtr->getSSLSession());
144  sessiondata = sess->serialize();
145  ASSERT_TRUE(!sessiondata.empty());
146  }
147 
148  {
149  int fds[2];
150  getfds(fds);
151  AsyncSSLSocket::UniquePtr clientSock(
152  new AsyncSSLSocket(clientCtx, &eventBase, fds[0], serverName));
153  auto clientPtr = clientSock.get();
154  std::unique_ptr<SSLSession> sess =
155  std::make_unique<SSLSession>(sessiondata);
156  ASSERT_NE(sess.get(), nullptr);
157  clientSock->setSSLSession(sess->getRawSSLSessionDangerous(), true);
158  AsyncSSLSocket::UniquePtr serverSock(
159  new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
160  SSLHandshakeClient client(std::move(clientSock), false, false);
162  std::move(serverSock), false, false);
163 
164  eventBase.loop();
166  ASSERT_TRUE(clientPtr->getSSLSessionReused());
167  }
168 }
169 
170 TEST_F(SSLSessionTest, GetSessionID) {
171  int fds[2];
172  getfds(fds);
173  AsyncSSLSocket::UniquePtr clientSock(
174  new AsyncSSLSocket(clientCtx, &eventBase, fds[0], serverName));
175  auto clientPtr = clientSock.get();
176  AsyncSSLSocket::UniquePtr serverSock(
177  new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
178  SSLHandshakeClient client(std::move(clientSock), false, false);
180  std::move(serverSock), false, false);
181 
182  eventBase.loop();
184 
185  std::unique_ptr<SSLSession> sess =
186  std::make_unique<SSLSession>(clientPtr->getSSLSession());
187  ASSERT_NE(sess, nullptr);
188  auto sessID = sess->getSessionID();
189  ASSERT_GE(sessID.length(), 0);
190 }
191 } // namespace folly
#define ASSERT_GE(val1, val2)
Definition: gtest.h:1972
const char * kTestCert
flags
Definition: http_parser.h:127
const std::string kTestKey
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
STL namespace.
std::shared_ptr< SSLContext > hskServerCtx
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
std::shared_ptr< SSLContext > dfServerCtx
std::unique_ptr< AsyncSSLSocket, Destructor > UniquePtr
std::string getSessionID() const
Definition: SSLSession.h:43
SSL_SESSION * getRawSSLSessionDangerous()
Definition: SSLSession.h:56
void getfds(int fds[2])
void TearDown() override
fbstring errnoStr(int err)
Definition: String.cpp:463
TEST_F(SSLSessionTest, GetSessionID)
void SetUp() override
std::string serialize() const
Definition: SSLSession.h:38
const char * string
Definition: Conv.cpp:212
void getctx(std::shared_ptr< folly::SSLContext > clientCtx, std::shared_ptr< folly::SSLContext > serverCtx)
folly::EventBase eventBase
#define ASSERT_NE(val1, val2)
Definition: gtest.h:1960
#define ASSERT_TRUE(condition)
Definition: gtest.h:1865
int socketpair(int domain, int type, int protocol, NetworkSocket sv[2])
Definition: NetOps.cpp:416
std::shared_ptr< SSLContext > clientCtx