proxygen
HandshakeTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree.
7  */
8 
9 #include <gmock/gmock.h>
10 #include <gtest/gtest.h>
11 
13 #include <fizz/client/test/Mocks.h>
14 #include <fizz/crypto/Utils.h>
28 #include <fizz/server/test/Mocks.h>
30 
31 using namespace folly;
32 using namespace folly::test;
33 using namespace fizz::client;
34 using namespace fizz::extensions;
35 using namespace fizz::server;
36 
37 namespace fizz {
38 namespace test {
39 
41  ProtocolVersion version{ProtocolVersion::tls_1_3};
42  CipherSuite cipher{CipherSuite::TLS_AES_128_GCM_SHA256};
44  SignatureScheme::ecdsa_secp256r1_sha256};
45  folly::Optional<NamedGroup> group{NamedGroup::x25519};
46  PskType pskType{PskType::NotAttempted};
48  folly::Optional<KeyExchangeType> clientKexType{KeyExchangeType::OneRtt};
49  folly::Optional<KeyExchangeType> serverKexType{KeyExchangeType::OneRtt};
50  folly::Optional<EarlyDataType> earlyDataType{EarlyDataType::NotAttempted};
52  std::shared_ptr<const Cert> clientCert;
54 };
55 
56 class HandshakeTest : public Test {
57  public:
58  void SetUp() override {
60 
61  clientContext_ = std::make_shared<FizzClientContext>();
62  serverContext_ = std::make_shared<FizzServerContext>();
63 
64  auto pskCache = std::make_shared<BasicPskCache>();
65  clientContext_->setPskCache(std::move(pskCache));
66 
67  auto certManager = std::make_unique<CertManager>();
68  std::vector<std::shared_ptr<CertificateCompressor>> compressors = {
69  std::make_shared<ZlibCertificateCompressor>(9)};
70  std::vector<ssl::X509UniquePtr> rsaCerts;
71  rsaCerts.emplace_back(getCert(kRSACertificate));
72  certManager->addCert(
73  std::make_shared<SelfCertImpl<KeyType::RSA>>(
74  getPrivateKey(kRSAKey), std::move(rsaCerts), compressors),
75  true);
76  std::vector<ssl::X509UniquePtr> p256Certs;
77  std::vector<ssl::X509UniquePtr> p384Certs;
78  std::vector<ssl::X509UniquePtr> p521Certs;
79  p256Certs.emplace_back(getCert(kP256Certificate));
80  p384Certs.emplace_back(getCert(kP384Certificate));
81  p521Certs.emplace_back(getCert(kP521Certificate));
82  certManager->addCert(std::make_shared<SelfCertImpl<KeyType::P256>>(
83  getPrivateKey(kP256Key), std::move(p256Certs), compressors));
84  certManager->addCert(std::make_shared<SelfCertImpl<KeyType::P384>>(
85  getPrivateKey(kP384Key), std::move(p384Certs), compressors));
86  certManager->addCert(std::make_shared<SelfCertImpl<KeyType::P521>>(
87  getPrivateKey(kP521Key), std::move(p521Certs), compressors));
88  serverContext_->setCertManager(std::move(certManager));
89  serverContext_->setEarlyDataSettings(
90  true,
91  {std::chrono::seconds(-60), std::chrono::seconds(60)},
92  std::make_shared<AllowAllReplayReplayCache>());
93 
94  auto caCert = getCert(kClientAuthCACert);
96  auto clientKey = getPrivateKey(kClientAuthClientKey);
97  folly::ssl::X509StoreUniquePtr store(X509_STORE_new());
98  ASSERT_EQ(X509_STORE_add_cert(store.get(), caCert.get()), 1);
99  auto verifier = std::make_shared<const DefaultCertificateVerifier>(
100  VerificationContext::Server, std::move(store));
101  serverContext_->setClientCertVerifier(verifier);
102  std::vector<folly::ssl::X509UniquePtr> certVec;
103  certVec.emplace_back(std::move(clientCert));
104  auto clientSelfCert = std::make_shared<SelfCertImpl<KeyType::RSA>>(
105  std::move(clientKey), std::move(certVec));
106  clientContext_->setClientCertificate(std::move(clientSelfCert));
107 
108  auto ticketCipher = std::make_shared<AES128TicketCipher>();
109  auto ticketSeed = RandomGenerator<32>().generateRandom();
110  ticketCipher->setTicketSecrets({{range(ticketSeed)}});
111  ticketCipher->setValidity(std::chrono::seconds(60));
112  serverContext_->setTicketCipher(std::move(ticketCipher));
113 
114  cookieCipher_ = std::make_shared<AES128CookieCipher>();
115  auto cookieSeed = RandomGenerator<32>().generateRandom();
116  cookieCipher_->setCookieSecrets({{range(cookieSeed)}});
117  cookieCipher_->setContext(serverContext_.get());
118  serverContext_->setCookieCipher(cookieCipher_);
119 
120  ON_CALL(clientRead_, isBufferMovable_()).WillByDefault(Return(true));
121  ON_CALL(serverRead_, isBufferMovable_()).WillByDefault(Return(true));
122 
123  resetTransports();
124  }
125 
127  clientTransport_ = new LocalTransport();
128  auto client = LocalTransport::UniquePtr(clientTransport_);
129  serverTransport_ = new LocalTransport();
130  auto server = LocalTransport::UniquePtr(serverTransport_);
131  client->attachEventBase(&evb_);
132  server->attachEventBase(&evb_);
133  client->setPeer(server.get());
134  server->setPeer(client.get());
135 
136  client_.reset(new AsyncFizzClient(
137  std::move(client), clientContext_, clientExtensions_));
138  server_.reset(new AsyncFizzServer(
139  std::move(server), serverContext_, serverExtensions_));
140  }
141 
143  clientTransport_ = new LocalTransport();
144  auto client = LocalTransport::UniquePtr(clientTransport_);
145  serverTransport_ = new LocalTransport();
146  auto server = LocalTransport::UniquePtr(serverTransport_);
147  client->attachEventBase(&evb_);
148  server->attachEventBase(&evb_);
149  client->setPeer(server.get());
150  server->setPeer(client.get());
151 
152  client_.reset(new AsyncFizzClient(
153  std::move(client), clientContext_, clientExtensions_));
154 
155  folly::test::MockReadCallback serverRawRead;
156  ON_CALL(serverRawRead, isBufferMovable_()).WillByDefault(Return(true));
157 
158  EXPECT_CALL(serverRawRead, readBufferAvailable_(_))
159  .WillOnce(Invoke([&](std::unique_ptr<IOBuf>& readBuf) {
160  server->setReadCB(nullptr);
161  auto tokenOrRetry = cookieCipher_->getTokenOrRetry(
162  std::move(readBuf), IOBuf::copyBuffer("test"));
163  auto retry =
164  std::move(boost::get<StatelessHelloRetryRequest>(tokenOrRetry));
165  server->writeChain(nullptr, std::move(retry.data));
166  }));
167 
168  server->setReadCB(&serverRawRead);
169  doClientHandshake();
170  EXPECT_EQ(server->getReadCallback(), nullptr);
171 
172  server_.reset(new AsyncFizzServer(
173  std::move(server), serverContext_, serverExtensions_));
174  }
175 
177  resetTransportsAndStartCookieHandshake();
178  doServerHandshake();
179  }
180 
181  void doHandshake() {
182  client_->connect(
183  &clientCallback_, nullptr, folly::none, std::string("Fizz"));
184  server_->accept(&serverCallback_);
185  evb_.loop();
186  }
187 
189  client_->connect(
190  &clientCallback_, nullptr, folly::none, std::string("Fizz"));
191  evb_.loop();
192  }
193 
195  server_->accept(&serverCallback_);
196  evb_.loop();
197  }
198 
200  EXPECT_CALL(clientCallback_, _fizzHandshakeSuccess())
201  .WillOnce(Invoke([this]() {
202  client_->setReadCB(&clientRead_);
203  if (!client_->isReplaySafe()) {
204  client_->setReplaySafetyCallback(&replayCallback_);
205  }
206  }));
207  ON_CALL(clientCallback_, _fizzHandshakeError(_))
208  .WillByDefault(Invoke([](folly::exception_wrapper ex) {
209  FAIL() << "Client Error: " << ex.what().toStdString();
210  }));
211  }
212 
214  EXPECT_CALL(serverCallback_, _fizzHandshakeSuccess())
215  .WillOnce(Invoke([this]() { server_->setReadCB(&serverRead_); }));
216  ON_CALL(serverCallback_, _fizzHandshakeError(_))
217  .WillByDefault(Invoke([](folly::exception_wrapper ex) {
218  FAIL() << "Server Error: " << ex.what().toStdString();
219  }));
220  }
221 
222  void expectSuccess() {
223  expectClientSuccess();
224  expectServerSuccess();
225  }
226 
227  void expectError(const std::string& clientStr, const std::string& serverStr) {
228  EXPECT_CALL(clientCallback_, _fizzHandshakeError(_))
229  .WillOnce(Invoke([clientStr](folly::exception_wrapper ex) {
230  EXPECT_THAT(ex.what().toStdString(), HasSubstr(clientStr));
231  }));
232  EXPECT_CALL(serverCallback_, _fizzHandshakeError(_))
233  .WillOnce(Invoke([serverStr](folly::exception_wrapper ex) {
234  EXPECT_THAT(ex.what().toStdString(), HasSubstr(serverStr));
235  }));
236  }
237 
239  const std::string& clientError,
240  const std::string& serverError) {
241  EXPECT_CALL(clientCallback_, _fizzHandshakeSuccess());
242  client_->setReadCB(&readCallback_);
243  EXPECT_CALL(readCallback_, readErr_(_))
244  .WillOnce(Invoke([clientError](const AsyncSocketException& ex) {
245  EXPECT_THAT(std::string(ex.what()), HasSubstr(clientError));
246  }));
247  EXPECT_CALL(serverCallback_, _fizzHandshakeError(_))
248  .WillOnce(Invoke([serverError](folly::exception_wrapper ex) {
249  EXPECT_THAT(ex.what().toStdString(), HasSubstr(serverError));
250  }));
251  }
252 
254  client_->writeChain(nullptr, IOBuf::copyBuffer(write));
255  }
256 
258  server_->writeChain(nullptr, IOBuf::copyBuffer(write));
259  }
260 
262  EXPECT_CALL(clientRead_, readBufferAvailable_(BufMatches(read)));
263  }
264 
266  EXPECT_CALL(serverRead_, readBufferAvailable_(BufMatches(read)));
267  }
268 
270  EXPECT_CALL(clientRead_, readErr_(_))
271  .WillOnce(Invoke([](const AsyncSocketException& ex) {
273  }));
274  }
275 
277  EXPECT_CALL(replayCallback_, onReplaySafe_());
278  }
279 
280  void sendAppData() {
281  expectClientRead("serverdata");
282  expectServerRead("clientdata");
283  clientWrite("clientdata");
284  serverWrite("serverdata");
285  }
286 
287  static bool certsMatch(
288  const std::shared_ptr<const Cert>& a,
289  const std::shared_ptr<const Cert>& b) {
290  if (!a || !b) {
291  return a == b;
292  } else {
293  return a->getIdentity() == b->getIdentity();
294  }
295  }
296 
298  EXPECT_EQ(
299  client_->getState().earlyDataParams()->version, expected_.version);
300  EXPECT_EQ(client_->getState().earlyDataParams()->cipher, expected_.cipher);
301  EXPECT_EQ(client_->getState().earlyDataParams()->alpn, expected_.alpn);
302  EXPECT_TRUE(certsMatch(
303  client_->getState().earlyDataParams()->clientCert,
304  expected_.clientCert));
305  }
306 
308  EXPECT_EQ(*client_->getState().version(), expected_.version);
309  EXPECT_EQ(*client_->getState().cipher(), expected_.cipher);
310  EXPECT_EQ(client_->getState().sigScheme(), expected_.scheme);
311  EXPECT_EQ(client_->getState().group(), expected_.group);
312  EXPECT_EQ(*server_->getState().pskType(), expected_.pskType);
313  EXPECT_EQ(client_->getState().pskMode(), expected_.pskMode);
314  EXPECT_EQ(client_->getState().keyExchangeType(), expected_.clientKexType);
315  EXPECT_EQ(client_->getState().earlyDataType(), expected_.earlyDataType);
316  EXPECT_EQ(client_->getState().alpn(), expected_.alpn);
317  EXPECT_TRUE(
318  certsMatch(client_->getState().clientCert(), expected_.clientCert));
319 
320  EXPECT_EQ(*server_->getState().version(), expected_.version);
321  EXPECT_EQ(*server_->getState().cipher(), expected_.cipher);
322  EXPECT_EQ(server_->getState().sigScheme(), expected_.scheme);
323  EXPECT_EQ(server_->getState().group(), expected_.group);
324  EXPECT_EQ(*server_->getState().pskType(), expected_.pskType);
325  EXPECT_EQ(server_->getState().pskMode(), expected_.pskMode);
326  EXPECT_EQ(server_->getState().keyExchangeType(), expected_.serverKexType);
327  EXPECT_EQ(server_->getState().earlyDataType(), expected_.earlyDataType);
328  EXPECT_EQ(server_->getState().alpn(), expected_.alpn);
329  EXPECT_TRUE(
330  certsMatch(server_->getState().clientCert(), expected_.clientCert));
331  EXPECT_EQ(
332  client_->getState().serverCertCompAlgo(), expected_.serverCertCompAlgo);
333  EXPECT_EQ(
334  server_->getState().serverCertCompAlgo(), expected_.serverCertCompAlgo);
335  }
336 
337  void setupResume() {
338  expectSuccess();
339  doHandshake();
340  verifyParameters();
341  resetTransports();
342  expected_.scheme = none;
343  expected_.pskType = PskType::Resumption;
344  expected_.pskMode = PskKeyExchangeMode::psk_dhe_ke;
345  }
346 
348  serverContext_->setSupportedGroups({NamedGroup::secp256r1});
349  expected_.group = NamedGroup::secp256r1;
350  expectSuccess();
351  doHandshake();
352  verifyParameters();
353  // Explicitly set a different supported group to trigger another
354  // negotiation, even if group is cached
355  serverContext_->setSupportedGroups({NamedGroup::x25519});
356  expected_.group = NamedGroup::x25519;
357  resetTransports();
358  expected_.scheme = none;
359  expected_.pskType = PskType::Resumption;
360  expected_.pskMode = PskKeyExchangeMode::psk_dhe_ke;
361  }
362 
363  protected:
365  std::shared_ptr<FizzClientContext> clientContext_;
366  std::shared_ptr<FizzServerContext> serverContext_;
369 
370  std::shared_ptr<AES128CookieCipher> cookieCipher_;
371 
374 
376 
377  std::shared_ptr<fizz::ClientExtensions> clientExtensions_;
378  std::shared_ptr<fizz::ServerExtensions> serverExtensions_;
379 
382 
385 
387 
389 };
390 
392  public ::testing::WithParamInterface<SignatureScheme> {};
393 
394 TEST_F(HandshakeTest, BasicHandshake) {
395  expectSuccess();
396  doHandshake();
397  verifyParameters();
398  sendAppData();
399 }
400 
401 TEST_F(HandshakeTest, BasicHandshakeTrickle) {
402  clientTransport_->setTrickle(true);
403  serverTransport_->setTrickle(true);
404  expectSuccess();
405  doHandshake();
406  verifyParameters();
407  sendAppData();
408 }
409 
411  clientContext_->setSupportedGroups(
412  {NamedGroup::x25519, NamedGroup::secp256r1});
413  clientContext_->setDefaultShares({NamedGroup::x25519, NamedGroup::secp256r1});
414  serverContext_->setSupportedGroups({NamedGroup::secp256r1});
415  expected_.group = NamedGroup::secp256r1;
416 
417  expectSuccess();
418  doHandshake();
419  verifyParameters();
420  sendAppData();
421 }
422 
424  clientContext_->setSupportedGroups(
425  {NamedGroup::x25519, NamedGroup::secp384r1});
426  clientContext_->setDefaultShares({NamedGroup::x25519, NamedGroup::secp384r1});
427  serverContext_->setSupportedGroups({NamedGroup::secp384r1});
428  expected_.group = NamedGroup::secp384r1;
429 
430  expectSuccess();
431  doHandshake();
432  verifyParameters();
433  sendAppData();
434 }
435 
437  clientContext_->setSupportedGroups(
438  {NamedGroup::x25519, NamedGroup::secp521r1});
439  clientContext_->setDefaultShares({NamedGroup::x25519, NamedGroup::secp521r1});
440  serverContext_->setSupportedGroups({NamedGroup::secp521r1});
441  expected_.group = NamedGroup::secp521r1;
442 
443  expectSuccess();
444  doHandshake();
445  verifyParameters();
446  sendAppData();
447 }
448 
449 TEST_F(HandshakeTest, GroupServerPref) {
450  clientContext_->setSupportedGroups(
451  {NamedGroup::secp256r1, NamedGroup::x25519});
452  clientContext_->setDefaultShares({NamedGroup::secp256r1, NamedGroup::x25519});
453  serverContext_->setSupportedGroups(
454  {NamedGroup::x25519, NamedGroup::secp256r1});
455  expected_.group = NamedGroup::x25519;
456 
457  expectSuccess();
458  doHandshake();
459  verifyParameters();
460  sendAppData();
461 }
462 
463 TEST_F(HandshakeTest, GroupMismatch) {
464  clientContext_->setSupportedGroups({NamedGroup::secp256r1});
465  clientContext_->setDefaultShares({NamedGroup::secp256r1});
466  serverContext_->setSupportedGroups({NamedGroup::x25519});
467 
468  expectError("alert: handshake_failure", "no group match");
469  doHandshake();
470 }
471 
472 TEST_F(HandshakeTest, SchemeServerPref) {
473  clientContext_->setSupportedSigSchemes(
474  {SignatureScheme::ecdsa_secp256r1_sha256,
475  SignatureScheme::rsa_pss_sha256});
476  serverContext_->setSupportedSigSchemes(
477  {SignatureScheme::rsa_pss_sha256,
478  SignatureScheme::ecdsa_secp256r1_sha256});
479  expected_.scheme = SignatureScheme::rsa_pss_sha256;
480 
481  expectSuccess();
482  doHandshake();
483  verifyParameters();
484  sendAppData();
485 }
486 
487 TEST_F(HandshakeTest, SchemeMismatch) {
488  clientContext_->setSupportedSigSchemes(
489  {SignatureScheme::ecdsa_secp256r1_sha256});
490  serverContext_->setSupportedSigSchemes({SignatureScheme::rsa_pss_sha256});
491 
492  // The server will try using its RSA cert anyway, so it will be the client
493  // that actually rejects that.
494  expectError("unsupported sig scheme", "alert: illegal_parameter");
495  doHandshake();
496 }
497 
499  clientContext_->setDefaultShares({});
500  expected_.clientKexType = expected_.serverKexType =
501  KeyExchangeType::HelloRetryRequest;
502 
503  expectSuccess();
504  doHandshake();
505  verifyParameters();
506  sendAppData();
507 }
508 
509 TEST_F(HandshakeTest, PskDheKe) {
510  setupResume();
511 
512  expectSuccess();
513  doHandshake();
514  verifyParameters();
515  sendAppData();
516 }
517 
518 TEST_F(HandshakeTest, HrrPskDheKe) {
519  clientContext_->setDefaultShares({});
520  expected_.clientKexType = expected_.serverKexType =
521  KeyExchangeType::HelloRetryRequest;
522  setupResumeWithHRR();
523  expectSuccess();
524  doHandshake();
525  verifyParameters();
526  sendAppData();
527 }
528 
529 TEST_F(HandshakeTest, HrrPskDheKeWithCache) {
530  clientContext_->setDefaultShares({});
531  expected_.clientKexType = expected_.serverKexType =
532  KeyExchangeType::HelloRetryRequest;
533  setupResume();
534 
535  // OneRtt as the first round should have cached the group
536  expected_.clientKexType = expected_.serverKexType = KeyExchangeType::OneRtt;
537  expectSuccess();
538  doHandshake();
539  verifyParameters();
540  sendAppData();
541 }
542 
543 TEST_F(HandshakeTest, HrrIncompatiblePsk) {
544  expectSuccess();
545  doHandshake();
546  verifyParameters();
547  resetTransports();
548 
549  serverContext_->setSupportedGroups({NamedGroup::secp256r1});
550  serverContext_->setSupportedCiphers({{CipherSuite::TLS_AES_256_GCM_SHA384}});
551  expected_.group = NamedGroup::secp256r1;
552  expected_.cipher = CipherSuite::TLS_AES_256_GCM_SHA384;
553  expected_.clientKexType = expected_.serverKexType =
554  KeyExchangeType::HelloRetryRequest;
555 
556  expectSuccess();
557  doHandshake();
558  verifyParameters();
559  sendAppData();
560 }
561 
563  serverContext_->setSupportedPskModes({PskKeyExchangeMode::psk_ke});
564  setupResume();
565 
566  expected_.group = none;
567  expected_.pskMode = PskKeyExchangeMode::psk_ke;
568  expected_.clientKexType = expected_.serverKexType = KeyExchangeType::None;
569 
570  expectSuccess();
571  doHandshake();
572  verifyParameters();
573  sendAppData();
574 }
575 
576 // This test is only run with 1.1.0 as it requires chacha to run (chacha and
577 // aes-gcm-128 are the only ciphers with a compatible hash algorithm).
578 #if FOLLY_OPENSSL_IS_110
579 TEST_F(HandshakeTest, ResumeChangeCipher) {
580  setupResume();
581  clientContext_->setSupportedCiphers(
582  {CipherSuite::TLS_AES_128_GCM_SHA256,
583  CipherSuite::TLS_CHACHA20_POLY1305_SHA256});
584  serverContext_->setSupportedCiphers(
585  {{CipherSuite::TLS_CHACHA20_POLY1305_SHA256},
586  {CipherSuite::TLS_AES_128_GCM_SHA256}});
587 
588  expected_.cipher = CipherSuite::TLS_CHACHA20_POLY1305_SHA256;
589 
590  expectSuccess();
591  doHandshake();
592  verifyParameters();
593  sendAppData();
594 }
595 #endif // FOLLY_OPENSSL_IS_110
596 
597 TEST_F(HandshakeTest, TestEkmSame) {
598  expectSuccess();
599  doHandshake();
600  auto clientEkm = client_->getEkm("EXPORTER-Some-Label", nullptr, 32);
601  auto serverEkm = server_->getEkm("EXPORTER-Some-Label", nullptr, 32);
602  EXPECT_TRUE(IOBufEqualTo()(clientEkm, serverEkm));
603  EXPECT_THROW(
604  client_->getEarlyEkm("EXPORTER-Some-Label", nullptr, 32), std::exception);
605  EXPECT_THROW(
606  server_->getEarlyEkm("EXPORTER-Some-Label", nullptr, 32), std::exception);
607 }
608 
609 TEST_F(HandshakeTest, TestEarlyEkmSame) {
610  clientContext_->setSendEarlyData(true);
611  setupResume();
612 
613  expectSuccess();
614  doHandshake();
615  auto clientEkm = client_->getEarlyEkm("EXPORTER-Some-Label", nullptr, 32);
616  auto serverEkm = server_->getEarlyEkm("EXPORTER-Some-Label", nullptr, 32);
617  EXPECT_TRUE(IOBufEqualTo()(clientEkm, serverEkm));
618 }
619 
620 TEST_F(HandshakeTest, TestExtensions) {
621  auto context = std::make_shared<TokenBindingContext>();
622  auto clientTokBind = std::make_shared<TokenBindingClientExtension>(context);
623  auto serverTokBind = std::make_shared<TokenBindingServerExtension>(context);
624  clientExtensions_ = clientTokBind;
625  serverExtensions_ = serverTokBind;
626  resetTransports();
627  doHandshake();
628  EXPECT_TRUE(clientTokBind->getNegotiatedKeyParam().hasValue());
629  EXPECT_TRUE(clientTokBind->getVersion().hasValue());
630  EXPECT_TRUE(serverTokBind->getNegotiatedKeyParam().hasValue());
631  EXPECT_EQ(
632  *clientTokBind->getNegotiatedKeyParam(),
633  TokenBindingKeyParameters::ecdsap256);
634  EXPECT_EQ(
635  *clientTokBind->getVersion(),
636  TokenBindingProtocolVersion::token_binding_0_14);
637  EXPECT_EQ(
638  *serverTokBind->getNegotiatedKeyParam(),
639  TokenBindingKeyParameters::ecdsap256);
640 }
641 
642 TEST_F(HandshakeTest, BasicCertRequest) {
643  expectSuccess();
644  serverContext_->setClientAuthMode(ClientAuthMode::Required);
645  expected_.clientCert = std::make_shared<PeerCertImpl<KeyType::RSA>>(
647  doHandshake();
648  verifyParameters();
649  sendAppData();
650 }
651 
653  SignatureScheme scheme = GetParam();
654  clientContext_->setSupportedSigSchemes({scheme});
655  serverContext_->setSupportedSigSchemes({scheme});
656  expected_.scheme = scheme;
657 
658  expectSuccess();
659  doHandshake();
660  verifyParameters();
661  sendAppData();
662 }
663 
664 TEST_F(HandshakeTest, CertRequestPskPreservesIdentity) {
665  serverContext_->setClientAuthMode(ClientAuthMode::Required);
666  expected_.clientCert = std::make_shared<PeerCertImpl<KeyType::RSA>>(
668  setupResume();
669 
670  expectSuccess();
671  doHandshake();
672  verifyParameters();
673  sendAppData();
674 }
675 
676 TEST_F(HandshakeTest, CertRequestNoCert) {
677  serverContext_->setClientAuthMode(ClientAuthMode::Required);
678  clientContext_->setClientCertificate(nullptr);
679  expectServerError(
680  "alert: certificate_required", "certificate requested but none received");
681  doHandshake();
682 }
683 
684 TEST_F(HandshakeTest, CertRequestPermitNoCert) {
685  serverContext_->setClientAuthMode(ClientAuthMode::Optional);
686  clientContext_->setClientCertificate(nullptr);
687  expectSuccess();
688  doHandshake();
689  verifyParameters();
690  sendAppData();
691 }
692 
693 TEST_F(HandshakeTest, CertRequestBadCert) {
694  serverContext_->setClientAuthMode(ClientAuthMode::Required);
695  auto badCert = createCert("foo", false, nullptr);
696  std::vector<folly::ssl::X509UniquePtr> certVec;
697  certVec.emplace_back(std::move(badCert.cert));
698  clientContext_->setClientCertificate(
699  std::make_shared<SelfCertImpl<KeyType::P256>>(
700  std::move(badCert.key), std::move(certVec)));
701  expectServerError("alert: bad_certificate", "client certificate failure");
702  doHandshake();
703 }
704 
705 TEST_F(HandshakeTest, BasicCertCompression) {
706  expectSuccess();
707  auto decompressor = std::make_shared<ZlibCertificateDecompressor>();
708  auto decompressionMgr = std::make_shared<CertDecompressionManager>();
709  decompressionMgr->setDecompressors(
710  {std::static_pointer_cast<CertificateDecompressor>(decompressor)});
711  clientContext_->setCertDecompressionManager(decompressionMgr);
712  serverContext_->setSupportedCompressionAlgorithms(
713  {CertificateCompressionAlgorithm::zlib});
714  expected_.serverCertCompAlgo = CertificateCompressionAlgorithm::zlib;
715  doHandshake();
716  verifyParameters();
717  sendAppData();
718 }
719 
720 TEST_F(HandshakeTest, EarlyDataAccepted) {
721  clientContext_->setSendEarlyData(true);
722  setupResume();
723 
724  expected_.pskType = PskType::Resumption;
725  expected_.earlyDataType = EarlyDataType::Accepted;
726 
727  expectClientSuccess();
728  doClientHandshake();
729  verifyEarlyParameters();
730  clientWrite("early");
731 
732  expectReplaySafety();
733  expectServerSuccess();
734  expectServerRead("early");
735  doServerHandshake();
736  verifyParameters();
737  sendAppData();
738 }
739 
740 TEST_F(HandshakeTest, EarlyDataRejected) {
741  clientContext_->setSendEarlyData(true);
742  setupResume();
743 
744  serverContext_->setEarlyDataSettings(false, {}, nullptr);
745  expected_.pskType = PskType::Resumption;
746  expected_.earlyDataType = EarlyDataType::Rejected;
747 
748  expectClientSuccess();
749  doClientHandshake();
750  verifyEarlyParameters();
751  clientWrite("early");
752 
753  expectEarlyDataRejectError();
754  expectServerSuccess();
755  doServerHandshake();
756  verifyParameters();
757 }
758 
759 TEST_F(HandshakeTest, EarlyDataRejectedHrr) {
760  clientContext_->setSendEarlyData(true);
761  setupResume();
762 
763  serverContext_->setSupportedGroups({NamedGroup::secp256r1});
764  expected_.pskType = PskType::Resumption;
765  expected_.earlyDataType = EarlyDataType::Rejected;
766  expected_.clientKexType = expected_.serverKexType =
767  KeyExchangeType::HelloRetryRequest;
768  expected_.group = NamedGroup::secp256r1;
769 
770  expectClientSuccess();
771  doClientHandshake();
772  verifyEarlyParameters();
773  clientWrite("early");
774 
775  expectEarlyDataRejectError();
776  expectServerSuccess();
777  doServerHandshake();
778  verifyParameters();
779 }
780 
781 TEST_F(HandshakeTest, EarlyDataRejectedResend) {
782  clientContext_->setSendEarlyData(true);
783  setupResume();
784 
785  serverContext_->setEarlyDataSettings(false, {}, nullptr);
786  client_->setEarlyDataRejectionPolicy(
787  EarlyDataRejectionPolicy::AutomaticResend);
788  expected_.pskType = PskType::Resumption;
789  expected_.earlyDataType = EarlyDataType::Rejected;
790 
791  expectClientSuccess();
792  doClientHandshake();
793  verifyEarlyParameters();
794  clientWrite("early");
795 
796  expectReplaySafety();
797  expectServerRead("early");
798  expectServerSuccess();
799  doServerHandshake();
800  verifyParameters();
801  sendAppData();
802 }
803 
804 TEST_F(HandshakeTest, EarlyDataRejectedDontResend) {
805  clientContext_->setSendEarlyData(true);
806  clientContext_->setSupportedAlpns({"h2"});
807  serverContext_->setSupportedAlpns({"h2"});
808  expected_.alpn = "h2";
809  setupResume();
810 
811  serverContext_->setSupportedAlpns({});
812  client_->setEarlyDataRejectionPolicy(
813  EarlyDataRejectionPolicy::AutomaticResend);
814 
815  expectClientSuccess();
816  doClientHandshake();
817  verifyEarlyParameters();
818  clientWrite("early");
819 
820  expected_.earlyDataType = EarlyDataType::Rejected;
821  expected_.alpn = none;
822 
823  expectEarlyDataRejectError();
824  expectServerSuccess();
825  doServerHandshake();
826  verifyParameters();
827 
828  expected_.pskType = PskType::NotAttempted;
829  expected_.pskMode = none;
830  expected_.scheme = SignatureScheme::ecdsa_secp256r1_sha256;
831  expected_.earlyDataType = EarlyDataType::NotAttempted;
832 
833  resetTransports();
834  expectSuccess();
835  doHandshake();
836  verifyParameters();
837  sendAppData();
838 }
839 
840 TEST_F(HandshakeTest, EarlyDataTrickleSendAccepted) {
841  clientContext_->setSendEarlyData(true);
842  setupResume();
843 
844  clientTransport_->setTrickle(true, [this]() { clientWrite("e"); });
845  expected_.pskType = PskType::Resumption;
846  expected_.earlyDataType = EarlyDataType::Accepted;
847 
848  expectClientSuccess();
849  doClientHandshake();
850  verifyEarlyParameters();
851 
852  expectReplaySafety();
853  expectServerSuccess();
854  doServerHandshake();
855  verifyParameters();
856 }
857 
858 TEST_F(HandshakeTest, EarlyDataTrickleSendRejected) {
859  clientContext_->setSendEarlyData(true);
860  setupResume();
861 
862  clientTransport_->setTrickle(true, [this]() { clientWrite("e"); });
863  serverContext_->setClientAuthMode(ClientAuthMode::Required);
864  serverContext_->setTicketCipher(nullptr);
865 
866  expectClientSuccess();
867  doClientHandshake();
868  verifyEarlyParameters();
869 
870  expected_.pskType = PskType::Rejected;
871  expected_.pskMode = none;
872  expected_.earlyDataType = EarlyDataType::Rejected;
873  expected_.scheme = SignatureScheme::ecdsa_secp256r1_sha256;
874  expected_.clientCert = std::make_shared<PeerCertImpl<KeyType::RSA>>(
876 
877  expectEarlyDataRejectError();
878  expectServerSuccess();
879  doServerHandshake();
880  verifyParameters();
881 }
882 
884  clientContext_->setCompatibilityMode(true);
885  expectSuccess();
886  doHandshake();
887  verifyParameters();
888  sendAppData();
889 }
890 
891 TEST_F(HandshakeTest, TestCompatHRR) {
892  clientContext_->setCompatibilityMode(true);
893  clientContext_->setDefaultShares({});
894  expected_.clientKexType = expected_.serverKexType =
895  KeyExchangeType::HelloRetryRequest;
896 
897  expectSuccess();
898  doHandshake();
899  verifyParameters();
900  sendAppData();
901 }
902 
903 TEST_F(HandshakeTest, TestCompatEarly) {
904  clientContext_->setCompatibilityMode(true);
905  clientContext_->setSendEarlyData(true);
906  setupResume();
907 
908  expected_.pskType = PskType::Resumption;
909  expected_.earlyDataType = EarlyDataType::Accepted;
910 
911  expectClientSuccess();
912  doClientHandshake();
913  verifyEarlyParameters();
914 
915  expectReplaySafety();
916  expectServerSuccess();
917  doServerHandshake();
918  verifyParameters();
919  sendAppData();
920 }
921 
922 TEST_F(HandshakeTest, TestCompatEarlyRejected) {
923  clientContext_->setCompatibilityMode(true);
924  clientContext_->setSendEarlyData(true);
925  setupResume();
926 
927  serverContext_->setEarlyDataSettings(false, {}, nullptr);
928  expected_.pskType = PskType::Resumption;
929  expected_.earlyDataType = EarlyDataType::Rejected;
930 
931  expectClientSuccess();
932  doClientHandshake();
933  verifyEarlyParameters();
934  clientWrite("early");
935 
936  expectEarlyDataRejectError();
937  expectServerSuccess();
938  doServerHandshake();
939  verifyParameters();
940 }
941 
942 TEST_F(HandshakeTest, TestCompatEarlyRejectedHRR) {
943  clientContext_->setCompatibilityMode(true);
944  clientContext_->setSendEarlyData(true);
945  setupResume();
946 
947  serverContext_->setSupportedGroups({NamedGroup::secp256r1});
948  expected_.pskType = PskType::Resumption;
949  expected_.earlyDataType = EarlyDataType::Rejected;
950  expected_.clientKexType = expected_.serverKexType =
951  KeyExchangeType::HelloRetryRequest;
952  expected_.group = NamedGroup::secp256r1;
953 
954  expectClientSuccess();
955  doClientHandshake();
956  verifyEarlyParameters();
957  clientWrite("early");
958 
959  expectEarlyDataRejectError();
960  expectServerSuccess();
961  doServerHandshake();
962  verifyParameters();
963 }
964 
965 TEST_F(HandshakeTest, TestCookie) {
966  expected_.clientKexType = KeyExchangeType::HelloRetryRequest;
967 
968  expectSuccess();
969  resetTransportsAndDoCookieHandshake();
970  verifyParameters();
971  sendAppData();
972 }
973 
974 TEST_F(HandshakeTest, TestCookieGroupNegotiate) {
975  clientContext_->setDefaultShares({});
976  expected_.clientKexType = KeyExchangeType::HelloRetryRequest;
977 
978  expectSuccess();
979  resetTransportsAndDoCookieHandshake();
980  verifyParameters();
981  sendAppData();
982 }
983 
984 TEST_F(HandshakeTest, TestCookieResume) {
985  setupResume();
986 
987  expected_.clientKexType = KeyExchangeType::HelloRetryRequest;
988 
989  expectSuccess();
990  resetTransportsAndDoCookieHandshake();
991  verifyParameters();
992  sendAppData();
993 }
994 
995 TEST_F(HandshakeTest, TestCookieIncompatiblePsk) {
996  expectSuccess();
997  doHandshake();
998  verifyParameters();
999 
1000  serverContext_->setSupportedCiphers({{CipherSuite::TLS_AES_256_GCM_SHA384}});
1001  expected_.cipher = CipherSuite::TLS_AES_256_GCM_SHA384;
1002  expected_.clientKexType = KeyExchangeType::HelloRetryRequest;
1003 
1004  expectSuccess();
1005  resetTransportsAndDoCookieHandshake();
1006  verifyParameters();
1007  sendAppData();
1008 }
1009 
1010 TEST_F(HandshakeTest, TestCookiePskKe) {
1011  serverContext_->setSupportedPskModes({PskKeyExchangeMode::psk_ke});
1012  setupResume();
1013 
1014  expected_.group = none;
1015  expected_.pskMode = PskKeyExchangeMode::psk_ke;
1016  expected_.clientKexType = KeyExchangeType::None;
1017  expected_.serverKexType = KeyExchangeType::None;
1018 
1019  expectSuccess();
1020  resetTransportsAndDoCookieHandshake();
1021  verifyParameters();
1022  sendAppData();
1023 }
1024 
1025 TEST_F(HandshakeTest, TestBadCookie) {
1026  expectError("decrypt_error", "could not decrypt cookie");
1027  resetTransportsAndStartCookieHandshake();
1028 
1029  auto cookieSeed = RandomGenerator<32>().generateRandom();
1030  cookieCipher_->setCookieSecrets({{range(cookieSeed)}});
1031 
1032  doServerHandshake();
1033 }
1035  SignatureSchemes,
1036  SigSchemeTest,
1037  ::testing::Values(
1038  SignatureScheme::rsa_pss_sha256,
1039  SignatureScheme::ecdsa_secp256r1_sha256,
1040  SignatureScheme::ecdsa_secp384r1_sha384,
1041  SignatureScheme::ecdsa_secp521r1_sha512));
1042 } // namespace test
1043 } // namespace fizz
folly::fbstring what() const
std::shared_ptr< AES128CookieCipher > cookieCipher_
AsyncFizzServer::UniquePtr server_
fizz::client::test::MockHandshakeCallback clientCallback_
size_t readBuf(Buf &buf, folly::io::Cursor &cursor)
Definition: Types-inl.h:220
static constexpr StringPiece retry
#define FAIL()
Definition: gtest.h:1822
void write(const T &in, folly::io::Appender &appender)
Definition: Types-inl.h:112
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
constexpr folly::StringPiece kP256Key
Definition: TestUtil.h:18
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
folly::Optional< PskKeyExchangeMode > pskMode
char b
void expectError(const std::string &clientStr, const std::string &serverStr)
folly::Optional< CertificateCompressionAlgorithm > serverCertCompAlgo
LocalTransport * clientTransport_
constexpr folly::StringPiece kRSACertificate
Definition: TestUtil.h:159
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
context
Definition: CMakeCache.txt:563
constexpr folly::StringPiece kP384Certificate
Definition: TestUtil.h:74
void clientWrite(StringPiece write)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
MockReadCallback clientRead_
SignatureScheme
Definition: Types.h:257
CipherSuite
Definition: Types.h:153
TEST_P(SigSchemeTest, Schemes)
AsyncFizzClient::UniquePtr client_
LocalTransport * serverTransport_
EvpPkeyUniquePtr getPrivateKey(StringPiece key)
Definition: TestUtil.cpp:21
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
folly::Optional< std::string > alpn
void init()
std::unique_ptr< AsyncFizzClientT, folly::DelayedDestruction::Destructor > UniquePtr
folly::ssl::X509UniquePtr getCert(folly::StringPiece cert)
Definition: TestUtil.cpp:48
folly::test::MockReadCallback readCallback_
CipherSuite cipher
ProtocolVersion
Definition: Types.h:24
std::shared_ptr< FizzClientContext > clientContext_
static bool certsMatch(const std::shared_ptr< const Cert > &a, const std::shared_ptr< const Cert > &b)
ProtocolVersion version
AsyncFizzClientT< ClientStateMachine > AsyncFizzClient
ExpectedParameters expected_
void serverWrite(StringPiece write)
constexpr folly::StringPiece kClientAuthClientCert
Definition: TestUtil.h:216
constexpr folly::StringPiece kClientAuthClientKey
Definition: TestUtil.h:247
EventBase * evb_
PolymorphicMatcher< internal::HasSubstrMatcher< internal::string > > HasSubstr(const internal::string &substring)
PolymorphicAction< internal::InvokeAction< FunctionImpl > > Invoke(FunctionImpl function_impl)
size_t read(T &out, folly::io::Cursor &cursor)
Definition: Types-inl.h:258
constexpr Iter data() const
Definition: Range.h:446
std::basic_string< E, T, A > toStdString() const
Definition: FBString.h:1227
fizz::server::test::MockHandshakeCallback serverCallback_
std::unique_ptr< X509_STORE, X509StoreDeleter > X509StoreUniquePtr
constexpr Range< Iter > range(Iter first, Iter last)
Definition: Range.h:1114
Definition: Actions.h:16
INSTANTIATE_TEST_CASE_P(SignatureSchemes, SigSchemeTest,::testing::Values(SignatureScheme::rsa_pss_sha256, SignatureScheme::ecdsa_secp256r1_sha256, SignatureScheme::ecdsa_secp384r1_sha384, SignatureScheme::ecdsa_secp521r1_sha512))
char a
std::shared_ptr< const Cert > clientCert
std::shared_ptr< FizzServerContext > serverContext_
std::shared_ptr< fizz::ClientExtensions > clientExtensions_
MockReplaySafetyCallback replayCallback_
std::shared_ptr< FizzClientContext > clientContext_
Optional< NamedGroup > group
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
PskType
Definition: Types.h:18
std::shared_ptr< fizz::ServerExtensions > serverExtensions_
#define EXPECT_THAT(value, matcher)
#define ON_CALL(obj, call)
void expectServerError(const std::string &clientError, const std::string &serverError)
void expectClientRead(StringPiece read)
std::unique_ptr< LocalTransport, Destructor > UniquePtr
std::unique_ptr< AsyncFizzServerT, folly::DelayedDestruction::Destructor > UniquePtr
CertAndKey createCert(std::string cn, bool ca, CertAndKey *issuer)
Definition: Utilities.h:35
const char * string
Definition: Conv.cpp:212
constexpr folly::StringPiece kRSAKey
Definition: TestUtil.h:129
std::shared_ptr< const Cert > clientCert
#define EXPECT_CALL(obj, call)
const internal::AnythingMatcher _
TEST_F(FileUtilTest, read)
AsyncFizzServerT< ServerStateMachine > AsyncFizzServer
constexpr folly::StringPiece kP521Key
Definition: TestUtil.h:91
AsyncSocketExceptionType getType() const noexcept
static std::unique_ptr< IOBuf > copyBuffer(const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
Definition: IOBuf.h:1587
constexpr folly::StringPiece kP521Certificate
Definition: TestUtil.h:110
void expectServerRead(StringPiece read)
constexpr folly::StringPiece kP384Key
Definition: TestUtil.h:57
MockReadCallback serverRead_
constexpr folly::StringPiece kClientAuthCACert
Definition: TestUtil.h:183
constexpr None none
Definition: Optional.h:87
internal::ReturnAction< R > Return(R value)
constexpr folly::StringPiece kP256Certificate
Definition: TestUtil.h:41