1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5  * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include <functional>
8 #include <memory>
9 #include <set>
10 #include "secerr.h"
11 #include "ssl.h"
12 #include "sslerr.h"
13 #include "sslproto.h"
14 
15 #include "gtest_utils.h"
16 #include "scoped_ptrs.h"
17 #include "tls_connect.h"
18 #include "tls_filter.h"
19 #include "tls_parser.h"
20 
21 namespace nss_test {
22 
TEST_P(TlsConnectGeneric,ConnectDhe)23 TEST_P(TlsConnectGeneric, ConnectDhe) {
24   EnableOnlyDheCiphers();
25   Connect();
26   CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign,
27             ssl_sig_rsa_pss_sha256);
28 }
29 
TEST_P(TlsConnectTls13,SharesForBothEcdheAndDhe)30 TEST_P(TlsConnectTls13, SharesForBothEcdheAndDhe) {
31   EnsureTlsSetup();
32   client_->ConfigNamedGroups(kAllDHEGroups);
33 
34   auto groups_capture = new TlsExtensionCapture(ssl_supported_groups_xtn);
35   auto shares_capture = new TlsExtensionCapture(ssl_tls13_key_share_xtn);
36   std::vector<PacketFilter*> captures;
37   captures.push_back(groups_capture);
38   captures.push_back(shares_capture);
39   client_->SetPacketFilter(new ChainedPacketFilter(captures));
40 
41   Connect();
42 
43   CheckKeys();
44 
45   bool ec, dh;
46   auto track_group_type = [&ec, &dh](SSLNamedGroup group) {
47     if ((group & 0xff00U) == 0x100U) {
48       dh = true;
49     } else {
50       ec = true;
51     }
52   };
53   CheckGroups(groups_capture->extension(), track_group_type);
54   CheckShares(shares_capture->extension(), track_group_type);
55   EXPECT_TRUE(ec) << "Should include an EC group and share";
56   EXPECT_TRUE(dh) << "Should include an FFDHE group and share";
57 }
58 
TEST_P(TlsConnectGeneric,ConnectFfdheClient)59 TEST_P(TlsConnectGeneric, ConnectFfdheClient) {
60   EnableOnlyDheCiphers();
61   EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(),
62                                       SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE));
63   auto groups_capture = new TlsExtensionCapture(ssl_supported_groups_xtn);
64   auto shares_capture = new TlsExtensionCapture(ssl_tls13_key_share_xtn);
65   std::vector<PacketFilter*> captures;
66   captures.push_back(groups_capture);
67   captures.push_back(shares_capture);
68   client_->SetPacketFilter(new ChainedPacketFilter(captures));
69 
70   Connect();
71 
72   CheckKeys(ssl_kea_dh, ssl_auth_rsa_sign);
73   auto is_ffdhe = [](SSLNamedGroup group) {
74     // The group has to be in this range.
75     EXPECT_LE(ssl_grp_ffdhe_2048, group);
76     EXPECT_GE(ssl_grp_ffdhe_8192, group);
77   };
78   CheckGroups(groups_capture->extension(), is_ffdhe);
79   if (version_ == SSL_LIBRARY_VERSION_TLS_1_3) {
80     CheckShares(shares_capture->extension(), is_ffdhe);
81   } else {
82     EXPECT_EQ(0U, shares_capture->extension().len());
83   }
84 }
85 
86 // Requiring the FFDHE extension on the server alone means that clients won't be
87 // able to connect using a DHE suite.  They should still connect in TLS 1.3,
88 // because the client automatically sends the supported groups extension.
TEST_P(TlsConnectGenericPre13,ConnectFfdheServer)89 TEST_P(TlsConnectGenericPre13, ConnectFfdheServer) {
90   EnableOnlyDheCiphers();
91   EXPECT_EQ(SECSuccess, SSL_OptionSet(server_->ssl_fd(),
92                                       SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE));
93 
94   if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
95     Connect();
96     CheckKeys(ssl_kea_dh, ssl_auth_rsa_sign);
97   } else {
98     ConnectExpectFail();
99     client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
100     server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
101   }
102 }
103 
104 class TlsDheServerKeyExchangeDamager : public TlsHandshakeFilter {
105  public:
TlsDheServerKeyExchangeDamager()106   TlsDheServerKeyExchangeDamager() {}
FilterHandshake(const TlsHandshakeFilter::HandshakeHeader & header,const DataBuffer & input,DataBuffer * output)107   virtual PacketFilter::Action FilterHandshake(
108       const TlsHandshakeFilter::HandshakeHeader& header,
109       const DataBuffer& input, DataBuffer* output) {
110     if (header.handshake_type() != kTlsHandshakeServerKeyExchange) {
111       return KEEP;
112     }
113 
114     // Damage the first octet of dh_p.  Anything other than the known prime will
115     // be rejected as "weak" when we have SSL_REQUIRE_DH_NAMED_GROUPS enabled.
116     *output = input;
117     output->data()[3] ^= 73;
118     return CHANGE;
119   }
120 };
121 
122 // Changing the prime in the server's key share results in an error.  This will
123 // invalidate the signature over the ServerKeyShare. That's ok, NSS won't check
124 // the signature until everything else has been checked.
TEST_P(TlsConnectGenericPre13,DamageServerKeyShare)125 TEST_P(TlsConnectGenericPre13, DamageServerKeyShare) {
126   EnableOnlyDheCiphers();
127   EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(),
128                                       SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE));
129   server_->SetPacketFilter(new TlsDheServerKeyExchangeDamager());
130 
131   ConnectExpectFail();
132 
133   client_->CheckErrorCode(SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY);
134   server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
135 }
136 
137 class TlsDheSkeChangeY : public TlsHandshakeFilter {
138  public:
139   enum ChangeYTo {
140     kYZero,
141     kYOne,
142     kYPMinusOne,
143     kYGreaterThanP,
144     kYTooLarge,
145     kYZeroPad
146   };
147 
TlsDheSkeChangeY(ChangeYTo change)148   TlsDheSkeChangeY(ChangeYTo change) : change_Y_(change) {}
149 
150  protected:
ChangeY(const DataBuffer & input,DataBuffer * output,size_t offset,const DataBuffer & prime)151   void ChangeY(const DataBuffer& input, DataBuffer* output, size_t offset,
152                const DataBuffer& prime) {
153     static const uint8_t kExtraZero = 0;
154     static const uint8_t kTooLargeExtra = 1;
155 
156     uint32_t dh_Ys_len;
157     EXPECT_TRUE(input.Read(offset, 2, &dh_Ys_len));
158     EXPECT_LT(offset + dh_Ys_len, input.len());
159     offset += 2;
160 
161     // This isn't generally true, but our code pads.
162     EXPECT_EQ(prime.len(), dh_Ys_len)
163         << "Length of dh_Ys must equal length of dh_p";
164 
165     *output = input;
166     switch (change_Y_) {
167       case kYZero:
168         memset(output->data() + offset, 0, prime.len());
169         break;
170 
171       case kYOne:
172         memset(output->data() + offset, 0, prime.len() - 1);
173         output->Write(offset + prime.len() - 1, 1U, 1);
174         break;
175 
176       case kYPMinusOne:
177         output->Write(offset, prime);
178         EXPECT_TRUE(output->data()[offset + prime.len() - 1] & 0x01)
179             << "P must at least be odd";
180         --output->data()[offset + prime.len() - 1];
181         break;
182 
183       case kYGreaterThanP:
184         // Set the first 32 octets of Y to 0xff, except the first which we set
185         // to p[0].  This will make Y > p.  That is, unless p is Mersenne, or
186         // improbably large (but still the same bit length).  We currently only
187         // use a fixed prime that isn't a problem for this code.
188         EXPECT_LT(0, prime.data()[0]) << "dh_p should not be zero-padded";
189         offset = output->Write(offset, prime.data()[0], 1);
190         memset(output->data() + offset, 0xff, 31);
191         break;
192 
193       case kYTooLarge:
194         // Increase the dh_Ys length.
195         output->Write(offset - 2, prime.len() + sizeof(kTooLargeExtra), 2);
196         // Then insert the octet.
197         output->Splice(&kTooLargeExtra, sizeof(kTooLargeExtra), offset);
198         break;
199 
200       case kYZeroPad:
201         output->Write(offset - 2, prime.len() + sizeof(kExtraZero), 2);
202         output->Splice(&kExtraZero, sizeof(kExtraZero), offset);
203         break;
204     }
205   }
206 
207  private:
208   ChangeYTo change_Y_;
209 };
210 
211 class TlsDheSkeChangeYServer : public TlsDheSkeChangeY {
212  public:
TlsDheSkeChangeYServer(ChangeYTo change,bool modify)213   TlsDheSkeChangeYServer(ChangeYTo change, bool modify)
214       : TlsDheSkeChangeY(change), modify_(modify), p_() {}
215 
prime() const216   const DataBuffer& prime() const { return p_; }
217 
218  protected:
FilterHandshake(const TlsHandshakeFilter::HandshakeHeader & header,const DataBuffer & input,DataBuffer * output)219   virtual PacketFilter::Action FilterHandshake(
220       const TlsHandshakeFilter::HandshakeHeader& header,
221       const DataBuffer& input, DataBuffer* output) override {
222     if (header.handshake_type() != kTlsHandshakeServerKeyExchange) {
223       return KEEP;
224     }
225 
226     size_t offset = 2;
227     // Read dh_p
228     uint32_t dh_len = 0;
229     EXPECT_TRUE(input.Read(0, 2, &dh_len));
230     EXPECT_GT(input.len(), offset + dh_len);
231     p_.Assign(input.data() + offset, dh_len);
232     offset += dh_len;
233 
234     // Skip dh_g to find dh_Ys
235     EXPECT_TRUE(input.Read(offset, 2, &dh_len));
236     offset += 2 + dh_len;
237 
238     if (modify_) {
239       ChangeY(input, output, offset, p_);
240       return CHANGE;
241     }
242     return KEEP;
243   }
244 
245  private:
246   bool modify_;
247   DataBuffer p_;
248 };
249 
250 class TlsDheSkeChangeYClient : public TlsDheSkeChangeY {
251  public:
TlsDheSkeChangeYClient(ChangeYTo change,const TlsDheSkeChangeYServer * server_filter)252   TlsDheSkeChangeYClient(ChangeYTo change,
253                          const TlsDheSkeChangeYServer* server_filter)
254       : TlsDheSkeChangeY(change), server_filter_(server_filter) {}
255 
256  protected:
FilterHandshake(const TlsHandshakeFilter::HandshakeHeader & header,const DataBuffer & input,DataBuffer * output)257   virtual PacketFilter::Action FilterHandshake(
258       const TlsHandshakeFilter::HandshakeHeader& header,
259       const DataBuffer& input, DataBuffer* output) override {
260     if (header.handshake_type() != kTlsHandshakeClientKeyExchange) {
261       return KEEP;
262     }
263 
264     ChangeY(input, output, 0, server_filter_->prime());
265     return CHANGE;
266   }
267 
268  private:
269   const TlsDheSkeChangeYServer* server_filter_;
270 };
271 
272 /* This matrix includes: mode (stream/datagram), TLS version, what change to
273  * make to dh_Ys, whether the client will be configured to require DH named
274  * groups.  Test all combinations. */
275 typedef std::tuple<std::string, uint16_t, TlsDheSkeChangeY::ChangeYTo, bool>
276     DamageDHYProfile;
277 class TlsDamageDHYTest
278     : public TlsConnectTestBase,
279       public ::testing::WithParamInterface<DamageDHYProfile> {
280  public:
TlsDamageDHYTest()281   TlsDamageDHYTest()
282       : TlsConnectTestBase(std::get<0>(GetParam()), std::get<1>(GetParam())) {}
283 };
284 
TEST_P(TlsDamageDHYTest,DamageServerY)285 TEST_P(TlsDamageDHYTest, DamageServerY) {
286   EnableOnlyDheCiphers();
287   if (std::get<3>(GetParam())) {
288     EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(),
289                                         SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE));
290   }
291   TlsDheSkeChangeY::ChangeYTo change = std::get<2>(GetParam());
292   server_->SetPacketFilter(new TlsDheSkeChangeYServer(change, true));
293 
294   ConnectExpectFail();
295   if (change == TlsDheSkeChangeY::kYZeroPad) {
296     // Zero padding Y only manifests in a signature failure.
297     // In TLS 1.0 and 1.1, the client reports a device error.
298     if (version_ < SSL_LIBRARY_VERSION_TLS_1_2) {
299       client_->CheckErrorCode(SEC_ERROR_PKCS11_DEVICE_ERROR);
300     } else {
301       client_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
302     }
303     server_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
304   } else {
305     client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE);
306     server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
307   }
308 }
309 
TEST_P(TlsDamageDHYTest,DamageClientY)310 TEST_P(TlsDamageDHYTest, DamageClientY) {
311   EnableOnlyDheCiphers();
312   if (std::get<3>(GetParam())) {
313     EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(),
314                                         SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE));
315   }
316   // The filter on the server is required to capture the prime.
317   TlsDheSkeChangeYServer* server_filter =
318       new TlsDheSkeChangeYServer(TlsDheSkeChangeY::kYZero, false);
319   server_->SetPacketFilter(server_filter);
320 
321   // The client filter does the damage.
322   TlsDheSkeChangeY::ChangeYTo change = std::get<2>(GetParam());
323   client_->SetPacketFilter(new TlsDheSkeChangeYClient(change, server_filter));
324 
325   ConnectExpectFail();
326   if (change == TlsDheSkeChangeY::kYZeroPad) {
327     // Zero padding Y only manifests in a finished error.
328     client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
329     server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
330   } else {
331     client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_FAILURE_ALERT);
332     server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE);
333   }
334 }
335 
336 static const TlsDheSkeChangeY::ChangeYTo kAllYArr[] = {
337     TlsDheSkeChangeY::kYZero,      TlsDheSkeChangeY::kYOne,
338     TlsDheSkeChangeY::kYPMinusOne, TlsDheSkeChangeY::kYGreaterThanP,
339     TlsDheSkeChangeY::kYTooLarge,  TlsDheSkeChangeY::kYZeroPad};
340 static ::testing::internal::ParamGenerator<TlsDheSkeChangeY::ChangeYTo> kAllY =
341     ::testing::ValuesIn(kAllYArr);
342 static const bool kTrueFalseArr[] = {true, false};
343 static ::testing::internal::ParamGenerator<bool> kTrueFalse =
344     ::testing::ValuesIn(kTrueFalseArr);
345 
346 INSTANTIATE_TEST_CASE_P(DamageYStream, TlsDamageDHYTest,
347                         ::testing::Combine(TlsConnectTestBase::kTlsModesStream,
348                                            TlsConnectTestBase::kTlsV10ToV12,
349                                            kAllY, kTrueFalse));
350 INSTANTIATE_TEST_CASE_P(
351     DamageYDatagram, TlsDamageDHYTest,
352     ::testing::Combine(TlsConnectTestBase::kTlsModesDatagram,
353                        TlsConnectTestBase::kTlsV11V12, kAllY, kTrueFalse));
354 
355 class TlsDheSkeMakePEven : public TlsHandshakeFilter {
356  public:
FilterHandshake(const TlsHandshakeFilter::HandshakeHeader & header,const DataBuffer & input,DataBuffer * output)357   virtual PacketFilter::Action FilterHandshake(
358       const TlsHandshakeFilter::HandshakeHeader& header,
359       const DataBuffer& input, DataBuffer* output) {
360     if (header.handshake_type() != kTlsHandshakeServerKeyExchange) {
361       return KEEP;
362     }
363 
364     // Find the end of dh_p
365     uint32_t dh_len = 0;
366     EXPECT_TRUE(input.Read(0, 2, &dh_len));
367     EXPECT_GT(input.len(), 2 + dh_len) << "enough space for dh_p";
368     size_t offset = 2 + dh_len - 1;
369     EXPECT_TRUE((input.data()[offset] & 0x01) == 0x01) << "p should be odd";
370 
371     *output = input;
372     output->data()[offset] &= 0xfe;
373 
374     return CHANGE;
375   }
376 };
377 
378 // Even without requiring named groups, an even value for p is bad news.
TEST_P(TlsConnectGenericPre13,MakeDhePEven)379 TEST_P(TlsConnectGenericPre13, MakeDhePEven) {
380   EnableOnlyDheCiphers();
381   server_->SetPacketFilter(new TlsDheSkeMakePEven());
382 
383   ConnectExpectFail();
384 
385   client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE);
386   server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
387 }
388 
389 class TlsDheSkeZeroPadP : public TlsHandshakeFilter {
390  public:
FilterHandshake(const TlsHandshakeFilter::HandshakeHeader & header,const DataBuffer & input,DataBuffer * output)391   virtual PacketFilter::Action FilterHandshake(
392       const TlsHandshakeFilter::HandshakeHeader& header,
393       const DataBuffer& input, DataBuffer* output) {
394     if (header.handshake_type() != kTlsHandshakeServerKeyExchange) {
395       return KEEP;
396     }
397 
398     *output = input;
399     uint32_t dh_len = 0;
400     EXPECT_TRUE(input.Read(0, 2, &dh_len));
401     static const uint8_t kZeroPad = 0;
402     output->Write(0, dh_len + sizeof(kZeroPad), 2);  // increment the length
403     output->Splice(&kZeroPad, sizeof(kZeroPad), 2);  // insert a zero
404 
405     return CHANGE;
406   }
407 };
408 
409 // Zero padding only causes signature failure.
TEST_P(TlsConnectGenericPre13,PadDheP)410 TEST_P(TlsConnectGenericPre13, PadDheP) {
411   EnableOnlyDheCiphers();
412   server_->SetPacketFilter(new TlsDheSkeZeroPadP());
413 
414   ConnectExpectFail();
415 
416   // In TLS 1.0 and 1.1, the client reports a device error.
417   if (version_ < SSL_LIBRARY_VERSION_TLS_1_2) {
418     client_->CheckErrorCode(SEC_ERROR_PKCS11_DEVICE_ERROR);
419   } else {
420     client_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
421   }
422   server_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
423 }
424 
425 // The server should not pick the weak DH group if the client includes FFDHE
426 // named groups in the supported_groups extension. The server then picks a
427 // commonly-supported named DH group and this connects.
428 //
429 // Note: This test case can take ages to generate the weak DH key.
TEST_P(TlsConnectGenericPre13,WeakDHGroup)430 TEST_P(TlsConnectGenericPre13, WeakDHGroup) {
431   EnableOnlyDheCiphers();
432   EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(),
433                                       SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE));
434   EXPECT_EQ(SECSuccess,
435             SSL_EnableWeakDHEPrimeGroup(server_->ssl_fd(), PR_TRUE));
436 
437   Connect();
438 }
439 
TEST_P(TlsConnectGeneric,Ffdhe3072)440 TEST_P(TlsConnectGeneric, Ffdhe3072) {
441   EnableOnlyDheCiphers();
442   static const std::vector<SSLNamedGroup> groups = {ssl_grp_ffdhe_3072};
443   client_->ConfigNamedGroups(groups);
444 
445   Connect();
446 }
447 
448 // Even though the client doesn't have DHE groups enabled the server assumes it
449 // does. Because the client doesn't require named groups it accepts FF3072 as
450 // custom group.
TEST_P(TlsConnectGenericPre13,NamedGroupMismatchPre13)451 TEST_P(TlsConnectGenericPre13, NamedGroupMismatchPre13) {
452   EnableOnlyDheCiphers();
453   static const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ffdhe_3072};
454   static const std::vector<SSLNamedGroup> client_groups = {
455       ssl_grp_ec_secp256r1};
456   server_->ConfigNamedGroups(server_groups);
457   client_->ConfigNamedGroups(client_groups);
458 
459   Connect();
460   CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_custom, ssl_auth_rsa_sign,
461             ssl_sig_rsa_pss_sha256);
462 }
463 
464 // Same test but for TLS 1.3. This has to fail.
TEST_P(TlsConnectTls13,NamedGroupMismatch13)465 TEST_P(TlsConnectTls13, NamedGroupMismatch13) {
466   EnableOnlyDheCiphers();
467   static const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ffdhe_3072};
468   static const std::vector<SSLNamedGroup> client_groups = {
469       ssl_grp_ec_secp256r1};
470   server_->ConfigNamedGroups(server_groups);
471   client_->ConfigNamedGroups(client_groups);
472 
473   ConnectExpectFail();
474   server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
475   client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
476 }
477 
478 // Even though the client doesn't have DHE groups enabled the server assumes it
479 // does. The client requires named groups and thus does not accept FF3072 as
480 // custom group in contrast to the previous test.
TEST_P(TlsConnectGenericPre13,RequireNamedGroupsMismatchPre13)481 TEST_P(TlsConnectGenericPre13, RequireNamedGroupsMismatchPre13) {
482   EnableOnlyDheCiphers();
483   EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(),
484                                       SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE));
485   static const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ffdhe_3072};
486   static const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_secp256r1,
487                                                            ssl_grp_ffdhe_2048};
488   server_->ConfigNamedGroups(server_groups);
489   client_->ConfigNamedGroups(client_groups);
490 
491   ConnectExpectFail();
492   server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
493   client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
494 }
495 
TEST_P(TlsConnectGenericPre13,PreferredFfdhe)496 TEST_P(TlsConnectGenericPre13, PreferredFfdhe) {
497   EnableOnlyDheCiphers();
498   static const SSLDHEGroupType groups[] = {ssl_ff_dhe_3072_group,
499                                            ssl_ff_dhe_2048_group};
500   EXPECT_EQ(SECSuccess, SSL_DHEGroupPrefSet(server_->ssl_fd(), groups,
501                                             PR_ARRAY_SIZE(groups)));
502 
503   Connect();
504   client_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_3072, 3072);
505   server_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_3072, 3072);
506   client_->CheckAuthType(ssl_auth_rsa_sign, ssl_sig_rsa_pss_sha256);
507   server_->CheckAuthType(ssl_auth_rsa_sign, ssl_sig_rsa_pss_sha256);
508 }
509 
TEST_P(TlsConnectGenericPre13,MismatchDHE)510 TEST_P(TlsConnectGenericPre13, MismatchDHE) {
511   EnableOnlyDheCiphers();
512   EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(),
513                                       SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE));
514   static const SSLDHEGroupType serverGroups[] = {ssl_ff_dhe_3072_group};
515   EXPECT_EQ(SECSuccess, SSL_DHEGroupPrefSet(server_->ssl_fd(), serverGroups,
516                                             PR_ARRAY_SIZE(serverGroups)));
517   static const SSLDHEGroupType clientGroups[] = {ssl_ff_dhe_2048_group};
518   EXPECT_EQ(SECSuccess, SSL_DHEGroupPrefSet(client_->ssl_fd(), clientGroups,
519                                             PR_ARRAY_SIZE(clientGroups)));
520 
521   ConnectExpectFail();
522   server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
523   client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
524 }
525 
TEST_P(TlsConnectTls13,ResumeFfdhe)526 TEST_P(TlsConnectTls13, ResumeFfdhe) {
527   EnableOnlyDheCiphers();
528   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
529   Connect();
530   SendReceive();  // Need to read so that we absorb the session ticket.
531   CheckKeys(ssl_kea_dh, ssl_auth_rsa_sign);
532 
533   Reset();
534   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
535   EnableOnlyDheCiphers();
536   TlsExtensionCapture* clientCapture =
537       new TlsExtensionCapture(ssl_tls13_pre_shared_key_xtn);
538   client_->SetPacketFilter(clientCapture);
539   TlsExtensionCapture* serverCapture =
540       new TlsExtensionCapture(ssl_tls13_pre_shared_key_xtn);
541   server_->SetPacketFilter(serverCapture);
542   ExpectResumption(RESUME_TICKET);
543   Connect();
544   CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign, ssl_sig_none);
545   ASSERT_LT(0UL, clientCapture->extension().len());
546   ASSERT_LT(0UL, serverCapture->extension().len());
547 }
548 
549 class TlsDheSkeChangeSignature : public TlsHandshakeFilter {
550  public:
TlsDheSkeChangeSignature(uint16_t version,const uint8_t * data,size_t len)551   TlsDheSkeChangeSignature(uint16_t version, const uint8_t* data, size_t len)
552       : version_(version), data_(data), len_(len) {}
553 
554  protected:
FilterHandshake(const HandshakeHeader & header,const DataBuffer & input,DataBuffer * output)555   virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
556                                                const DataBuffer& input,
557                                                DataBuffer* output) {
558     if (header.handshake_type() != kTlsHandshakeServerKeyExchange) {
559       return KEEP;
560     }
561 
562     TlsParser parser(input);
563     EXPECT_TRUE(parser.SkipVariable(2));  // dh_p
564     EXPECT_TRUE(parser.SkipVariable(2));  // dh_g
565     EXPECT_TRUE(parser.SkipVariable(2));  // dh_Ys
566 
567     // Copy DH params to output.
568     size_t offset = output->Write(0, input.data(), parser.consumed());
569 
570     if (version_ == SSL_LIBRARY_VERSION_TLS_1_2) {
571       // Write signature algorithm.
572       offset = output->Write(offset, ssl_sig_dsa_sha256, 2);
573     }
574 
575     // Write new signature.
576     offset = output->Write(offset, len_, 2);
577     offset = output->Write(offset, data_, len_);
578 
579     return CHANGE;
580   }
581 
582  private:
583   uint16_t version_;
584   const uint8_t* data_;
585   size_t len_;
586 };
587 
TEST_P(TlsConnectGenericPre13,InvalidDERSignatureFfdhe)588 TEST_P(TlsConnectGenericPre13, InvalidDERSignatureFfdhe) {
589   const uint8_t kBogusDheSignature[] = {
590       0x30, 0x69, 0x3c, 0x02, 0x1c, 0x7d, 0x0b, 0x2f, 0x64, 0x00, 0x27,
591       0xae, 0xcf, 0x1e, 0x28, 0x08, 0x6a, 0x7f, 0xb1, 0xbd, 0x78, 0xb5,
592       0x3b, 0x8c, 0x8f, 0x59, 0xed, 0x8f, 0xee, 0x78, 0xeb, 0x2c, 0xe9,
593       0x02, 0x1c, 0x6d, 0x7f, 0x3c, 0x0f, 0xf4, 0x44, 0x35, 0x0b, 0xb2,
594       0x6d, 0xdc, 0xb8, 0x21, 0x87, 0xdd, 0x0d, 0xb9, 0x46, 0x09, 0x3e,
595       0xef, 0x81, 0x5b, 0x37, 0x09, 0x39, 0xeb};
596 
597   Reset(TlsAgent::kServerDsa);
598 
599   const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ffdhe_2048};
600   client_->ConfigNamedGroups(client_groups);
601 
602   server_->SetPacketFilter(new TlsDheSkeChangeSignature(
603       version_, kBogusDheSignature, sizeof(kBogusDheSignature)));
604 
605   ConnectExpectFail();
606   client_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
607 }
608 
609 }  // namespace nss_test
610