TEST(AsyncSSLSocketTest, GetClientCertificate) {
  EventBase eventBase;
  auto clientCtx = std::make_shared<SSLContext>();
  auto serverCtx = std::make_shared<SSLContext>();
  serverCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
  serverCtx->ciphers("ECDHE-RSA-AES128-SHA:AES128-SHA:AES256-SHA");
  serverCtx->loadPrivateKey(kTestKey);
  serverCtx->loadCertificate(kTestCert);
  serverCtx->loadTrustedCertificates(kClientTestCA);
  serverCtx->loadClientCAList(kClientTestCA);

  clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
  clientCtx->ciphers("AES256-SHA:AES128-SHA");
  clientCtx->loadPrivateKey(kClientTestKey);
  clientCtx->loadCertificate(kClientTestCert);
  clientCtx->loadTrustedCertificates(kTestCA);

  std::array<NetworkSocket, 2> fds;
  getfds(fds.data());

  AsyncSSLSocket::UniquePtr clientSock(
      new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
  AsyncSSLSocket::UniquePtr serverSock(
      new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));

  SSLHandshakeClient client(std::move(clientSock), true, true);
  SSLHandshakeServerParseClientHello server(std::move(serverSock), true, true);

  eventBase.loop();

  // Handshake should succeed.
  EXPECT_TRUE(client.handshakeSuccess_);
  EXPECT_TRUE(server.handshakeSuccess_);

  // Reclaim the sockets from SSLHandshakeBase.
  auto cliSocket = std::move(client).moveSocket();
  auto srvSocket = std::move(server).moveSocket();

  // Client cert retrieved from server side.
  auto serverPeerCert = srvSocket->getPeerCertificate();
  CHECK(serverPeerCert);

  // Client cert retrieved from client side.
  auto clientSelfCert = cliSocket->getSelfCertificate();
  CHECK(clientSelfCert);

  auto serverX509 = serverPeerCert->getX509();
  auto clientX509 = clientSelfCert->getX509();
  CHECK(serverX509);
  CHECK(clientX509);

  // The two certs should be the same.
  EXPECT_EQ(0, X509_cmp(clientX509.get(), serverX509.get()));
}
TEST(AsyncSSLSocketTest, GetClientCertificate) {
  EventBase eventBase;
  auto clientCtx = std::make_shared<SSLContext>();
  auto serverCtx = std::make_shared<SSLContext>();
  serverCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
  serverCtx->ciphers("ECDHE-RSA-AES128-SHA:AES128-SHA:AES256-SHA");
  serverCtx->loadPrivateKey(kTestKey);
  serverCtx->loadCertificate(kTestCert);
  serverCtx->loadTrustedCertificates(kClientTestCA);
  serverCtx->loadClientCAList(kClientTestCA);

  clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
  clientCtx->ciphers("AES256-SHA:AES128-SHA");
  clientCtx->loadPrivateKey(kClientTestKey);
  clientCtx->loadCertificate(kClientTestCert);
  clientCtx->loadTrustedCertificates(kTestCA);

  std::array<NetworkSocket, 2> fds;
  getfds(fds.data());

  AsyncSSLSocket::UniquePtr clientSock(
      new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
  AsyncSSLSocket::UniquePtr serverSock(
      new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));

  SSLHandshakeClient client(std::move(clientSock), true, true);
  SSLHandshakeServerParseClientHello server(std::move(serverSock), true, true);

  eventBase.loop();

   
  EXPECT_TRUE(client.handshakeSuccess_);
  EXPECT_TRUE(server.handshakeSuccess_);

   
  auto cliSocket = std::move(client).moveSocket();
  auto srvSocket = std::move(server).moveSocket();

   
  auto serverPeerCert = srvSocket->getPeerCertificate();
  CHECK(serverPeerCert);

   
  auto clientSelfCert = cliSocket->getSelfCertificate();
  CHECK(clientSelfCert);

  auto serverX509 = serverPeerCert->getX509();
  auto clientX509 = clientSelfCert->getX509();
  CHECK(serverX509);
  CHECK(clientX509);

   
  EXPECT_EQ(0, X509_cmp(clientX509.get(), serverX509.get()));
}