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 "pk11pub.h"
8 #include "ssl.h"
9 #include "sslerr.h"
10 #include "sslproto.h"
11 
12 extern "C" {
13 // This is not something that should make you happy.
14 #include "libssl_internals.h"
15 }
16 
17 #include "gtest_utils.h"
18 #include "tls_connect.h"
19 #include "tls_filter.h"
20 
21 namespace nss_test {
22 
23 // Replaces the client hello with an SSLv2 version once.
24 class SSLv2ClientHelloFilter : public PacketFilter {
25  public:
SSLv2ClientHelloFilter(const std::shared_ptr<TlsAgent> & client,uint16_t version)26   SSLv2ClientHelloFilter(const std::shared_ptr<TlsAgent>& client,
27                          uint16_t version)
28       : replaced_(false),
29         client_(client),
30         version_(version),
31         pad_len_(0),
32         reported_pad_len_(0),
33         client_random_len_(16),
34         ciphers_(0),
35         send_escape_(false) {}
36 
SetVersion(uint16_t version)37   void SetVersion(uint16_t version) { version_ = version; }
38 
SetCipherSuites(const std::vector<uint16_t> & ciphers)39   void SetCipherSuites(const std::vector<uint16_t>& ciphers) {
40     ciphers_ = ciphers;
41   }
42 
43   // Set a padding length and announce it correctly.
SetPadding(uint8_t pad_len)44   void SetPadding(uint8_t pad_len) { SetPadding(pad_len, pad_len); }
45 
46   // Set a padding length and allow to lie about its length.
SetPadding(uint8_t pad_len,uint8_t reported_pad_len)47   void SetPadding(uint8_t pad_len, uint8_t reported_pad_len) {
48     pad_len_ = pad_len;
49     reported_pad_len_ = reported_pad_len;
50   }
51 
SetClientRandomLength(uint16_t client_random_len)52   void SetClientRandomLength(uint16_t client_random_len) {
53     client_random_len_ = client_random_len;
54   }
55 
SetSendEscape(bool send_escape)56   void SetSendEscape(bool send_escape) { send_escape_ = send_escape; }
57 
58  protected:
Filter(const DataBuffer & input,DataBuffer * output)59   virtual PacketFilter::Action Filter(const DataBuffer& input,
60                                       DataBuffer* output) {
61     if (replaced_) {
62       return KEEP;
63     }
64 
65     // Replace only the very first packet.
66     replaced_ = true;
67 
68     // The SSLv2 client hello size.
69     size_t packet_len = SSL_HL_CLIENT_HELLO_HBYTES + (ciphers_.size() * 3) +
70                         client_random_len_ + pad_len_;
71 
72     size_t idx = 0;
73     *output = input;
74     output->Allocate(packet_len);
75     output->Truncate(packet_len);
76 
77     // Write record length.
78     if (pad_len_ > 0) {
79       size_t masked_len = 0x3fff & packet_len;
80       if (send_escape_) {
81         masked_len |= 0x4000;
82       }
83 
84       idx = output->Write(idx, masked_len, 2);
85       idx = output->Write(idx, reported_pad_len_, 1);
86     } else {
87       PR_ASSERT(!send_escape_);
88       idx = output->Write(idx, 0x8000 | packet_len, 2);
89     }
90 
91     // Remember header length.
92     size_t hdr_len = idx;
93 
94     // Write client hello.
95     idx = output->Write(idx, SSL_MT_CLIENT_HELLO, 1);
96     idx = output->Write(idx, version_, 2);
97 
98     // Cipher list length.
99     idx = output->Write(idx, (ciphers_.size() * 3), 2);
100 
101     // Session ID length.
102     idx = output->Write(idx, static_cast<uint32_t>(0), 2);
103 
104     // ClientRandom length.
105     idx = output->Write(idx, client_random_len_, 2);
106 
107     // Cipher suites.
108     for (auto cipher : ciphers_) {
109       idx = output->Write(idx, static_cast<uint32_t>(cipher), 3);
110     }
111 
112     // Challenge.
113     std::vector<uint8_t> challenge(client_random_len_);
114     PK11_GenerateRandom(challenge.data(), challenge.size());
115     idx = output->Write(idx, challenge.data(), challenge.size());
116 
117     // Add padding if any.
118     if (pad_len_ > 0) {
119       std::vector<uint8_t> pad(pad_len_);
120       idx = output->Write(idx, pad.data(), pad.size());
121     }
122 
123     // Update the client random so that the handshake succeeds.
124     SECStatus rv = SSLInt_UpdateSSLv2ClientRandom(
125         client_.lock()->ssl_fd(), challenge.data(), challenge.size(),
126         output->data() + hdr_len, output->len() - hdr_len);
127     EXPECT_EQ(SECSuccess, rv);
128 
129     return CHANGE;
130   }
131 
132  private:
133   bool replaced_;
134   std::weak_ptr<TlsAgent> client_;
135   uint16_t version_;
136   uint8_t pad_len_;
137   uint8_t reported_pad_len_;
138   uint16_t client_random_len_;
139   std::vector<uint16_t> ciphers_;
140   bool send_escape_;
141 };
142 
143 class SSLv2ClientHelloTestF : public TlsConnectTestBase {
144  public:
SSLv2ClientHelloTestF()145   SSLv2ClientHelloTestF()
146       : TlsConnectTestBase(ssl_variant_stream, 0), filter_(nullptr) {}
147 
SSLv2ClientHelloTestF(SSLProtocolVariant variant,uint16_t version)148   SSLv2ClientHelloTestF(SSLProtocolVariant variant, uint16_t version)
149       : TlsConnectTestBase(variant, version), filter_(nullptr) {}
150 
SetUp()151   void SetUp() override {
152     TlsConnectTestBase::SetUp();
153     filter_ = MakeTlsFilter<SSLv2ClientHelloFilter>(client_, version_);
154     server_->SetOption(SSL_ENABLE_V2_COMPATIBLE_HELLO, PR_TRUE);
155   }
156 
SetExpectedVersion(uint16_t version)157   void SetExpectedVersion(uint16_t version) {
158     TlsConnectTestBase::SetExpectedVersion(version);
159     filter_->SetVersion(version);
160   }
161 
SetAvailableCipherSuite(uint16_t cipher)162   void SetAvailableCipherSuite(uint16_t cipher) {
163     filter_->SetCipherSuites(std::vector<uint16_t>(1, cipher));
164   }
165 
SetAvailableCipherSuites(const std::vector<uint16_t> & ciphers)166   void SetAvailableCipherSuites(const std::vector<uint16_t>& ciphers) {
167     filter_->SetCipherSuites(ciphers);
168   }
169 
SetPadding(uint8_t pad_len)170   void SetPadding(uint8_t pad_len) { filter_->SetPadding(pad_len); }
171 
SetPadding(uint8_t pad_len,uint8_t reported_pad_len)172   void SetPadding(uint8_t pad_len, uint8_t reported_pad_len) {
173     filter_->SetPadding(pad_len, reported_pad_len);
174   }
175 
SetClientRandomLength(uint16_t client_random_len)176   void SetClientRandomLength(uint16_t client_random_len) {
177     filter_->SetClientRandomLength(client_random_len);
178   }
179 
SetSendEscape(bool send_escape)180   void SetSendEscape(bool send_escape) { filter_->SetSendEscape(send_escape); }
181 
182  private:
183   std::shared_ptr<SSLv2ClientHelloFilter> filter_;
184 };
185 
186 // Parameterized version of SSLv2ClientHelloTestF we can
187 // use with TEST_P to test multiple TLS versions easily.
188 class SSLv2ClientHelloTest : public SSLv2ClientHelloTestF,
189                              public ::testing::WithParamInterface<uint16_t> {
190  public:
SSLv2ClientHelloTest()191   SSLv2ClientHelloTest()
192       : SSLv2ClientHelloTestF(ssl_variant_stream, GetParam()) {}
193 };
194 
195 // Test negotiating TLS 1.0 - 1.2.
TEST_P(SSLv2ClientHelloTest,Connect)196 TEST_P(SSLv2ClientHelloTest, Connect) {
197   SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
198   Connect();
199 }
200 
TEST_P(SSLv2ClientHelloTest,ConnectDisabled)201 TEST_P(SSLv2ClientHelloTest, ConnectDisabled) {
202   server_->SetOption(SSL_ENABLE_V2_COMPATIBLE_HELLO, PR_FALSE);
203   SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
204 
205   StartConnect();
206   client_->Handshake();  // Send the modified ClientHello.
207   server_->Handshake();  // Read some.
208   // The problem here is that the v2 ClientHello puts the version where the v3
209   // ClientHello puts a version number.  So the version number (0x0301+) appears
210   // to be a length and server blocks waiting for that much data.
211   EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
212 
213   // This is usually what happens with v2-compatible: the server hangs.
214   // But to be certain, feed in more data to see if an error comes out.
215   uint8_t zeros[SSL_LIBRARY_VERSION_TLS_1_2] = {0};
216   client_->SendDirect(DataBuffer(zeros, sizeof(zeros)));
217   ExpectAlert(server_, kTlsAlertIllegalParameter);
218   server_->Handshake();
219   client_->Handshake();
220 }
221 
222 // Sending a v2 ClientHello after a no-op v3 record must fail.
TEST_P(SSLv2ClientHelloTest,ConnectAfterEmptyV3Record)223 TEST_P(SSLv2ClientHelloTest, ConnectAfterEmptyV3Record) {
224   DataBuffer buffer;
225 
226   size_t idx = 0;
227   idx = buffer.Write(idx, 0x16, 1);    // handshake
228   idx = buffer.Write(idx, 0x0301, 2);  // record_version
229   (void)buffer.Write(idx, 0U, 2);      // length=0
230 
231   SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
232   EnsureTlsSetup();
233   client_->SendDirect(buffer);
234 
235   // Need padding so the connection doesn't just time out. With a v2
236   // ClientHello parsed as a v3 record we will use the record version
237   // as the record length.
238   SetPadding(255);
239 
240   ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
241   EXPECT_EQ(SSL_ERROR_BAD_CLIENT, server_->error_code());
242 }
243 
244 // Test negotiating TLS 1.3.
TEST_F(SSLv2ClientHelloTestF,Connect13)245 TEST_F(SSLv2ClientHelloTestF, Connect13) {
246   EnsureTlsSetup();
247   SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_3);
248   ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
249 
250   std::vector<uint16_t> cipher_suites = {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256};
251   SetAvailableCipherSuites(cipher_suites);
252 
253   ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
254   EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code());
255 }
256 
257 // Test negotiating an EC suite.
TEST_P(SSLv2ClientHelloTest,NegotiateECSuite)258 TEST_P(SSLv2ClientHelloTest, NegotiateECSuite) {
259   SetAvailableCipherSuite(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
260   Connect();
261 }
262 
263 // Test negotiating TLS 1.0 - 1.2 with a padded client hello.
TEST_P(SSLv2ClientHelloTest,AddPadding)264 TEST_P(SSLv2ClientHelloTest, AddPadding) {
265   SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
266   SetPadding(255);
267   Connect();
268 }
269 
270 // Test that sending a security escape fails the handshake.
TEST_P(SSLv2ClientHelloTest,SendSecurityEscape)271 TEST_P(SSLv2ClientHelloTest, SendSecurityEscape) {
272   SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
273 
274   // Send a security escape.
275   SetSendEscape(true);
276 
277   // Set a big padding so that the server fails instead of timing out.
278   SetPadding(255);
279 
280   ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
281 }
282 
283 // Invalid SSLv2 client hello padding must fail the handshake.
TEST_P(SSLv2ClientHelloTest,AddErroneousPadding)284 TEST_P(SSLv2ClientHelloTest, AddErroneousPadding) {
285   SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
286 
287   // Append 5 bytes of padding but say it's only 4.
288   SetPadding(5, 4);
289 
290   ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
291   EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code());
292 }
293 
294 // Invalid SSLv2 client hello padding must fail the handshake.
TEST_P(SSLv2ClientHelloTest,AddErroneousPadding2)295 TEST_P(SSLv2ClientHelloTest, AddErroneousPadding2) {
296   SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
297 
298   // Append 5 bytes of padding but say it's 6.
299   SetPadding(5, 6);
300 
301   ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
302   EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code());
303 }
304 
305 // Wrong amount of bytes for the ClientRandom must fail the handshake.
TEST_P(SSLv2ClientHelloTest,SmallClientRandom)306 TEST_P(SSLv2ClientHelloTest, SmallClientRandom) {
307   SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
308 
309   // Send a ClientRandom that's too small.
310   SetClientRandomLength(15);
311 
312   ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
313   EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code());
314 }
315 
316 // Test sending the maximum accepted number of ClientRandom bytes.
TEST_P(SSLv2ClientHelloTest,MaxClientRandom)317 TEST_P(SSLv2ClientHelloTest, MaxClientRandom) {
318   SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
319   SetClientRandomLength(32);
320   Connect();
321 }
322 
323 // Wrong amount of bytes for the ClientRandom must fail the handshake.
TEST_P(SSLv2ClientHelloTest,BigClientRandom)324 TEST_P(SSLv2ClientHelloTest, BigClientRandom) {
325   SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
326 
327   // Send a ClientRandom that's too big.
328   SetClientRandomLength(33);
329 
330   ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
331   EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code());
332 }
333 
334 // Connection must fail if we require safe renegotiation but the client doesn't
335 // include TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the list of cipher suites.
TEST_P(SSLv2ClientHelloTest,RequireSafeRenegotiation)336 TEST_P(SSLv2ClientHelloTest, RequireSafeRenegotiation) {
337   server_->SetOption(SSL_REQUIRE_SAFE_NEGOTIATION, PR_TRUE);
338   SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
339   ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
340   EXPECT_EQ(SSL_ERROR_UNSAFE_NEGOTIATION, server_->error_code());
341 }
342 
343 // Connection must succeed when requiring safe renegotiation and the client
344 // includes TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the list of cipher suites.
TEST_P(SSLv2ClientHelloTest,RequireSafeRenegotiationWithSCSV)345 TEST_P(SSLv2ClientHelloTest, RequireSafeRenegotiationWithSCSV) {
346   server_->SetOption(SSL_REQUIRE_SAFE_NEGOTIATION, PR_TRUE);
347   std::vector<uint16_t> cipher_suites = {TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
348                                          TLS_EMPTY_RENEGOTIATION_INFO_SCSV};
349   SetAvailableCipherSuites(cipher_suites);
350   Connect();
351 }
352 
TEST_P(SSLv2ClientHelloTest,CheckServerRandom)353 TEST_P(SSLv2ClientHelloTest, CheckServerRandom) {
354   ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
355   SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
356 
357   static const size_t random_len = 32;
358   uint8_t srandom1[random_len];
359   uint8_t z[random_len] = {0};
360 
361   auto sh = MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_server_hello);
362   Connect();
363   ASSERT_TRUE(sh->buffer().len() > (random_len + 2));
364   memcpy(srandom1, sh->buffer().data() + 2, random_len);
365   EXPECT_NE(0, memcmp(srandom1, z, random_len));
366 
367   Reset();
368   sh = MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_server_hello);
369   Connect();
370   ASSERT_TRUE(sh->buffer().len() > (random_len + 2));
371   const uint8_t* srandom2 = sh->buffer().data() + 2;
372 
373   EXPECT_NE(0, memcmp(srandom2, z, random_len));
374   EXPECT_NE(0, memcmp(srandom1, srandom2, random_len));
375 }
376 
377 // Connect to the server with TLS 1.1, signalling that this is a fallback from
378 // a higher version. As the server doesn't support anything higher than TLS 1.1
379 // it must accept the connection.
TEST_F(SSLv2ClientHelloTestF,FallbackSCSV)380 TEST_F(SSLv2ClientHelloTestF, FallbackSCSV) {
381   EnsureTlsSetup();
382   SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_1);
383   ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_1);
384 
385   std::vector<uint16_t> cipher_suites = {TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
386                                          TLS_FALLBACK_SCSV};
387   SetAvailableCipherSuites(cipher_suites);
388   Connect();
389 }
390 
391 // Connect to the server with TLS 1.1, signalling that this is a fallback from
392 // a higher version. As the server supports TLS 1.2 though it must reject the
393 // connection due to a possible downgrade attack.
TEST_F(SSLv2ClientHelloTestF,InappropriateFallbackSCSV)394 TEST_F(SSLv2ClientHelloTestF, InappropriateFallbackSCSV) {
395   SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_1);
396   client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
397                            SSL_LIBRARY_VERSION_TLS_1_1);
398   server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
399                            SSL_LIBRARY_VERSION_TLS_1_2);
400 
401   std::vector<uint16_t> cipher_suites = {TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
402                                          TLS_FALLBACK_SCSV};
403   SetAvailableCipherSuites(cipher_suites);
404 
405   ConnectExpectAlert(server_, kTlsAlertInappropriateFallback);
406   EXPECT_EQ(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT, server_->error_code());
407 }
408 
409 INSTANTIATE_TEST_CASE_P(VersionsStream10Pre13, SSLv2ClientHelloTest,
410                         TlsConnectTestBase::kTlsV10);
411 INSTANTIATE_TEST_CASE_P(VersionsStreamPre13, SSLv2ClientHelloTest,
412                         TlsConnectTestBase::kTlsV11V12);
413 
414 }  // namespace nss_test
415