blob: 72f02e88d2c9366810efe9404f5dda8528c3411b [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
2 * Copyright 2011 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11
12#include <algorithm>
13#include <set>
14#include <string>
15
jbauche488a0d2015-11-19 05:17:58 -080016#include "webrtc/base/bufferqueue.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000017#include "webrtc/base/gunit.h"
18#include "webrtc/base/helpers.h"
19#include "webrtc/base/scoped_ptr.h"
20#include "webrtc/base/ssladapter.h"
21#include "webrtc/base/sslconfig.h"
22#include "webrtc/base/sslidentity.h"
23#include "webrtc/base/sslstreamadapter.h"
24#include "webrtc/base/stream.h"
henrike@webrtc.orgfded02c2014-09-19 13:10:10 +000025#include "webrtc/test/testsupport/gtest_disable.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000026
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +020027using ::testing::WithParamInterface;
28using ::testing::Values;
29using ::testing::Combine;
30using ::testing::tuple;
31
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000032static const int kBlockSize = 4096;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000033static const char kExporterLabel[] = "label";
34static const unsigned char kExporterContext[] = "context";
35static int kExporterContextLen = sizeof(kExporterContext);
36
37static const char kRSA_PRIVATE_KEY_PEM[] =
38 "-----BEGIN RSA PRIVATE KEY-----\n"
39 "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMYRkbhmI7kVA/rM\n"
40 "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n"
41 "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n"
42 "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAECgYAvgOs4FJcgvp+TuREx7YtiYVsH\n"
43 "mwQPTum2z/8VzWGwR8BBHBvIpVe1MbD/Y4seyI2aco/7UaisatSgJhsU46/9Y4fq\n"
44 "2TwXH9QANf4at4d9n/R6rzwpAJOpgwZgKvdQjkfrKTtgLV+/dawvpxUYkRH4JZM1\n"
45 "CVGukMfKNrSVH4Ap4QJBAOJmGV1ASPnB4r4nc99at7JuIJmd7fmuVUwUgYi4XgaR\n"
46 "WhScBsgYwZ/JoywdyZJgnbcrTDuVcWG56B3vXbhdpMsCQQDf9zeJrjnPZ3Cqm79y\n"
47 "kdqANep0uwZciiNiWxsQrCHztywOvbFhdp8iYVFG9EK8DMY41Y5TxUwsHD+67zao\n"
48 "ZNqJAkEA1suLUP/GvL8IwuRneQd2tWDqqRQ/Td3qq03hP7e77XtF/buya3Ghclo5\n"
49 "54czUR89QyVfJEC6278nzA7n2h1uVQJAcG6mztNL6ja/dKZjYZye2CY44QjSlLo0\n"
50 "MTgTSjdfg/28fFn2Jjtqf9Pi/X+50LWI/RcYMC2no606wRk9kyOuIQJBAK6VSAim\n"
51 "1pOEjsYQn0X5KEIrz1G3bfCbB848Ime3U2/FWlCHMr6ch8kCZ5d1WUeJD3LbwMNG\n"
52 "UCXiYxSsu20QNVw=\n"
53 "-----END RSA PRIVATE KEY-----\n";
54
55static const char kCERT_PEM[] =
56 "-----BEGIN CERTIFICATE-----\n"
57 "MIIBmTCCAQKgAwIBAgIEbzBSAjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDEwZX\n"
58 "ZWJSVEMwHhcNMTQwMTAyMTgyNDQ3WhcNMTQwMjAxMTgyNDQ3WjARMQ8wDQYDVQQD\n"
59 "EwZXZWJSVEMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYRkbhmI7kVA/rM\n"
60 "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n"
61 "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n"
62 "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAEwDQYJKoZIhvcNAQELBQADgYEAUflI\n"
63 "VUe5Krqf5RVa5C3u/UTAOAUJBiDS3VANTCLBxjuMsvqOG0WvaYWP3HYPgrz0jXK2\n"
64 "LJE/mGw3MyFHEqi81jh95J+ypl6xKW6Rm8jKLR87gUvCaVYn/Z4/P3AqcQTB7wOv\n"
65 "UD0A8qfhfDM+LK6rPAnCsVN0NRDY3jvd6rzix9M=\n"
66 "-----END CERTIFICATE-----\n";
67
68#define MAYBE_SKIP_TEST(feature) \
69 if (!(rtc::SSLStreamAdapter::feature())) { \
70 LOG(LS_INFO) << "Feature disabled... skipping"; \
71 return; \
72 }
73
74class SSLStreamAdapterTestBase;
75
jbauche488a0d2015-11-19 05:17:58 -080076class SSLDummyStreamBase : public rtc::StreamInterface,
77 public sigslot::has_slots<> {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000078 public:
jbauche488a0d2015-11-19 05:17:58 -080079 SSLDummyStreamBase(SSLStreamAdapterTestBase* test,
80 const std::string &side,
81 rtc::StreamInterface* in,
82 rtc::StreamInterface* out) :
83 test_base_(test),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000084 side_(side),
85 in_(in),
86 out_(out),
87 first_packet_(true) {
jbauche488a0d2015-11-19 05:17:58 -080088 in_->SignalEvent.connect(this, &SSLDummyStreamBase::OnEventIn);
89 out_->SignalEvent.connect(this, &SSLDummyStreamBase::OnEventOut);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000090 }
91
jbauche488a0d2015-11-19 05:17:58 -080092 rtc::StreamState GetState() const override { return rtc::SS_OPEN; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000093
jbauche488a0d2015-11-19 05:17:58 -080094 rtc::StreamResult Read(void* buffer, size_t buffer_len,
95 size_t* read, int* error) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000096 rtc::StreamResult r;
97
98 r = in_->Read(buffer, buffer_len, read, error);
99 if (r == rtc::SR_BLOCK)
100 return rtc::SR_BLOCK;
101 if (r == rtc::SR_EOS)
102 return rtc::SR_EOS;
103
104 if (r != rtc::SR_SUCCESS) {
105 ADD_FAILURE();
106 return rtc::SR_ERROR;
107 }
108
109 return rtc::SR_SUCCESS;
110 }
111
112 // Catch readability events on in and pass them up.
jbauche488a0d2015-11-19 05:17:58 -0800113 void OnEventIn(rtc::StreamInterface* stream, int sig, int err) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000114 int mask = (rtc::SE_READ | rtc::SE_CLOSE);
115
116 if (sig & mask) {
jbauche488a0d2015-11-19 05:17:58 -0800117 LOG(LS_INFO) << "SSLDummyStreamBase::OnEvent side=" << side_ << " sig="
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000118 << sig << " forwarding upward";
119 PostEvent(sig & mask, 0);
120 }
121 }
122
123 // Catch writeability events on out and pass them up.
jbauche488a0d2015-11-19 05:17:58 -0800124 void OnEventOut(rtc::StreamInterface* stream, int sig, int err) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000125 if (sig & rtc::SE_WRITE) {
jbauche488a0d2015-11-19 05:17:58 -0800126 LOG(LS_INFO) << "SSLDummyStreamBase::OnEvent side=" << side_ << " sig="
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000127 << sig << " forwarding upward";
128
129 PostEvent(sig & rtc::SE_WRITE, 0);
130 }
131 }
132
133 // Write to the outgoing FifoBuffer
134 rtc::StreamResult WriteData(const void* data, size_t data_len,
jbauche488a0d2015-11-19 05:17:58 -0800135 size_t* written, int* error) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000136 return out_->Write(data, data_len, written, error);
137 }
138
jbauche488a0d2015-11-19 05:17:58 -0800139 rtc::StreamResult Write(const void* data, size_t data_len,
140 size_t* written, int* error) override;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000141
jbauche488a0d2015-11-19 05:17:58 -0800142 void Close() override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000143 LOG(LS_INFO) << "Closing outbound stream";
144 out_->Close();
145 }
146
jbauche488a0d2015-11-19 05:17:58 -0800147 protected:
148 SSLStreamAdapterTestBase* test_base_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000149 const std::string side_;
jbauche488a0d2015-11-19 05:17:58 -0800150 rtc::StreamInterface* in_;
151 rtc::StreamInterface* out_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000152 bool first_packet_;
153};
154
jbauche488a0d2015-11-19 05:17:58 -0800155class SSLDummyStreamTLS : public SSLDummyStreamBase {
156 public:
157 SSLDummyStreamTLS(SSLStreamAdapterTestBase* test,
158 const std::string& side,
159 rtc::FifoBuffer* in,
160 rtc::FifoBuffer* out) :
161 SSLDummyStreamBase(test, side, in, out) {
162 }
163};
164
165class BufferQueueStream : public rtc::BufferQueue,
166 public rtc::StreamInterface {
167 public:
168 BufferQueueStream(size_t capacity, size_t default_size)
169 : rtc::BufferQueue(capacity, default_size) {
170 }
171
172 // Implementation of abstract StreamInterface methods.
173
174 // A buffer queue stream is always "open".
175 rtc::StreamState GetState() const override { return rtc::SS_OPEN; }
176
177 // Reading a buffer queue stream will either succeed or block.
178 rtc::StreamResult Read(void* buffer, size_t buffer_len,
179 size_t* read, int* error) override {
180 if (!ReadFront(buffer, buffer_len, read)) {
181 return rtc::SR_BLOCK;
182 }
183 return rtc::SR_SUCCESS;
184 }
185
186 // Writing to a buffer queue stream will either succeed or block.
187 rtc::StreamResult Write(const void* data, size_t data_len,
188 size_t* written, int* error) override {
189 if (!WriteBack(data, data_len, written)) {
190 return rtc::SR_BLOCK;
191 }
192 return rtc::SR_SUCCESS;
193 }
194
195 // A buffer queue stream can not be closed.
196 void Close() override {}
197
198 protected:
199 void NotifyReadableForTest() override {
200 PostEvent(rtc::SE_READ, 0);
201 }
202
203 void NotifyWritableForTest() override {
204 PostEvent(rtc::SE_WRITE, 0);
205 }
206};
207
208class SSLDummyStreamDTLS : public SSLDummyStreamBase {
209 public:
210 SSLDummyStreamDTLS(SSLStreamAdapterTestBase* test,
211 const std::string& side,
212 BufferQueueStream* in,
213 BufferQueueStream* out) :
214 SSLDummyStreamBase(test, side, in, out) {
215 }
216};
217
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000218static const int kFifoBufferSize = 4096;
jbauche488a0d2015-11-19 05:17:58 -0800219static const int kBufferCapacity = 1;
220static const size_t kDefaultBufferSize = 2048;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000221
222class SSLStreamAdapterTestBase : public testing::Test,
223 public sigslot::has_slots<> {
224 public:
torbjorng4e572472015-10-08 09:42:49 -0700225 SSLStreamAdapterTestBase(
226 const std::string& client_cert_pem,
227 const std::string& client_private_key_pem,
228 bool dtls,
229 rtc::KeyParams client_key_type = rtc::KeyParams(rtc::KT_DEFAULT),
230 rtc::KeyParams server_key_type = rtc::KeyParams(rtc::KT_DEFAULT))
jbauche488a0d2015-11-19 05:17:58 -0800231 : client_cert_pem_(client_cert_pem),
232 client_private_key_pem_(client_private_key_pem),
233 client_key_type_(client_key_type),
234 server_key_type_(server_key_type),
235 client_stream_(NULL),
236 server_stream_(NULL),
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200237 client_identity_(NULL),
238 server_identity_(NULL),
239 delay_(0),
240 mtu_(1460),
241 loss_(0),
242 lose_first_packet_(false),
243 damage_(false),
244 dtls_(dtls),
245 handshake_wait_(5000),
246 identities_set_(false) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000247 // Set use of the test RNG to get predictable loss patterns.
248 rtc::SetRandomTestMode(true);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000249 }
250
251 ~SSLStreamAdapterTestBase() {
252 // Put it back for the next test.
253 rtc::SetRandomTestMode(false);
254 }
255
torbjorng7593aad2015-11-19 12:20:51 -0800256 void SetUp() override {
jbauche488a0d2015-11-19 05:17:58 -0800257 CreateStreams();
258
259 client_ssl_.reset(rtc::SSLStreamAdapter::Create(client_stream_));
260 server_ssl_.reset(rtc::SSLStreamAdapter::Create(server_stream_));
261
262 // Set up the slots
263 client_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
264 server_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
265
266 if (!client_cert_pem_.empty() && !client_private_key_pem_.empty()) {
267 client_identity_ = rtc::SSLIdentity::FromPEMStrings(
268 client_private_key_pem_, client_cert_pem_);
269 } else {
270 client_identity_ = rtc::SSLIdentity::Generate("client", client_key_type_);
271 }
272 server_identity_ = rtc::SSLIdentity::Generate("server", server_key_type_);
273
274 client_ssl_->SetIdentity(client_identity_);
275 server_ssl_->SetIdentity(server_identity_);
276 }
277
torbjorng7593aad2015-11-19 12:20:51 -0800278 void TearDown() override {
jbauche488a0d2015-11-19 05:17:58 -0800279 client_ssl_.reset(nullptr);
280 server_ssl_.reset(nullptr);
281 }
282
283 virtual void CreateStreams() = 0;
284
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000285 // Recreate the client/server identities with the specified validity period.
286 // |not_before| and |not_after| are offsets from the current time in number
287 // of seconds.
288 void ResetIdentitiesWithValidity(int not_before, int not_after) {
jbauche488a0d2015-11-19 05:17:58 -0800289 CreateStreams();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000290
291 client_ssl_.reset(rtc::SSLStreamAdapter::Create(client_stream_));
292 server_ssl_.reset(rtc::SSLStreamAdapter::Create(server_stream_));
293
294 client_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
295 server_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
296
Torbjorn Granlund46c9cc02015-12-01 13:06:34 +0100297 time_t now = time(nullptr);
298
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000299 rtc::SSLIdentityParams client_params;
torbjorng4e572472015-10-08 09:42:49 -0700300 client_params.key_params = rtc::KeyParams(rtc::KT_DEFAULT);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000301 client_params.common_name = "client";
Torbjorn Granlund46c9cc02015-12-01 13:06:34 +0100302 client_params.not_before = now + not_before;
303 client_params.not_after = now + not_after;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000304 client_identity_ = rtc::SSLIdentity::GenerateForTest(client_params);
305
306 rtc::SSLIdentityParams server_params;
torbjorng4e572472015-10-08 09:42:49 -0700307 server_params.key_params = rtc::KeyParams(rtc::KT_DEFAULT);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000308 server_params.common_name = "server";
Torbjorn Granlund46c9cc02015-12-01 13:06:34 +0100309 server_params.not_before = now + not_before;
310 server_params.not_after = now + not_after;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000311 server_identity_ = rtc::SSLIdentity::GenerateForTest(server_params);
312
313 client_ssl_->SetIdentity(client_identity_);
314 server_ssl_->SetIdentity(server_identity_);
315 }
316
317 virtual void OnEvent(rtc::StreamInterface *stream, int sig, int err) {
318 LOG(LS_INFO) << "SSLStreamAdapterTestBase::OnEvent sig=" << sig;
319
320 if (sig & rtc::SE_READ) {
321 ReadData(stream);
322 }
323
324 if ((stream == client_ssl_.get()) && (sig & rtc::SE_WRITE)) {
325 WriteData();
326 }
327 }
328
329 void SetPeerIdentitiesByDigest(bool correct) {
330 unsigned char digest[20];
331 size_t digest_len;
332 bool rv;
333
334 LOG(LS_INFO) << "Setting peer identities by digest";
335
336 rv = server_identity_->certificate().ComputeDigest(rtc::DIGEST_SHA_1,
337 digest, 20,
338 &digest_len);
339 ASSERT_TRUE(rv);
340 if (!correct) {
341 LOG(LS_INFO) << "Setting bogus digest for server cert";
342 digest[0]++;
343 }
344 rv = client_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, digest,
345 digest_len);
346 ASSERT_TRUE(rv);
347
348
349 rv = client_identity_->certificate().ComputeDigest(rtc::DIGEST_SHA_1,
350 digest, 20, &digest_len);
351 ASSERT_TRUE(rv);
352 if (!correct) {
353 LOG(LS_INFO) << "Setting bogus digest for client cert";
354 digest[0]++;
355 }
356 rv = server_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, digest,
357 digest_len);
358 ASSERT_TRUE(rv);
359
360 identities_set_ = true;
361 }
362
Joachim Bauch831c5582015-05-20 12:48:41 +0200363 void SetupProtocolVersions(rtc::SSLProtocolVersion server_version,
364 rtc::SSLProtocolVersion client_version) {
365 server_ssl_->SetMaxProtocolVersion(server_version);
366 client_ssl_->SetMaxProtocolVersion(client_version);
367 }
368
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000369 void TestHandshake(bool expect_success = true) {
370 server_ssl_->SetMode(dtls_ ? rtc::SSL_MODE_DTLS :
371 rtc::SSL_MODE_TLS);
372 client_ssl_->SetMode(dtls_ ? rtc::SSL_MODE_DTLS :
373 rtc::SSL_MODE_TLS);
374
375 if (!dtls_) {
376 // Make sure we simulate a reliable network for TLS.
377 // This is just a check to make sure that people don't write wrong
378 // tests.
379 ASSERT((mtu_ == 1460) && (loss_ == 0) && (lose_first_packet_ == 0));
380 }
381
382 if (!identities_set_)
383 SetPeerIdentitiesByDigest(true);
384
385 // Start the handshake
386 int rv;
387
388 server_ssl_->SetServerRole();
389 rv = server_ssl_->StartSSLWithPeer();
390 ASSERT_EQ(0, rv);
391
392 rv = client_ssl_->StartSSLWithPeer();
393 ASSERT_EQ(0, rv);
394
395 // Now run the handshake
396 if (expect_success) {
397 EXPECT_TRUE_WAIT((client_ssl_->GetState() == rtc::SS_OPEN)
398 && (server_ssl_->GetState() == rtc::SS_OPEN),
399 handshake_wait_);
400 } else {
401 EXPECT_TRUE_WAIT(client_ssl_->GetState() == rtc::SS_CLOSED,
402 handshake_wait_);
403 }
404 }
405
jbauche488a0d2015-11-19 05:17:58 -0800406 rtc::StreamResult DataWritten(SSLDummyStreamBase *from, const void *data,
407 size_t data_len, size_t *written,
408 int *error) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000409 // Randomly drop loss_ percent of packets
Peter Boström0c4e06b2015-10-07 12:23:21 +0200410 if (rtc::CreateRandomId() % 100 < static_cast<uint32_t>(loss_)) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000411 LOG(LS_INFO) << "Randomly dropping packet, size=" << data_len;
412 *written = data_len;
413 return rtc::SR_SUCCESS;
414 }
415 if (dtls_ && (data_len > mtu_)) {
416 LOG(LS_INFO) << "Dropping packet > mtu, size=" << data_len;
417 *written = data_len;
418 return rtc::SR_SUCCESS;
419 }
420
421 // Optionally damage application data (type 23). Note that we don't damage
422 // handshake packets and we damage the last byte to keep the header
423 // intact but break the MAC.
424 if (damage_ && (*static_cast<const unsigned char *>(data) == 23)) {
425 std::vector<char> buf(data_len);
426
427 LOG(LS_INFO) << "Damaging packet";
428
429 memcpy(&buf[0], data, data_len);
430 buf[data_len - 1]++;
431
432 return from->WriteData(&buf[0], data_len, written, error);
433 }
434
435 return from->WriteData(data, data_len, written, error);
436 }
437
438 void SetDelay(int delay) {
439 delay_ = delay;
440 }
441 int GetDelay() { return delay_; }
442
443 void SetLoseFirstPacket(bool lose) {
444 lose_first_packet_ = lose;
445 }
446 bool GetLoseFirstPacket() { return lose_first_packet_; }
447
448 void SetLoss(int percent) {
449 loss_ = percent;
450 }
451
452 void SetDamage() {
453 damage_ = true;
454 }
455
456 void SetMtu(size_t mtu) {
457 mtu_ = mtu;
458 }
459
460 void SetHandshakeWait(int wait) {
461 handshake_wait_ = wait;
462 }
463
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800464 void SetDtlsSrtpCryptoSuites(const std::vector<int>& ciphers, bool client) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000465 if (client)
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800466 client_ssl_->SetDtlsSrtpCryptoSuites(ciphers);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000467 else
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800468 server_ssl_->SetDtlsSrtpCryptoSuites(ciphers);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000469 }
470
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800471 bool GetDtlsSrtpCryptoSuite(bool client, int* retval) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000472 if (client)
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800473 return client_ssl_->GetDtlsSrtpCryptoSuite(retval);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000474 else
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800475 return server_ssl_->GetDtlsSrtpCryptoSuite(retval);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000476 }
477
478 bool GetPeerCertificate(bool client, rtc::SSLCertificate** cert) {
479 if (client)
480 return client_ssl_->GetPeerCertificate(cert);
481 else
482 return server_ssl_->GetPeerCertificate(cert);
483 }
484
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -0700485 bool GetSslCipherSuite(bool client, int* retval) {
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000486 if (client)
Guo-wei Shieh456696a2015-09-30 21:48:54 -0700487 return client_ssl_->GetSslCipherSuite(retval);
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000488 else
Guo-wei Shieh456696a2015-09-30 21:48:54 -0700489 return server_ssl_->GetSslCipherSuite(retval);
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000490 }
491
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000492 bool ExportKeyingMaterial(const char *label,
493 const unsigned char *context,
494 size_t context_len,
495 bool use_context,
496 bool client,
497 unsigned char *result,
498 size_t result_len) {
499 if (client)
500 return client_ssl_->ExportKeyingMaterial(label,
501 context, context_len,
502 use_context,
503 result, result_len);
504 else
505 return server_ssl_->ExportKeyingMaterial(label,
506 context, context_len,
507 use_context,
508 result, result_len);
509 }
510
511 // To be implemented by subclasses.
512 virtual void WriteData() = 0;
513 virtual void ReadData(rtc::StreamInterface *stream) = 0;
514 virtual void TestTransfer(int size) = 0;
515
516 protected:
jbauche488a0d2015-11-19 05:17:58 -0800517 std::string client_cert_pem_;
518 std::string client_private_key_pem_;
519 rtc::KeyParams client_key_type_;
520 rtc::KeyParams server_key_type_;
521 SSLDummyStreamBase *client_stream_; // freed by client_ssl_ destructor
522 SSLDummyStreamBase *server_stream_; // freed by server_ssl_ destructor
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000523 rtc::scoped_ptr<rtc::SSLStreamAdapter> client_ssl_;
524 rtc::scoped_ptr<rtc::SSLStreamAdapter> server_ssl_;
525 rtc::SSLIdentity *client_identity_; // freed by client_ssl_ destructor
526 rtc::SSLIdentity *server_identity_; // freed by server_ssl_ destructor
527 int delay_;
528 size_t mtu_;
529 int loss_;
530 bool lose_first_packet_;
531 bool damage_;
532 bool dtls_;
533 int handshake_wait_;
534 bool identities_set_;
535};
536
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200537class SSLStreamAdapterTestTLS
538 : public SSLStreamAdapterTestBase,
torbjorng4e572472015-10-08 09:42:49 -0700539 public WithParamInterface<tuple<rtc::KeyParams, rtc::KeyParams>> {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000540 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200541 SSLStreamAdapterTestTLS()
542 : SSLStreamAdapterTestBase("",
543 "",
544 false,
545 ::testing::get<0>(GetParam()),
jbauche488a0d2015-11-19 05:17:58 -0800546 ::testing::get<1>(GetParam())),
547 client_buffer_(kFifoBufferSize),
548 server_buffer_(kFifoBufferSize) {
549 }
550
torbjorng7593aad2015-11-19 12:20:51 -0800551 void CreateStreams() override {
jbauche488a0d2015-11-19 05:17:58 -0800552 client_stream_ =
553 new SSLDummyStreamTLS(this, "c2s", &client_buffer_, &server_buffer_);
554 server_stream_ =
555 new SSLDummyStreamTLS(this, "s2c", &server_buffer_, &client_buffer_);
556 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000557
558 // Test data transfer for TLS
559 virtual void TestTransfer(int size) {
560 LOG(LS_INFO) << "Starting transfer test with " << size << " bytes";
561 // Create some dummy data to send.
562 size_t received;
563
564 send_stream_.ReserveSize(size);
565 for (int i = 0; i < size; ++i) {
566 char ch = static_cast<char>(i);
567 send_stream_.Write(&ch, 1, NULL, NULL);
568 }
569 send_stream_.Rewind();
570
571 // Prepare the receive stream.
572 recv_stream_.ReserveSize(size);
573
574 // Start sending
575 WriteData();
576
577 // Wait for the client to close
578 EXPECT_TRUE_WAIT(server_ssl_->GetState() == rtc::SS_CLOSED, 10000);
579
580 // Now check the data
581 recv_stream_.GetSize(&received);
582
583 EXPECT_EQ(static_cast<size_t>(size), received);
584 EXPECT_EQ(0, memcmp(send_stream_.GetBuffer(),
585 recv_stream_.GetBuffer(), size));
586 }
587
588 void WriteData() {
589 size_t position, tosend, size;
590 rtc::StreamResult rv;
591 size_t sent;
592 char block[kBlockSize];
593
594 send_stream_.GetSize(&size);
595 if (!size)
596 return;
597
598 for (;;) {
599 send_stream_.GetPosition(&position);
600 if (send_stream_.Read(block, sizeof(block), &tosend, NULL) !=
601 rtc::SR_EOS) {
602 rv = client_ssl_->Write(block, tosend, &sent, 0);
603
604 if (rv == rtc::SR_SUCCESS) {
605 send_stream_.SetPosition(position + sent);
606 LOG(LS_VERBOSE) << "Sent: " << position + sent;
607 } else if (rv == rtc::SR_BLOCK) {
608 LOG(LS_VERBOSE) << "Blocked...";
609 send_stream_.SetPosition(position);
610 break;
611 } else {
612 ADD_FAILURE();
613 break;
614 }
615 } else {
616 // Now close
617 LOG(LS_INFO) << "Wrote " << position << " bytes. Closing";
618 client_ssl_->Close();
619 break;
620 }
621 }
622 };
623
624 virtual void ReadData(rtc::StreamInterface *stream) {
625 char buffer[1600];
626 size_t bread;
627 int err2;
628 rtc::StreamResult r;
629
630 for (;;) {
631 r = stream->Read(buffer, sizeof(buffer), &bread, &err2);
632
633 if (r == rtc::SR_ERROR || r == rtc::SR_EOS) {
634 // Unfortunately, errors are the way that the stream adapter
torbjorng7593aad2015-11-19 12:20:51 -0800635 // signals close in OpenSSL.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000636 stream->Close();
637 return;
638 }
639
640 if (r == rtc::SR_BLOCK)
641 break;
642
643 ASSERT_EQ(rtc::SR_SUCCESS, r);
644 LOG(LS_INFO) << "Read " << bread;
645
646 recv_stream_.Write(buffer, bread, NULL, NULL);
647 }
648 }
649
650 private:
jbauche488a0d2015-11-19 05:17:58 -0800651 rtc::FifoBuffer client_buffer_;
652 rtc::FifoBuffer server_buffer_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000653 rtc::MemoryStream send_stream_;
654 rtc::MemoryStream recv_stream_;
655};
656
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200657class SSLStreamAdapterTestDTLS
658 : public SSLStreamAdapterTestBase,
torbjorng4e572472015-10-08 09:42:49 -0700659 public WithParamInterface<tuple<rtc::KeyParams, rtc::KeyParams>> {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000660 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200661 SSLStreamAdapterTestDTLS()
662 : SSLStreamAdapterTestBase("",
663 "",
664 true,
665 ::testing::get<0>(GetParam()),
666 ::testing::get<1>(GetParam())),
jbauche488a0d2015-11-19 05:17:58 -0800667 client_buffer_(kBufferCapacity, kDefaultBufferSize),
668 server_buffer_(kBufferCapacity, kDefaultBufferSize),
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200669 packet_size_(1000),
670 count_(0),
671 sent_(0) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000672
673 SSLStreamAdapterTestDTLS(const std::string& cert_pem,
674 const std::string& private_key_pem) :
675 SSLStreamAdapterTestBase(cert_pem, private_key_pem, true),
jbauche488a0d2015-11-19 05:17:58 -0800676 client_buffer_(kBufferCapacity, kDefaultBufferSize),
677 server_buffer_(kBufferCapacity, kDefaultBufferSize),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000678 packet_size_(1000), count_(0), sent_(0) {
679 }
680
torbjorng7593aad2015-11-19 12:20:51 -0800681 void CreateStreams() override {
jbauche488a0d2015-11-19 05:17:58 -0800682 client_stream_ =
683 new SSLDummyStreamDTLS(this, "c2s", &client_buffer_, &server_buffer_);
684 server_stream_ =
685 new SSLDummyStreamDTLS(this, "s2c", &server_buffer_, &client_buffer_);
686 }
687
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000688 virtual void WriteData() {
689 unsigned char *packet = new unsigned char[1600];
690
jbauche488a0d2015-11-19 05:17:58 -0800691 while (sent_ < count_) {
torbjorng7593aad2015-11-19 12:20:51 -0800692 unsigned int rand_state = sent_;
693 packet[0] = sent_;
694 for (size_t i = 1; i < packet_size_; i++) {
695 // This is a simple LC PRNG. Keep in synch with identical code below.
696 rand_state = (rand_state * 251 + 19937) >> 7;
697 packet[i] = rand_state & 0xff;
698 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000699
700 size_t sent;
torbjorng7593aad2015-11-19 12:20:51 -0800701 rtc::StreamResult rv = client_ssl_->Write(packet, packet_size_, &sent, 0);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000702 if (rv == rtc::SR_SUCCESS) {
703 LOG(LS_VERBOSE) << "Sent: " << sent_;
704 sent_++;
705 } else if (rv == rtc::SR_BLOCK) {
706 LOG(LS_VERBOSE) << "Blocked...";
707 break;
708 } else {
709 ADD_FAILURE();
710 break;
711 }
jbauche488a0d2015-11-19 05:17:58 -0800712 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000713
714 delete [] packet;
715 }
716
717 virtual void ReadData(rtc::StreamInterface *stream) {
718 unsigned char buffer[2000];
719 size_t bread;
720 int err2;
721 rtc::StreamResult r;
722
723 for (;;) {
724 r = stream->Read(buffer, 2000, &bread, &err2);
725
726 if (r == rtc::SR_ERROR) {
727 // Unfortunately, errors are the way that the stream adapter
728 // signals close right now
729 stream->Close();
730 return;
731 }
732
733 if (r == rtc::SR_BLOCK)
734 break;
735
736 ASSERT_EQ(rtc::SR_SUCCESS, r);
737 LOG(LS_INFO) << "Read " << bread;
738
739 // Now parse the datagram
740 ASSERT_EQ(packet_size_, bread);
torbjorng7593aad2015-11-19 12:20:51 -0800741 unsigned char packet_num = buffer[0];
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000742
torbjorng7593aad2015-11-19 12:20:51 -0800743 unsigned int rand_state = packet_num;
744 for (size_t i = 1; i < packet_size_; i++) {
745 // This is a simple LC PRNG. Keep in synch with identical code above.
746 rand_state = (rand_state * 251 + 19937) >> 7;
747 ASSERT_EQ(rand_state & 0xff, buffer[i]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000748 }
749 received_.insert(packet_num);
750 }
751 }
752
753 virtual void TestTransfer(int count) {
754 count_ = count;
755
756 WriteData();
757
758 EXPECT_TRUE_WAIT(sent_ == count_, 10000);
759 LOG(LS_INFO) << "sent_ == " << sent_;
760
761 if (damage_) {
762 WAIT(false, 2000);
763 EXPECT_EQ(0U, received_.size());
764 } else if (loss_ == 0) {
765 EXPECT_EQ_WAIT(static_cast<size_t>(sent_), received_.size(), 1000);
766 } else {
767 LOG(LS_INFO) << "Sent " << sent_ << " packets; received " <<
768 received_.size();
769 }
770 };
771
772 private:
jbauche488a0d2015-11-19 05:17:58 -0800773 BufferQueueStream client_buffer_;
774 BufferQueueStream server_buffer_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000775 size_t packet_size_;
776 int count_;
777 int sent_;
778 std::set<int> received_;
779};
780
781
jbauche488a0d2015-11-19 05:17:58 -0800782rtc::StreamResult SSLDummyStreamBase::Write(const void* data, size_t data_len,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000783 size_t* written, int* error) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000784 LOG(LS_INFO) << "Writing to loopback " << data_len;
785
786 if (first_packet_) {
787 first_packet_ = false;
jbauche488a0d2015-11-19 05:17:58 -0800788 if (test_base_->GetLoseFirstPacket()) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000789 LOG(LS_INFO) << "Losing initial packet of length " << data_len;
torbjorng7593aad2015-11-19 12:20:51 -0800790 *written = data_len; // Fake successful writing also to writer.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000791 return rtc::SR_SUCCESS;
792 }
793 }
794
jbauche488a0d2015-11-19 05:17:58 -0800795 return test_base_->DataWritten(this, data, data_len, written, error);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000796};
797
798class SSLStreamAdapterTestDTLSFromPEMStrings : public SSLStreamAdapterTestDTLS {
799 public:
800 SSLStreamAdapterTestDTLSFromPEMStrings() :
801 SSLStreamAdapterTestDTLS(kCERT_PEM, kRSA_PRIVATE_KEY_PEM) {
802 }
803};
804
805// Basic tests: TLS
806
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000807// Test that we can make a handshake work
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200808TEST_P(SSLStreamAdapterTestTLS, TestTLSConnect) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000809 TestHandshake();
810};
811
jiayl@webrtc.orgf1d751c2014-09-25 16:38:46 +0000812// Test that closing the connection on one side updates the other side.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200813TEST_P(SSLStreamAdapterTestTLS, TestTLSClose) {
jiayl@webrtc.orgf1d751c2014-09-25 16:38:46 +0000814 TestHandshake();
815 client_ssl_->Close();
816 EXPECT_EQ_WAIT(rtc::SS_CLOSED, server_ssl_->GetState(), handshake_wait_);
817};
818
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000819// Test transfer -- trivial
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200820TEST_P(SSLStreamAdapterTestTLS, TestTLSTransfer) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000821 TestHandshake();
822 TestTransfer(100000);
823};
824
825// Test read-write after close.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200826TEST_P(SSLStreamAdapterTestTLS, ReadWriteAfterClose) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000827 TestHandshake();
828 TestTransfer(100000);
829 client_ssl_->Close();
830
831 rtc::StreamResult rv;
832 char block[kBlockSize];
833 size_t dummy;
834
835 // It's an error to write after closed.
836 rv = client_ssl_->Write(block, sizeof(block), &dummy, NULL);
837 ASSERT_EQ(rtc::SR_ERROR, rv);
838
839 // But after closed read gives you EOS.
840 rv = client_ssl_->Read(block, sizeof(block), &dummy, NULL);
841 ASSERT_EQ(rtc::SR_EOS, rv);
842};
843
844// Test a handshake with a bogus peer digest
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200845TEST_P(SSLStreamAdapterTestTLS, TestTLSBogusDigest) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000846 SetPeerIdentitiesByDigest(false);
847 TestHandshake(false);
848};
849
850// Test moving a bunch of data
851
852// Basic tests: DTLS
853// Test that we can make a handshake work
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200854TEST_P(SSLStreamAdapterTestDTLS, TestDTLSConnect) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000855 MAYBE_SKIP_TEST(HaveDtls);
856 TestHandshake();
857};
858
859// Test that we can make a handshake work if the first packet in
860// each direction is lost. This gives us predictable loss
861// rather than having to tune random
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200862TEST_P(SSLStreamAdapterTestDTLS, TestDTLSConnectWithLostFirstPacket) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000863 MAYBE_SKIP_TEST(HaveDtls);
864 SetLoseFirstPacket(true);
865 TestHandshake();
866};
867
868// Test a handshake with loss and delay
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200869TEST_P(SSLStreamAdapterTestDTLS, TestDTLSConnectWithLostFirstPacketDelay2s) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000870 MAYBE_SKIP_TEST(HaveDtls);
871 SetLoseFirstPacket(true);
872 SetDelay(2000);
873 SetHandshakeWait(20000);
874 TestHandshake();
875};
876
877// Test a handshake with small MTU
pbos@webrtc.org127ca3f2014-10-09 07:52:03 +0000878// Disabled due to https://code.google.com/p/webrtc/issues/detail?id=3910
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200879TEST_P(SSLStreamAdapterTestDTLS, DISABLED_TestDTLSConnectWithSmallMtu) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000880 MAYBE_SKIP_TEST(HaveDtls);
881 SetMtu(700);
882 SetHandshakeWait(20000);
883 TestHandshake();
884};
885
886// Test transfer -- trivial
jbauche488a0d2015-11-19 05:17:58 -0800887TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransfer) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000888 MAYBE_SKIP_TEST(HaveDtls);
889 TestHandshake();
890 TestTransfer(100);
891};
892
jbauche488a0d2015-11-19 05:17:58 -0800893TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransferWithLoss) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000894 MAYBE_SKIP_TEST(HaveDtls);
895 TestHandshake();
896 SetLoss(10);
897 TestTransfer(100);
898};
899
jbauche488a0d2015-11-19 05:17:58 -0800900TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransferWithDamage) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000901 MAYBE_SKIP_TEST(HaveDtls);
902 SetDamage(); // Must be called first because first packet
903 // write happens at end of handshake.
904 TestHandshake();
905 TestTransfer(100);
906};
907
908// Test DTLS-SRTP with all high ciphers
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200909TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpHigh) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000910 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800911 std::vector<int> high;
912 high.push_back(rtc::SRTP_AES128_CM_SHA1_80);
913 SetDtlsSrtpCryptoSuites(high, true);
914 SetDtlsSrtpCryptoSuites(high, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000915 TestHandshake();
916
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800917 int client_cipher;
918 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
919 int server_cipher;
920 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000921
922 ASSERT_EQ(client_cipher, server_cipher);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800923 ASSERT_EQ(client_cipher, rtc::SRTP_AES128_CM_SHA1_80);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000924};
925
926// Test DTLS-SRTP with all low ciphers
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200927TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpLow) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000928 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800929 std::vector<int> low;
930 low.push_back(rtc::SRTP_AES128_CM_SHA1_32);
931 SetDtlsSrtpCryptoSuites(low, true);
932 SetDtlsSrtpCryptoSuites(low, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000933 TestHandshake();
934
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800935 int client_cipher;
936 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
937 int server_cipher;
938 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000939
940 ASSERT_EQ(client_cipher, server_cipher);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800941 ASSERT_EQ(client_cipher, rtc::SRTP_AES128_CM_SHA1_32);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000942};
943
944
945// Test DTLS-SRTP with a mismatch -- should not converge
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200946TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpHighLow) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000947 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800948 std::vector<int> high;
949 high.push_back(rtc::SRTP_AES128_CM_SHA1_80);
950 std::vector<int> low;
951 low.push_back(rtc::SRTP_AES128_CM_SHA1_32);
952 SetDtlsSrtpCryptoSuites(high, true);
953 SetDtlsSrtpCryptoSuites(low, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000954 TestHandshake();
955
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800956 int client_cipher;
957 ASSERT_FALSE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
958 int server_cipher;
959 ASSERT_FALSE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000960};
961
962// Test DTLS-SRTP with each side being mixed -- should select high
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200963TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpMixed) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000964 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800965 std::vector<int> mixed;
966 mixed.push_back(rtc::SRTP_AES128_CM_SHA1_80);
967 mixed.push_back(rtc::SRTP_AES128_CM_SHA1_32);
968 SetDtlsSrtpCryptoSuites(mixed, true);
969 SetDtlsSrtpCryptoSuites(mixed, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000970 TestHandshake();
971
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800972 int client_cipher;
973 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
974 int server_cipher;
975 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000976
977 ASSERT_EQ(client_cipher, server_cipher);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800978 ASSERT_EQ(client_cipher, rtc::SRTP_AES128_CM_SHA1_80);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000979};
980
981// Test an exporter
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200982TEST_P(SSLStreamAdapterTestDTLS, TestDTLSExporter) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000983 MAYBE_SKIP_TEST(HaveExporter);
984 TestHandshake();
985 unsigned char client_out[20];
986 unsigned char server_out[20];
987
988 bool result;
989 result = ExportKeyingMaterial(kExporterLabel,
990 kExporterContext, kExporterContextLen,
991 true, true,
992 client_out, sizeof(client_out));
993 ASSERT_TRUE(result);
994
995 result = ExportKeyingMaterial(kExporterLabel,
996 kExporterContext, kExporterContextLen,
997 true, false,
998 server_out, sizeof(server_out));
999 ASSERT_TRUE(result);
1000
1001 ASSERT_TRUE(!memcmp(client_out, server_out, sizeof(client_out)));
1002}
1003
1004// Test not yet valid certificates are not rejected.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +02001005TEST_P(SSLStreamAdapterTestDTLS, TestCertNotYetValid) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001006 MAYBE_SKIP_TEST(HaveDtls);
1007 long one_day = 60 * 60 * 24;
1008 // Make the certificates not valid until one day later.
1009 ResetIdentitiesWithValidity(one_day, one_day);
1010 TestHandshake();
1011}
1012
1013// Test expired certificates are not rejected.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +02001014TEST_P(SSLStreamAdapterTestDTLS, TestCertExpired) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001015 MAYBE_SKIP_TEST(HaveDtls);
1016 long one_day = 60 * 60 * 24;
1017 // Make the certificates already expired.
1018 ResetIdentitiesWithValidity(-one_day, -one_day);
1019 TestHandshake();
1020}
1021
1022// Test data transfer using certs created from strings.
torbjorng7593aad2015-11-19 12:20:51 -08001023TEST_F(SSLStreamAdapterTestDTLSFromPEMStrings, TestTransfer) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001024 MAYBE_SKIP_TEST(HaveDtls);
1025 TestHandshake();
1026 TestTransfer(100);
1027}
1028
1029// Test getting the remote certificate.
torbjorng7593aad2015-11-19 12:20:51 -08001030TEST_F(SSLStreamAdapterTestDTLSFromPEMStrings, TestDTLSGetPeerCertificate) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001031 MAYBE_SKIP_TEST(HaveDtls);
1032
1033 // Peer certificates haven't been received yet.
1034 rtc::scoped_ptr<rtc::SSLCertificate> client_peer_cert;
1035 ASSERT_FALSE(GetPeerCertificate(true, client_peer_cert.accept()));
1036 ASSERT_FALSE(client_peer_cert != NULL);
1037
1038 rtc::scoped_ptr<rtc::SSLCertificate> server_peer_cert;
1039 ASSERT_FALSE(GetPeerCertificate(false, server_peer_cert.accept()));
1040 ASSERT_FALSE(server_peer_cert != NULL);
1041
1042 TestHandshake();
1043
1044 // The client should have a peer certificate after the handshake.
1045 ASSERT_TRUE(GetPeerCertificate(true, client_peer_cert.accept()));
1046 ASSERT_TRUE(client_peer_cert != NULL);
1047
1048 // It's not kCERT_PEM.
1049 std::string client_peer_string = client_peer_cert->ToPEMString();
1050 ASSERT_NE(kCERT_PEM, client_peer_string);
1051
1052 // It must not have a chain, because the test certs are self-signed.
1053 rtc::SSLCertChain* client_peer_chain;
1054 ASSERT_FALSE(client_peer_cert->GetChain(&client_peer_chain));
1055
1056 // The server should have a peer certificate after the handshake.
1057 ASSERT_TRUE(GetPeerCertificate(false, server_peer_cert.accept()));
1058 ASSERT_TRUE(server_peer_cert != NULL);
1059
1060 // It's kCERT_PEM
1061 ASSERT_EQ(kCERT_PEM, server_peer_cert->ToPEMString());
1062
1063 // It must not have a chain, because the test certs are self-signed.
1064 rtc::SSLCertChain* server_peer_chain;
1065 ASSERT_FALSE(server_peer_cert->GetChain(&server_peer_chain));
1066}
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001067
1068// Test getting the used DTLS ciphers.
Joachim Bauch831c5582015-05-20 12:48:41 +02001069// DTLS 1.2 enabled for neither client nor server -> DTLS 1.0 will be used.
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001070TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuite) {
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001071 MAYBE_SKIP_TEST(HaveDtls);
Joachim Bauch831c5582015-05-20 12:48:41 +02001072 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10);
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001073 TestHandshake();
1074
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001075 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001076 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001077 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001078 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001079
1080 ASSERT_EQ(client_cipher, server_cipher);
torbjorng4e572472015-10-08 09:42:49 -07001081 ASSERT_EQ(
1082 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
1083 rtc::SSL_PROTOCOL_DTLS_10, ::testing::get<1>(GetParam()).type()),
1084 server_cipher);
Joachim Bauch831c5582015-05-20 12:48:41 +02001085}
1086
1087// Test getting the used DTLS 1.2 ciphers.
1088// DTLS 1.2 enabled for client and server -> DTLS 1.2 will be used.
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001089TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Both) {
Joachim Bauch831c5582015-05-20 12:48:41 +02001090 MAYBE_SKIP_TEST(HaveDtls);
1091 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_12);
1092 TestHandshake();
1093
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001094 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001095 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001096 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001097 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
Joachim Bauch831c5582015-05-20 12:48:41 +02001098
1099 ASSERT_EQ(client_cipher, server_cipher);
torbjorng4e572472015-10-08 09:42:49 -07001100 ASSERT_EQ(
1101 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
1102 rtc::SSL_PROTOCOL_DTLS_12, ::testing::get<1>(GetParam()).type()),
1103 server_cipher);
Joachim Bauch831c5582015-05-20 12:48:41 +02001104}
1105
1106// DTLS 1.2 enabled for client only -> DTLS 1.0 will be used.
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001107TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Client) {
Joachim Bauch831c5582015-05-20 12:48:41 +02001108 MAYBE_SKIP_TEST(HaveDtls);
1109 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_12);
1110 TestHandshake();
1111
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001112 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001113 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001114 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001115 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
Joachim Bauch831c5582015-05-20 12:48:41 +02001116
1117 ASSERT_EQ(client_cipher, server_cipher);
torbjorng4e572472015-10-08 09:42:49 -07001118 ASSERT_EQ(
1119 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
1120 rtc::SSL_PROTOCOL_DTLS_10, ::testing::get<1>(GetParam()).type()),
1121 server_cipher);
Joachim Bauch831c5582015-05-20 12:48:41 +02001122}
1123
1124// DTLS 1.2 enabled for server only -> DTLS 1.0 will be used.
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001125TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Server) {
Joachim Bauch831c5582015-05-20 12:48:41 +02001126 MAYBE_SKIP_TEST(HaveDtls);
1127 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_10);
1128 TestHandshake();
1129
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001130 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001131 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001132 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001133 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
Joachim Bauch831c5582015-05-20 12:48:41 +02001134
1135 ASSERT_EQ(client_cipher, server_cipher);
torbjorng4e572472015-10-08 09:42:49 -07001136 ASSERT_EQ(
1137 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
1138 rtc::SSL_PROTOCOL_DTLS_10, ::testing::get<1>(GetParam()).type()),
1139 server_cipher);
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001140}
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +02001141
torbjorng4e572472015-10-08 09:42:49 -07001142// The RSA keysizes here might look strange, why not include the RFC's size
1143// 2048?. The reason is test case slowness; testing two sizes to exercise
1144// parametrization is sufficient.
1145INSTANTIATE_TEST_CASE_P(
1146 SSLStreamAdapterTestsTLS,
1147 SSLStreamAdapterTestTLS,
1148 Combine(Values(rtc::KeyParams::RSA(1024, 65537),
1149 rtc::KeyParams::RSA(1152, 65537),
1150 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256)),
1151 Values(rtc::KeyParams::RSA(1024, 65537),
1152 rtc::KeyParams::RSA(1152, 65537),
1153 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256))));
kjellander2f042f22015-12-20 12:25:12 -08001154
1155#if !defined(MEMORY_SANITIZER)
1156// Fails under MemorySanitizer:
1157// See https://code.google.com/p/webrtc/issues/detail?id=5381.
torbjorng4e572472015-10-08 09:42:49 -07001158INSTANTIATE_TEST_CASE_P(
1159 SSLStreamAdapterTestsDTLS,
1160 SSLStreamAdapterTestDTLS,
1161 Combine(Values(rtc::KeyParams::RSA(1024, 65537),
1162 rtc::KeyParams::RSA(1152, 65537),
1163 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256)),
1164 Values(rtc::KeyParams::RSA(1024, 65537),
1165 rtc::KeyParams::RSA(1152, 65537),
1166 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256))));
kjellander2f042f22015-12-20 12:25:12 -08001167#endif