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 "nss_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_rsae_sha256);
28 }
29 
TEST_P(TlsConnectTls13,SharesForBothEcdheAndDhe)30 TEST_P(TlsConnectTls13, SharesForBothEcdheAndDhe) {
31   EnsureTlsSetup();
32   client_->ConfigNamedGroups(kAllDHEGroups);
33 
34   auto groups_capture =
35       std::make_shared<TlsExtensionCapture>(client_, ssl_supported_groups_xtn);
36   auto shares_capture =
37       std::make_shared<TlsExtensionCapture>(client_, ssl_tls13_key_share_xtn);
38   std::vector<std::shared_ptr<PacketFilter>> captures = {groups_capture,
39                                                          shares_capture};
40   client_->SetFilter(std::make_shared<ChainedPacketFilter>(captures));
41 
42   Connect();
43 
44   CheckKeys();
45 
46   bool ec, dh;
47   auto track_group_type = [&ec, &dh](SSLNamedGroup group) {
48     if ((group & 0xff00U) == 0x100U) {
49       dh = true;
50     } else {
51       ec = true;
52     }
53   };
54   CheckGroups(groups_capture->extension(), track_group_type);
55   CheckShares(shares_capture->extension(), track_group_type);
56   EXPECT_TRUE(ec) << "Should include an EC group and share";
57   EXPECT_TRUE(dh) << "Should include an FFDHE group and share";
58 }
59 
TEST_P(TlsConnectGeneric,ConnectFfdheClient)60 TEST_P(TlsConnectGeneric, ConnectFfdheClient) {
61   EnableOnlyDheCiphers();
62   client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
63   auto groups_capture =
64       std::make_shared<TlsExtensionCapture>(client_, ssl_supported_groups_xtn);
65   auto shares_capture =
66       std::make_shared<TlsExtensionCapture>(client_, ssl_tls13_key_share_xtn);
67   std::vector<std::shared_ptr<PacketFilter>> captures = {groups_capture,
68                                                          shares_capture};
69   client_->SetFilter(std::make_shared<ChainedPacketFilter>(captures));
70 
71   Connect();
72 
73   CheckKeys(ssl_kea_dh, ssl_auth_rsa_sign);
74   auto is_ffdhe = [](SSLNamedGroup group) {
75     // The group has to be in this range.
76     EXPECT_LE(ssl_grp_ffdhe_2048, group);
77     EXPECT_GE(ssl_grp_ffdhe_8192, group);
78   };
79   CheckGroups(groups_capture->extension(), is_ffdhe);
80   if (version_ == SSL_LIBRARY_VERSION_TLS_1_3) {
81     CheckShares(shares_capture->extension(), is_ffdhe);
82   } else {
83     EXPECT_EQ(0U, shares_capture->extension().len());
84   }
85 }
86 
87 // Requiring the FFDHE extension on the server alone means that clients won't be
88 // able to connect using a DHE suite.  They should still connect in TLS 1.3,
89 // because the client automatically sends the supported groups extension.
TEST_P(TlsConnectGenericPre13,ConnectFfdheServer)90 TEST_P(TlsConnectGenericPre13, ConnectFfdheServer) {
91   EnableOnlyDheCiphers();
92   server_->SetOption(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     ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
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(const std::shared_ptr<TlsAgent> & a)106   TlsDheServerKeyExchangeDamager(const std::shared_ptr<TlsAgent>& a)
107       : TlsHandshakeFilter(a, {kTlsHandshakeServerKeyExchange}) {}
FilterHandshake(const TlsHandshakeFilter::HandshakeHeader & header,const DataBuffer & input,DataBuffer * output)108   virtual PacketFilter::Action FilterHandshake(
109       const TlsHandshakeFilter::HandshakeHeader& header,
110       const DataBuffer& input, DataBuffer* output) {
111     // Damage the first octet of dh_p.  Anything other than the known prime will
112     // be rejected as "weak" when we have SSL_REQUIRE_DH_NAMED_GROUPS enabled.
113     *output = input;
114     output->data()[3] ^= 73;
115     return CHANGE;
116   }
117 };
118 
119 // Changing the prime in the server's key share results in an error.  This will
120 // invalidate the signature over the ServerKeyShare. That's ok, NSS won't check
121 // the signature until everything else has been checked.
TEST_P(TlsConnectGenericPre13,DamageServerKeyShare)122 TEST_P(TlsConnectGenericPre13, DamageServerKeyShare) {
123   EnableOnlyDheCiphers();
124   client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
125   MakeTlsFilter<TlsDheServerKeyExchangeDamager>(server_);
126 
127   ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
128 
129   client_->CheckErrorCode(SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY);
130   server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
131 }
132 
133 class TlsDheSkeChangeY : public TlsHandshakeFilter {
134  public:
135   enum ChangeYTo {
136     kYZero,
137     kYOne,
138     kYPMinusOne,
139     kYGreaterThanP,
140     kYTooLarge,
141     kYZeroPad
142   };
143 
TlsDheSkeChangeY(const std::shared_ptr<TlsAgent> & a,uint8_t handshake_type,ChangeYTo change)144   TlsDheSkeChangeY(const std::shared_ptr<TlsAgent>& a, uint8_t handshake_type,
145                    ChangeYTo change)
146       : TlsHandshakeFilter(a, {handshake_type}), change_Y_(change) {}
147 
148  protected:
ChangeY(const DataBuffer & input,DataBuffer * output,size_t offset,const DataBuffer & prime)149   void ChangeY(const DataBuffer& input, DataBuffer* output, size_t offset,
150                const DataBuffer& prime) {
151     static const uint8_t kExtraZero = 0;
152     static const uint8_t kTooLargeExtra = 1;
153 
154     uint32_t dh_Ys_len;
155     EXPECT_TRUE(input.Read(offset, 2, &dh_Ys_len));
156     EXPECT_LT(offset + dh_Ys_len, input.len());
157     offset += 2;
158 
159     // This isn't generally true, but our code pads.
160     EXPECT_EQ(prime.len(), dh_Ys_len)
161         << "Length of dh_Ys must equal length of dh_p";
162 
163     *output = input;
164     switch (change_Y_) {
165       case kYZero:
166         memset(output->data() + offset, 0, prime.len());
167         break;
168 
169       case kYOne:
170         memset(output->data() + offset, 0, prime.len() - 1);
171         output->Write(offset + prime.len() - 1, 1U, 1);
172         break;
173 
174       case kYPMinusOne:
175         output->Write(offset, prime);
176         EXPECT_TRUE(output->data()[offset + prime.len() - 1] & 0x01)
177             << "P must at least be odd";
178         --output->data()[offset + prime.len() - 1];
179         break;
180 
181       case kYGreaterThanP:
182         // Set the first 32 octets of Y to 0xff, except the first which we set
183         // to p[0].  This will make Y > p.  That is, unless p is Mersenne, or
184         // improbably large (but still the same bit length).  We currently only
185         // use a fixed prime that isn't a problem for this code.
186         EXPECT_LT(0, prime.data()[0]) << "dh_p should not be zero-padded";
187         offset = output->Write(offset, prime.data()[0], 1);
188         memset(output->data() + offset, 0xff, 31);
189         break;
190 
191       case kYTooLarge:
192         // Increase the dh_Ys length.
193         output->Write(offset - 2, prime.len() + sizeof(kTooLargeExtra), 2);
194         // Then insert the octet.
195         output->Splice(&kTooLargeExtra, sizeof(kTooLargeExtra), offset);
196         break;
197 
198       case kYZeroPad:
199         output->Write(offset - 2, prime.len() + sizeof(kExtraZero), 2);
200         output->Splice(&kExtraZero, sizeof(kExtraZero), offset);
201         break;
202     }
203   }
204 
205  private:
206   ChangeYTo change_Y_;
207 };
208 
209 class TlsDheSkeChangeYServer : public TlsDheSkeChangeY {
210  public:
TlsDheSkeChangeYServer(const std::shared_ptr<TlsAgent> & a,ChangeYTo change,bool modify)211   TlsDheSkeChangeYServer(const std::shared_ptr<TlsAgent>& a, ChangeYTo change,
212                          bool modify)
213       : TlsDheSkeChangeY(a, kTlsHandshakeServerKeyExchange, change),
214         modify_(modify),
215         p_() {}
216 
prime() const217   const DataBuffer& prime() const { return p_; }
218 
219  protected:
FilterHandshake(const TlsHandshakeFilter::HandshakeHeader & header,const DataBuffer & input,DataBuffer * output)220   virtual PacketFilter::Action FilterHandshake(
221       const TlsHandshakeFilter::HandshakeHeader& header,
222       const DataBuffer& input, DataBuffer* output) override {
223     size_t offset = 2;
224     // Read dh_p
225     uint32_t dh_len = 0;
226     EXPECT_TRUE(input.Read(0, 2, &dh_len));
227     EXPECT_GT(input.len(), offset + dh_len);
228     p_.Assign(input.data() + offset, dh_len);
229     offset += dh_len;
230 
231     // Skip dh_g to find dh_Ys
232     EXPECT_TRUE(input.Read(offset, 2, &dh_len));
233     offset += 2 + dh_len;
234 
235     if (modify_) {
236       ChangeY(input, output, offset, p_);
237       return CHANGE;
238     }
239     return KEEP;
240   }
241 
242  private:
243   bool modify_;
244   DataBuffer p_;
245 };
246 
247 class TlsDheSkeChangeYClient : public TlsDheSkeChangeY {
248  public:
TlsDheSkeChangeYClient(const std::shared_ptr<TlsAgent> & a,ChangeYTo change,std::shared_ptr<const TlsDheSkeChangeYServer> server_filter)249   TlsDheSkeChangeYClient(
250       const std::shared_ptr<TlsAgent>& a, ChangeYTo change,
251       std::shared_ptr<const TlsDheSkeChangeYServer> server_filter)
252       : TlsDheSkeChangeY(a, kTlsHandshakeClientKeyExchange, change),
253         server_filter_(server_filter) {}
254 
255  protected:
FilterHandshake(const TlsHandshakeFilter::HandshakeHeader & header,const DataBuffer & input,DataBuffer * output)256   virtual PacketFilter::Action FilterHandshake(
257       const TlsHandshakeFilter::HandshakeHeader& header,
258       const DataBuffer& input, DataBuffer* output) override {
259     ChangeY(input, output, 0, server_filter_->prime());
260     return CHANGE;
261   }
262 
263  private:
264   std::shared_ptr<const TlsDheSkeChangeYServer> server_filter_;
265 };
266 
267 /* This matrix includes: variant (stream/datagram), TLS version, what change to
268  * make to dh_Ys, whether the client will be configured to require DH named
269  * groups.  Test all combinations. */
270 typedef std::tuple<SSLProtocolVariant, uint16_t, TlsDheSkeChangeY::ChangeYTo,
271                    bool>
272     DamageDHYProfile;
273 class TlsDamageDHYTest
274     : public TlsConnectTestBase,
275       public ::testing::WithParamInterface<DamageDHYProfile> {
276  public:
TlsDamageDHYTest()277   TlsDamageDHYTest()
278       : TlsConnectTestBase(std::get<0>(GetParam()), std::get<1>(GetParam())) {}
279 };
280 
TEST_P(TlsDamageDHYTest,DamageServerY)281 TEST_P(TlsDamageDHYTest, DamageServerY) {
282   EnableOnlyDheCiphers();
283   if (std::get<3>(GetParam())) {
284     client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
285   }
286   TlsDheSkeChangeY::ChangeYTo change = std::get<2>(GetParam());
287   MakeTlsFilter<TlsDheSkeChangeYServer>(server_, change, true);
288 
289   if (change == TlsDheSkeChangeY::kYZeroPad) {
290     ExpectAlert(client_, kTlsAlertDecryptError);
291   } else {
292     ExpectAlert(client_, kTlsAlertIllegalParameter);
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     client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
314   }
315   // The filter on the server is required to capture the prime.
316   auto server_filter = MakeTlsFilter<TlsDheSkeChangeYServer>(
317       server_, TlsDheSkeChangeY::kYZero, false);
318 
319   // The client filter does the damage.
320   TlsDheSkeChangeY::ChangeYTo change = std::get<2>(GetParam());
321   MakeTlsFilter<TlsDheSkeChangeYClient>(client_, change, server_filter);
322 
323   if (change == TlsDheSkeChangeY::kYZeroPad) {
324     ExpectAlert(server_, kTlsAlertDecryptError);
325   } else {
326     ExpectAlert(server_, kTlsAlertHandshakeFailure);
327   }
328   ConnectExpectFail();
329   if (change == TlsDheSkeChangeY::kYZeroPad) {
330     // Zero padding Y only manifests in a finished error.
331     client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
332     server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
333   } else {
334     client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_FAILURE_ALERT);
335     server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE);
336   }
337 }
338 
339 static const TlsDheSkeChangeY::ChangeYTo kAllYArr[] = {
340     TlsDheSkeChangeY::kYZero,      TlsDheSkeChangeY::kYOne,
341     TlsDheSkeChangeY::kYPMinusOne, TlsDheSkeChangeY::kYGreaterThanP,
342     TlsDheSkeChangeY::kYTooLarge,  TlsDheSkeChangeY::kYZeroPad};
343 static ::testing::internal::ParamGenerator<TlsDheSkeChangeY::ChangeYTo> kAllY =
344     ::testing::ValuesIn(kAllYArr);
345 static const bool kTrueFalseArr[] = {true, false};
346 static ::testing::internal::ParamGenerator<bool> kTrueFalse =
347     ::testing::ValuesIn(kTrueFalseArr);
348 
349 INSTANTIATE_TEST_SUITE_P(
350     DamageYStream, TlsDamageDHYTest,
351     ::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
352                        TlsConnectTestBase::kTlsV10ToV12, kAllY, kTrueFalse));
353 INSTANTIATE_TEST_SUITE_P(
354     DamageYDatagram, TlsDamageDHYTest,
355     ::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram,
356                        TlsConnectTestBase::kTlsV11V12, kAllY, kTrueFalse));
357 
358 class TlsDheSkeMakePEven : public TlsHandshakeFilter {
359  public:
TlsDheSkeMakePEven(const std::shared_ptr<TlsAgent> & a)360   TlsDheSkeMakePEven(const std::shared_ptr<TlsAgent>& a)
361       : TlsHandshakeFilter(a, {kTlsHandshakeServerKeyExchange}) {}
362 
FilterHandshake(const TlsHandshakeFilter::HandshakeHeader & header,const DataBuffer & input,DataBuffer * output)363   virtual PacketFilter::Action FilterHandshake(
364       const TlsHandshakeFilter::HandshakeHeader& header,
365       const DataBuffer& input, DataBuffer* output) {
366     // Find the end of dh_p
367     uint32_t dh_len = 0;
368     EXPECT_TRUE(input.Read(0, 2, &dh_len));
369     EXPECT_GT(input.len(), 2 + dh_len) << "enough space for dh_p";
370     size_t offset = 2 + dh_len - 1;
371     EXPECT_TRUE((input.data()[offset] & 0x01) == 0x01) << "p should be odd";
372 
373     *output = input;
374     output->data()[offset] &= 0xfe;
375 
376     return CHANGE;
377   }
378 };
379 
380 // Even without requiring named groups, an even value for p is bad news.
TEST_P(TlsConnectGenericPre13,MakeDhePEven)381 TEST_P(TlsConnectGenericPre13, MakeDhePEven) {
382   EnableOnlyDheCiphers();
383   MakeTlsFilter<TlsDheSkeMakePEven>(server_);
384 
385   ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
386 
387   client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE);
388   server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
389 }
390 
391 class TlsDheSkeZeroPadP : public TlsHandshakeFilter {
392  public:
TlsDheSkeZeroPadP(const std::shared_ptr<TlsAgent> & a)393   TlsDheSkeZeroPadP(const std::shared_ptr<TlsAgent>& a)
394       : TlsHandshakeFilter(a, {kTlsHandshakeServerKeyExchange}) {}
395 
FilterHandshake(const TlsHandshakeFilter::HandshakeHeader & header,const DataBuffer & input,DataBuffer * output)396   virtual PacketFilter::Action FilterHandshake(
397       const TlsHandshakeFilter::HandshakeHeader& header,
398       const DataBuffer& input, DataBuffer* output) {
399     *output = input;
400     uint32_t dh_len = 0;
401     EXPECT_TRUE(input.Read(0, 2, &dh_len));
402     static const uint8_t kZeroPad = 0;
403     output->Write(0, dh_len + sizeof(kZeroPad), 2);  // increment the length
404     output->Splice(&kZeroPad, sizeof(kZeroPad), 2);  // insert a zero
405 
406     return CHANGE;
407   }
408 };
409 
410 // Zero padding only causes signature failure.
TEST_P(TlsConnectGenericPre13,PadDheP)411 TEST_P(TlsConnectGenericPre13, PadDheP) {
412   EnableOnlyDheCiphers();
413   MakeTlsFilter<TlsDheSkeZeroPadP>(server_);
414 
415   ConnectExpectAlert(client_, kTlsAlertDecryptError);
416 
417   // In TLS 1.0 and 1.1, the client reports a device error.
418   if (version_ < SSL_LIBRARY_VERSION_TLS_1_2) {
419     client_->CheckErrorCode(SEC_ERROR_PKCS11_DEVICE_ERROR);
420   } else {
421     client_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
422   }
423   server_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
424 }
425 
426 // The server should not pick the weak DH group if the client includes FFDHE
427 // named groups in the supported_groups extension. The server then picks a
428 // commonly-supported named DH group and this connects.
429 //
430 // Note: This test case can take ages to generate the weak DH key.
TEST_P(TlsConnectGenericPre13,WeakDHGroup)431 TEST_P(TlsConnectGenericPre13, WeakDHGroup) {
432   EnableOnlyDheCiphers();
433   client_->SetOption(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_rsae_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   ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
474   server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
475   client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
476 }
477 
478 // Replace the key share in the server key exchange message with one that's
479 // larger than 8192 bits.
480 class TooLongDHEServerKEXFilter : public TlsHandshakeFilter {
481  public:
TooLongDHEServerKEXFilter(const std::shared_ptr<TlsAgent> & server)482   TooLongDHEServerKEXFilter(const std::shared_ptr<TlsAgent>& server)
483       : TlsHandshakeFilter(server, {kTlsHandshakeServerKeyExchange}) {}
484 
485  protected:
FilterHandshake(const HandshakeHeader & header,const DataBuffer & input,DataBuffer * output)486   virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
487                                                const DataBuffer& input,
488                                                DataBuffer* output) {
489     // Replace the server key exchange message very large DH shares that are
490     // not supported by NSS.
491     const uint32_t share_len = 0x401;
492     const uint8_t zero_share[share_len] = {0x80};
493     size_t offset = 0;
494     // Write dh_p.
495     offset = output->Write(offset, share_len, 2);
496     offset = output->Write(offset, zero_share, share_len);
497     // Write dh_g.
498     offset = output->Write(offset, share_len, 2);
499     offset = output->Write(offset, zero_share, share_len);
500     // Write dh_Y.
501     offset = output->Write(offset, share_len, 2);
502     offset = output->Write(offset, zero_share, share_len);
503 
504     return CHANGE;
505   }
506 };
507 
TEST_P(TlsConnectGenericPre13,TooBigDHGroup)508 TEST_P(TlsConnectGenericPre13, TooBigDHGroup) {
509   EnableOnlyDheCiphers();
510   MakeTlsFilter<TooLongDHEServerKEXFilter>(server_);
511   client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_FALSE);
512   ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
513   server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
514   client_->CheckErrorCode(SSL_ERROR_DH_KEY_TOO_LONG);
515 }
516 
517 // Even though the client doesn't have DHE groups enabled the server assumes it
518 // does. The client requires named groups and thus does not accept FF3072 as
519 // custom group in contrast to the previous test.
TEST_P(TlsConnectGenericPre13,RequireNamedGroupsMismatchPre13)520 TEST_P(TlsConnectGenericPre13, RequireNamedGroupsMismatchPre13) {
521   EnableOnlyDheCiphers();
522   client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
523   static const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ffdhe_3072};
524   static const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_secp256r1,
525                                                            ssl_grp_ffdhe_2048};
526   server_->ConfigNamedGroups(server_groups);
527   client_->ConfigNamedGroups(client_groups);
528 
529   ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
530   server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
531   client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
532 }
533 
TEST_P(TlsConnectGenericPre13,PreferredFfdhe)534 TEST_P(TlsConnectGenericPre13, PreferredFfdhe) {
535   EnableOnlyDheCiphers();
536   static const SSLDHEGroupType groups[] = {ssl_ff_dhe_3072_group,
537                                            ssl_ff_dhe_2048_group};
538   EXPECT_EQ(SECSuccess, SSL_DHEGroupPrefSet(server_->ssl_fd(), groups,
539                                             PR_ARRAY_SIZE(groups)));
540 
541   Connect();
542   client_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_3072, 3072);
543   server_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_3072, 3072);
544   client_->CheckAuthType(ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
545   server_->CheckAuthType(ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
546 }
547 
TEST_P(TlsConnectGenericPre13,MismatchDHE)548 TEST_P(TlsConnectGenericPre13, MismatchDHE) {
549   EnableOnlyDheCiphers();
550   client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
551   static const SSLDHEGroupType serverGroups[] = {ssl_ff_dhe_3072_group};
552   EXPECT_EQ(SECSuccess, SSL_DHEGroupPrefSet(server_->ssl_fd(), serverGroups,
553                                             PR_ARRAY_SIZE(serverGroups)));
554   static const SSLDHEGroupType clientGroups[] = {ssl_ff_dhe_2048_group};
555   EXPECT_EQ(SECSuccess, SSL_DHEGroupPrefSet(client_->ssl_fd(), clientGroups,
556                                             PR_ARRAY_SIZE(clientGroups)));
557 
558   ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
559   server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
560   client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
561 }
562 
TEST_P(TlsConnectTls13,ResumeFfdhe)563 TEST_P(TlsConnectTls13, ResumeFfdhe) {
564   EnableOnlyDheCiphers();
565   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
566   Connect();
567   SendReceive();  // Need to read so that we absorb the session ticket.
568   CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign,
569             ssl_sig_rsa_pss_rsae_sha256);
570 
571   Reset();
572   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
573   EnableOnlyDheCiphers();
574   auto clientCapture =
575       MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_pre_shared_key_xtn);
576   auto serverCapture =
577       MakeTlsFilter<TlsExtensionCapture>(server_, ssl_tls13_pre_shared_key_xtn);
578   ExpectResumption(RESUME_TICKET);
579   Connect();
580   CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign,
581             ssl_sig_rsa_pss_rsae_sha256);
582   ASSERT_LT(0UL, clientCapture->extension().len());
583   ASSERT_LT(0UL, serverCapture->extension().len());
584 }
585 
586 class TlsDheSkeChangeSignature : public TlsHandshakeFilter {
587  public:
TlsDheSkeChangeSignature(const std::shared_ptr<TlsAgent> & a,uint16_t version,const uint8_t * data,size_t len)588   TlsDheSkeChangeSignature(const std::shared_ptr<TlsAgent>& a, uint16_t version,
589                            const uint8_t* data, size_t len)
590       : TlsHandshakeFilter(a, {kTlsHandshakeServerKeyExchange}),
591         version_(version),
592         data_(data),
593         len_(len) {}
594 
595  protected:
FilterHandshake(const HandshakeHeader & header,const DataBuffer & input,DataBuffer * output)596   virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
597                                                const DataBuffer& input,
598                                                DataBuffer* output) {
599     TlsParser parser(input);
600     EXPECT_TRUE(parser.SkipVariable(2));  // dh_p
601     EXPECT_TRUE(parser.SkipVariable(2));  // dh_g
602     EXPECT_TRUE(parser.SkipVariable(2));  // dh_Ys
603 
604     // Copy DH params to output.
605     size_t offset = output->Write(0, input.data(), parser.consumed());
606 
607     if (version_ == SSL_LIBRARY_VERSION_TLS_1_2) {
608       // Write signature algorithm.
609       offset = output->Write(offset, ssl_sig_dsa_sha256, 2);
610     }
611 
612     // Write new signature.
613     offset = output->Write(offset, len_, 2);
614     offset = output->Write(offset, data_, len_);
615 
616     return CHANGE;
617   }
618 
619  private:
620   uint16_t version_;
621   const uint8_t* data_;
622   size_t len_;
623 };
624 
TEST_P(TlsConnectGenericPre13,InvalidDERSignatureFfdhe)625 TEST_P(TlsConnectGenericPre13, InvalidDERSignatureFfdhe) {
626   const uint8_t kBogusDheSignature[] = {
627       0x30, 0x69, 0x3c, 0x02, 0x1c, 0x7d, 0x0b, 0x2f, 0x64, 0x00, 0x27,
628       0xae, 0xcf, 0x1e, 0x28, 0x08, 0x6a, 0x7f, 0xb1, 0xbd, 0x78, 0xb5,
629       0x3b, 0x8c, 0x8f, 0x59, 0xed, 0x8f, 0xee, 0x78, 0xeb, 0x2c, 0xe9,
630       0x02, 0x1c, 0x6d, 0x7f, 0x3c, 0x0f, 0xf4, 0x44, 0x35, 0x0b, 0xb2,
631       0x6d, 0xdc, 0xb8, 0x21, 0x87, 0xdd, 0x0d, 0xb9, 0x46, 0x09, 0x3e,
632       0xef, 0x81, 0x5b, 0x37, 0x09, 0x39, 0xeb};
633 
634   Reset(TlsAgent::kServerDsa);
635 
636   const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ffdhe_2048};
637   client_->ConfigNamedGroups(client_groups);
638 
639   MakeTlsFilter<TlsDheSkeChangeSignature>(server_, version_, kBogusDheSignature,
640                                           sizeof(kBogusDheSignature));
641 
642   ConnectExpectAlert(client_, kTlsAlertDecryptError);
643   client_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
644 }
645 
646 // Replace SignatureAndHashAlgorithm of a SKE.
647 class DHEServerKEXSigAlgReplacer : public TlsHandshakeFilter {
648  public:
DHEServerKEXSigAlgReplacer(const std::shared_ptr<TlsAgent> & server,SSLSignatureScheme sig_scheme)649   DHEServerKEXSigAlgReplacer(const std::shared_ptr<TlsAgent>& server,
650                              SSLSignatureScheme sig_scheme)
651       : TlsHandshakeFilter(server, {kTlsHandshakeServerKeyExchange}),
652         sig_scheme_(sig_scheme) {}
653 
654  protected:
FilterHandshake(const HandshakeHeader & header,const DataBuffer & input,DataBuffer * output)655   virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
656                                                const DataBuffer& input,
657                                                DataBuffer* output) {
658     *output = input;
659 
660     uint32_t len;
661     uint32_t idx = 0;
662     EXPECT_TRUE(output->Read(idx, 2, &len));
663     idx += 2 + len;
664     EXPECT_TRUE(output->Read(idx, 2, &len));
665     idx += 2 + len;
666     EXPECT_TRUE(output->Read(idx, 2, &len));
667     idx += 2 + len;
668     output->Write(idx, sig_scheme_, 2);
669 
670     return CHANGE;
671   }
672 
673  private:
674   SSLSignatureScheme sig_scheme_;
675 };
676 
TEST_P(TlsConnectTls12,ConnectInconsistentSigAlgDHE)677 TEST_P(TlsConnectTls12, ConnectInconsistentSigAlgDHE) {
678   EnableOnlyDheCiphers();
679 
680   MakeTlsFilter<DHEServerKEXSigAlgReplacer>(server_,
681                                             ssl_sig_ecdsa_secp256r1_sha256);
682   ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
683 }
684 
CheckSkeSigScheme(std::shared_ptr<TlsHandshakeRecorder> & capture_ske,uint16_t expected_scheme)685 static void CheckSkeSigScheme(
686     std::shared_ptr<TlsHandshakeRecorder>& capture_ske,
687     uint16_t expected_scheme) {
688   TlsParser parser(capture_ske->buffer());
689   EXPECT_TRUE(parser.SkipVariable(2)) << " read dh_p";
690   EXPECT_TRUE(parser.SkipVariable(2)) << " read dh_q";
691   EXPECT_TRUE(parser.SkipVariable(2)) << " read dh_Ys";
692 
693   uint32_t tmp;
694   EXPECT_TRUE(parser.Read(&tmp, 2)) << " read sig_scheme";
695   EXPECT_EQ(expected_scheme, static_cast<uint16_t>(tmp));
696 }
697 
TEST_P(TlsConnectTls12,ConnectSigAlgEnabledByPolicyDhe)698 TEST_P(TlsConnectTls12, ConnectSigAlgEnabledByPolicyDhe) {
699   EnableOnlyDheCiphers();
700 
701   const std::vector<SSLSignatureScheme> schemes = {ssl_sig_rsa_pkcs1_sha1,
702                                                    ssl_sig_rsa_pkcs1_sha384};
703 
704   EnsureTlsSetup();
705   client_->SetSignatureSchemes(schemes.data(), schemes.size());
706   server_->SetSignatureSchemes(schemes.data(), schemes.size());
707   auto capture_ske = MakeTlsFilter<TlsHandshakeRecorder>(
708       server_, kTlsHandshakeServerKeyExchange);
709 
710   StartConnect();
711   client_->Handshake();  // Send ClientHello
712 
713   // Enable SHA-1 by policy.
714   SECStatus rv = NSS_SetAlgorithmPolicy(SEC_OID_SHA1, NSS_USE_ALG_IN_SSL_KX, 0);
715   ASSERT_EQ(SECSuccess, rv);
716   rv = NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL,
717                               0);
718   ASSERT_EQ(SECSuccess, rv);
719 
720   Handshake();  // Remainder of handshake
721   // The server should now report that it is connected
722   EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
723 
724   CheckSkeSigScheme(capture_ske, ssl_sig_rsa_pkcs1_sha1);
725 }
726 
TEST_P(TlsConnectTls12,ConnectSigAlgDisabledByPolicyDhe)727 TEST_P(TlsConnectTls12, ConnectSigAlgDisabledByPolicyDhe) {
728   EnableOnlyDheCiphers();
729 
730   const std::vector<SSLSignatureScheme> schemes = {ssl_sig_rsa_pkcs1_sha1,
731                                                    ssl_sig_rsa_pkcs1_sha384};
732 
733   EnsureTlsSetup();
734   client_->SetSignatureSchemes(schemes.data(), schemes.size());
735   server_->SetSignatureSchemes(schemes.data(), schemes.size());
736   auto capture_ske = MakeTlsFilter<TlsHandshakeRecorder>(
737       server_, kTlsHandshakeServerKeyExchange);
738 
739   StartConnect();
740   client_->Handshake();  // Send ClientHello
741 
742   // Disable SHA-1 by policy after sending ClientHello so that CH
743   // includes SHA-1 signature scheme.
744   SECStatus rv = NSS_SetAlgorithmPolicy(SEC_OID_SHA1, 0, NSS_USE_ALG_IN_SSL_KX);
745   ASSERT_EQ(SECSuccess, rv);
746   rv = NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL,
747                               0);
748   ASSERT_EQ(SECSuccess, rv);
749 
750   Handshake();  // Remainder of handshake
751   // The server should now report that it is connected
752   EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
753 
754   CheckSkeSigScheme(capture_ske, ssl_sig_rsa_pkcs1_sha384);
755 }
756 
TEST_P(TlsConnectPre12,ConnectSigAlgDisabledByPolicyDhePre12)757 TEST_P(TlsConnectPre12, ConnectSigAlgDisabledByPolicyDhePre12) {
758   EnableOnlyDheCiphers();
759 
760   EnsureTlsSetup();
761   StartConnect();
762   client_->Handshake();  // Send ClientHello
763 
764   // Disable SHA-1 by policy.  This will cause the connection fail as
765   // TLS 1.1 or earlier uses combined SHA-1 + MD5 signature.
766   SECStatus rv = NSS_SetAlgorithmPolicy(SEC_OID_SHA1, 0, NSS_USE_ALG_IN_SSL_KX);
767   ASSERT_EQ(SECSuccess, rv);
768   rv = NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL,
769                               0);
770   ASSERT_EQ(SECSuccess, rv);
771 
772   server_->ExpectSendAlert(kTlsAlertHandshakeFailure);
773   client_->ExpectReceiveAlert(kTlsAlertHandshakeFailure);
774 
775   // Remainder of handshake
776   Handshake();
777 
778   server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
779 }
780 
781 }  // namespace nss_test
782