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