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