blob: 1ed06c3154f761cb3af130a86287bd75084fddb0 [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"
25
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +020026using ::testing::WithParamInterface;
27using ::testing::Values;
28using ::testing::Combine;
29using ::testing::tuple;
30
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000031static const int kBlockSize = 4096;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000032static const char kExporterLabel[] = "label";
33static const unsigned char kExporterContext[] = "context";
34static int kExporterContextLen = sizeof(kExporterContext);
35
36static const char kRSA_PRIVATE_KEY_PEM[] =
37 "-----BEGIN RSA PRIVATE KEY-----\n"
38 "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMYRkbhmI7kVA/rM\n"
39 "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n"
40 "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n"
41 "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAECgYAvgOs4FJcgvp+TuREx7YtiYVsH\n"
42 "mwQPTum2z/8VzWGwR8BBHBvIpVe1MbD/Y4seyI2aco/7UaisatSgJhsU46/9Y4fq\n"
43 "2TwXH9QANf4at4d9n/R6rzwpAJOpgwZgKvdQjkfrKTtgLV+/dawvpxUYkRH4JZM1\n"
44 "CVGukMfKNrSVH4Ap4QJBAOJmGV1ASPnB4r4nc99at7JuIJmd7fmuVUwUgYi4XgaR\n"
45 "WhScBsgYwZ/JoywdyZJgnbcrTDuVcWG56B3vXbhdpMsCQQDf9zeJrjnPZ3Cqm79y\n"
46 "kdqANep0uwZciiNiWxsQrCHztywOvbFhdp8iYVFG9EK8DMY41Y5TxUwsHD+67zao\n"
47 "ZNqJAkEA1suLUP/GvL8IwuRneQd2tWDqqRQ/Td3qq03hP7e77XtF/buya3Ghclo5\n"
48 "54czUR89QyVfJEC6278nzA7n2h1uVQJAcG6mztNL6ja/dKZjYZye2CY44QjSlLo0\n"
49 "MTgTSjdfg/28fFn2Jjtqf9Pi/X+50LWI/RcYMC2no606wRk9kyOuIQJBAK6VSAim\n"
50 "1pOEjsYQn0X5KEIrz1G3bfCbB848Ime3U2/FWlCHMr6ch8kCZ5d1WUeJD3LbwMNG\n"
51 "UCXiYxSsu20QNVw=\n"
52 "-----END RSA PRIVATE KEY-----\n";
53
54static const char kCERT_PEM[] =
55 "-----BEGIN CERTIFICATE-----\n"
56 "MIIBmTCCAQKgAwIBAgIEbzBSAjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDEwZX\n"
57 "ZWJSVEMwHhcNMTQwMTAyMTgyNDQ3WhcNMTQwMjAxMTgyNDQ3WjARMQ8wDQYDVQQD\n"
58 "EwZXZWJSVEMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYRkbhmI7kVA/rM\n"
59 "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n"
60 "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n"
61 "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAEwDQYJKoZIhvcNAQELBQADgYEAUflI\n"
62 "VUe5Krqf5RVa5C3u/UTAOAUJBiDS3VANTCLBxjuMsvqOG0WvaYWP3HYPgrz0jXK2\n"
63 "LJE/mGw3MyFHEqi81jh95J+ypl6xKW6Rm8jKLR87gUvCaVYn/Z4/P3AqcQTB7wOv\n"
64 "UD0A8qfhfDM+LK6rPAnCsVN0NRDY3jvd6rzix9M=\n"
65 "-----END CERTIFICATE-----\n";
66
67#define MAYBE_SKIP_TEST(feature) \
68 if (!(rtc::SSLStreamAdapter::feature())) { \
69 LOG(LS_INFO) << "Feature disabled... skipping"; \
70 return; \
71 }
72
73class SSLStreamAdapterTestBase;
74
jbauche488a0d2015-11-19 05:17:58 -080075class SSLDummyStreamBase : public rtc::StreamInterface,
76 public sigslot::has_slots<> {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000077 public:
jbauche488a0d2015-11-19 05:17:58 -080078 SSLDummyStreamBase(SSLStreamAdapterTestBase* test,
79 const std::string &side,
80 rtc::StreamInterface* in,
81 rtc::StreamInterface* out) :
82 test_base_(test),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000083 side_(side),
84 in_(in),
85 out_(out),
86 first_packet_(true) {
jbauche488a0d2015-11-19 05:17:58 -080087 in_->SignalEvent.connect(this, &SSLDummyStreamBase::OnEventIn);
88 out_->SignalEvent.connect(this, &SSLDummyStreamBase::OnEventOut);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000089 }
90
jbauche488a0d2015-11-19 05:17:58 -080091 rtc::StreamState GetState() const override { return rtc::SS_OPEN; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000092
jbauche488a0d2015-11-19 05:17:58 -080093 rtc::StreamResult Read(void* buffer, size_t buffer_len,
94 size_t* read, int* error) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000095 rtc::StreamResult r;
96
97 r = in_->Read(buffer, buffer_len, read, error);
98 if (r == rtc::SR_BLOCK)
99 return rtc::SR_BLOCK;
100 if (r == rtc::SR_EOS)
101 return rtc::SR_EOS;
102
103 if (r != rtc::SR_SUCCESS) {
104 ADD_FAILURE();
105 return rtc::SR_ERROR;
106 }
107
108 return rtc::SR_SUCCESS;
109 }
110
111 // Catch readability events on in and pass them up.
jbauche488a0d2015-11-19 05:17:58 -0800112 void OnEventIn(rtc::StreamInterface* stream, int sig, int err) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000113 int mask = (rtc::SE_READ | rtc::SE_CLOSE);
114
115 if (sig & mask) {
jbauche488a0d2015-11-19 05:17:58 -0800116 LOG(LS_INFO) << "SSLDummyStreamBase::OnEvent side=" << side_ << " sig="
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000117 << sig << " forwarding upward";
118 PostEvent(sig & mask, 0);
119 }
120 }
121
122 // Catch writeability events on out and pass them up.
jbauche488a0d2015-11-19 05:17:58 -0800123 void OnEventOut(rtc::StreamInterface* stream, int sig, int err) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000124 if (sig & rtc::SE_WRITE) {
jbauche488a0d2015-11-19 05:17:58 -0800125 LOG(LS_INFO) << "SSLDummyStreamBase::OnEvent side=" << side_ << " sig="
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000126 << sig << " forwarding upward";
127
128 PostEvent(sig & rtc::SE_WRITE, 0);
129 }
130 }
131
132 // Write to the outgoing FifoBuffer
133 rtc::StreamResult WriteData(const void* data, size_t data_len,
jbauche488a0d2015-11-19 05:17:58 -0800134 size_t* written, int* error) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000135 return out_->Write(data, data_len, written, error);
136 }
137
jbauche488a0d2015-11-19 05:17:58 -0800138 rtc::StreamResult Write(const void* data, size_t data_len,
139 size_t* written, int* error) override;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000140
jbauche488a0d2015-11-19 05:17:58 -0800141 void Close() override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000142 LOG(LS_INFO) << "Closing outbound stream";
143 out_->Close();
144 }
145
jbauche488a0d2015-11-19 05:17:58 -0800146 protected:
147 SSLStreamAdapterTestBase* test_base_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000148 const std::string side_;
jbauche488a0d2015-11-19 05:17:58 -0800149 rtc::StreamInterface* in_;
150 rtc::StreamInterface* out_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000151 bool first_packet_;
152};
153
jbauche488a0d2015-11-19 05:17:58 -0800154class SSLDummyStreamTLS : public SSLDummyStreamBase {
155 public:
156 SSLDummyStreamTLS(SSLStreamAdapterTestBase* test,
157 const std::string& side,
158 rtc::FifoBuffer* in,
159 rtc::FifoBuffer* out) :
160 SSLDummyStreamBase(test, side, in, out) {
161 }
162};
163
164class BufferQueueStream : public rtc::BufferQueue,
165 public rtc::StreamInterface {
166 public:
167 BufferQueueStream(size_t capacity, size_t default_size)
168 : rtc::BufferQueue(capacity, default_size) {
169 }
170
171 // Implementation of abstract StreamInterface methods.
172
173 // A buffer queue stream is always "open".
174 rtc::StreamState GetState() const override { return rtc::SS_OPEN; }
175
176 // Reading a buffer queue stream will either succeed or block.
177 rtc::StreamResult Read(void* buffer, size_t buffer_len,
178 size_t* read, int* error) override {
179 if (!ReadFront(buffer, buffer_len, read)) {
180 return rtc::SR_BLOCK;
181 }
182 return rtc::SR_SUCCESS;
183 }
184
185 // Writing to a buffer queue stream will either succeed or block.
186 rtc::StreamResult Write(const void* data, size_t data_len,
187 size_t* written, int* error) override {
188 if (!WriteBack(data, data_len, written)) {
189 return rtc::SR_BLOCK;
190 }
191 return rtc::SR_SUCCESS;
192 }
193
194 // A buffer queue stream can not be closed.
195 void Close() override {}
196
197 protected:
198 void NotifyReadableForTest() override {
199 PostEvent(rtc::SE_READ, 0);
200 }
201
202 void NotifyWritableForTest() override {
203 PostEvent(rtc::SE_WRITE, 0);
204 }
205};
206
207class SSLDummyStreamDTLS : public SSLDummyStreamBase {
208 public:
209 SSLDummyStreamDTLS(SSLStreamAdapterTestBase* test,
210 const std::string& side,
211 BufferQueueStream* in,
212 BufferQueueStream* out) :
213 SSLDummyStreamBase(test, side, in, out) {
214 }
215};
216
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000217static const int kFifoBufferSize = 4096;
jbauche488a0d2015-11-19 05:17:58 -0800218static const int kBufferCapacity = 1;
219static const size_t kDefaultBufferSize = 2048;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000220
221class SSLStreamAdapterTestBase : public testing::Test,
222 public sigslot::has_slots<> {
223 public:
torbjorng4e572472015-10-08 09:42:49 -0700224 SSLStreamAdapterTestBase(
225 const std::string& client_cert_pem,
226 const std::string& client_private_key_pem,
227 bool dtls,
228 rtc::KeyParams client_key_type = rtc::KeyParams(rtc::KT_DEFAULT),
229 rtc::KeyParams server_key_type = rtc::KeyParams(rtc::KT_DEFAULT))
jbauche488a0d2015-11-19 05:17:58 -0800230 : client_cert_pem_(client_cert_pem),
231 client_private_key_pem_(client_private_key_pem),
232 client_key_type_(client_key_type),
233 server_key_type_(server_key_type),
234 client_stream_(NULL),
235 server_stream_(NULL),
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200236 client_identity_(NULL),
237 server_identity_(NULL),
238 delay_(0),
239 mtu_(1460),
240 loss_(0),
241 lose_first_packet_(false),
242 damage_(false),
243 dtls_(dtls),
244 handshake_wait_(5000),
245 identities_set_(false) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000246 // Set use of the test RNG to get predictable loss patterns.
247 rtc::SetRandomTestMode(true);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000248 }
249
250 ~SSLStreamAdapterTestBase() {
251 // Put it back for the next test.
252 rtc::SetRandomTestMode(false);
253 }
254
torbjorng7593aad2015-11-19 12:20:51 -0800255 void SetUp() override {
jbauche488a0d2015-11-19 05:17:58 -0800256 CreateStreams();
257
258 client_ssl_.reset(rtc::SSLStreamAdapter::Create(client_stream_));
259 server_ssl_.reset(rtc::SSLStreamAdapter::Create(server_stream_));
260
261 // Set up the slots
262 client_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
263 server_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
264
265 if (!client_cert_pem_.empty() && !client_private_key_pem_.empty()) {
266 client_identity_ = rtc::SSLIdentity::FromPEMStrings(
267 client_private_key_pem_, client_cert_pem_);
268 } else {
269 client_identity_ = rtc::SSLIdentity::Generate("client", client_key_type_);
270 }
271 server_identity_ = rtc::SSLIdentity::Generate("server", server_key_type_);
272
273 client_ssl_->SetIdentity(client_identity_);
274 server_ssl_->SetIdentity(server_identity_);
275 }
276
torbjorng7593aad2015-11-19 12:20:51 -0800277 void TearDown() override {
jbauche488a0d2015-11-19 05:17:58 -0800278 client_ssl_.reset(nullptr);
279 server_ssl_.reset(nullptr);
280 }
281
282 virtual void CreateStreams() = 0;
283
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000284 // Recreate the client/server identities with the specified validity period.
285 // |not_before| and |not_after| are offsets from the current time in number
286 // of seconds.
287 void ResetIdentitiesWithValidity(int not_before, int not_after) {
jbauche488a0d2015-11-19 05:17:58 -0800288 CreateStreams();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000289
290 client_ssl_.reset(rtc::SSLStreamAdapter::Create(client_stream_));
291 server_ssl_.reset(rtc::SSLStreamAdapter::Create(server_stream_));
292
293 client_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
294 server_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
295
Torbjorn Granlund46c9cc02015-12-01 13:06:34 +0100296 time_t now = time(nullptr);
297
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000298 rtc::SSLIdentityParams client_params;
torbjorng4e572472015-10-08 09:42:49 -0700299 client_params.key_params = rtc::KeyParams(rtc::KT_DEFAULT);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000300 client_params.common_name = "client";
Torbjorn Granlund46c9cc02015-12-01 13:06:34 +0100301 client_params.not_before = now + not_before;
302 client_params.not_after = now + not_after;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000303 client_identity_ = rtc::SSLIdentity::GenerateForTest(client_params);
304
305 rtc::SSLIdentityParams server_params;
torbjorng4e572472015-10-08 09:42:49 -0700306 server_params.key_params = rtc::KeyParams(rtc::KT_DEFAULT);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000307 server_params.common_name = "server";
Torbjorn Granlund46c9cc02015-12-01 13:06:34 +0100308 server_params.not_before = now + not_before;
309 server_params.not_after = now + not_after;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000310 server_identity_ = rtc::SSLIdentity::GenerateForTest(server_params);
311
312 client_ssl_->SetIdentity(client_identity_);
313 server_ssl_->SetIdentity(server_identity_);
314 }
315
316 virtual void OnEvent(rtc::StreamInterface *stream, int sig, int err) {
317 LOG(LS_INFO) << "SSLStreamAdapterTestBase::OnEvent sig=" << sig;
318
319 if (sig & rtc::SE_READ) {
320 ReadData(stream);
321 }
322
323 if ((stream == client_ssl_.get()) && (sig & rtc::SE_WRITE)) {
324 WriteData();
325 }
326 }
327
328 void SetPeerIdentitiesByDigest(bool correct) {
329 unsigned char digest[20];
330 size_t digest_len;
331 bool rv;
332
333 LOG(LS_INFO) << "Setting peer identities by digest";
334
335 rv = server_identity_->certificate().ComputeDigest(rtc::DIGEST_SHA_1,
336 digest, 20,
337 &digest_len);
338 ASSERT_TRUE(rv);
339 if (!correct) {
340 LOG(LS_INFO) << "Setting bogus digest for server cert";
341 digest[0]++;
342 }
343 rv = client_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, digest,
344 digest_len);
345 ASSERT_TRUE(rv);
346
347
348 rv = client_identity_->certificate().ComputeDigest(rtc::DIGEST_SHA_1,
349 digest, 20, &digest_len);
350 ASSERT_TRUE(rv);
351 if (!correct) {
352 LOG(LS_INFO) << "Setting bogus digest for client cert";
353 digest[0]++;
354 }
355 rv = server_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, digest,
356 digest_len);
357 ASSERT_TRUE(rv);
358
359 identities_set_ = true;
360 }
361
Joachim Bauch831c5582015-05-20 12:48:41 +0200362 void SetupProtocolVersions(rtc::SSLProtocolVersion server_version,
363 rtc::SSLProtocolVersion client_version) {
364 server_ssl_->SetMaxProtocolVersion(server_version);
365 client_ssl_->SetMaxProtocolVersion(client_version);
366 }
367
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000368 void TestHandshake(bool expect_success = true) {
369 server_ssl_->SetMode(dtls_ ? rtc::SSL_MODE_DTLS :
370 rtc::SSL_MODE_TLS);
371 client_ssl_->SetMode(dtls_ ? rtc::SSL_MODE_DTLS :
372 rtc::SSL_MODE_TLS);
373
374 if (!dtls_) {
375 // Make sure we simulate a reliable network for TLS.
376 // This is just a check to make sure that people don't write wrong
377 // tests.
378 ASSERT((mtu_ == 1460) && (loss_ == 0) && (lose_first_packet_ == 0));
379 }
380
381 if (!identities_set_)
382 SetPeerIdentitiesByDigest(true);
383
384 // Start the handshake
385 int rv;
386
387 server_ssl_->SetServerRole();
388 rv = server_ssl_->StartSSLWithPeer();
389 ASSERT_EQ(0, rv);
390
391 rv = client_ssl_->StartSSLWithPeer();
392 ASSERT_EQ(0, rv);
393
394 // Now run the handshake
395 if (expect_success) {
396 EXPECT_TRUE_WAIT((client_ssl_->GetState() == rtc::SS_OPEN)
397 && (server_ssl_->GetState() == rtc::SS_OPEN),
398 handshake_wait_);
399 } else {
400 EXPECT_TRUE_WAIT(client_ssl_->GetState() == rtc::SS_CLOSED,
401 handshake_wait_);
402 }
403 }
404
jbauche488a0d2015-11-19 05:17:58 -0800405 rtc::StreamResult DataWritten(SSLDummyStreamBase *from, const void *data,
406 size_t data_len, size_t *written,
407 int *error) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000408 // Randomly drop loss_ percent of packets
Peter Boström0c4e06b2015-10-07 12:23:21 +0200409 if (rtc::CreateRandomId() % 100 < static_cast<uint32_t>(loss_)) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000410 LOG(LS_INFO) << "Randomly dropping packet, size=" << data_len;
411 *written = data_len;
412 return rtc::SR_SUCCESS;
413 }
414 if (dtls_ && (data_len > mtu_)) {
415 LOG(LS_INFO) << "Dropping packet > mtu, size=" << data_len;
416 *written = data_len;
417 return rtc::SR_SUCCESS;
418 }
419
420 // Optionally damage application data (type 23). Note that we don't damage
421 // handshake packets and we damage the last byte to keep the header
422 // intact but break the MAC.
423 if (damage_ && (*static_cast<const unsigned char *>(data) == 23)) {
424 std::vector<char> buf(data_len);
425
426 LOG(LS_INFO) << "Damaging packet";
427
428 memcpy(&buf[0], data, data_len);
429 buf[data_len - 1]++;
430
431 return from->WriteData(&buf[0], data_len, written, error);
432 }
433
434 return from->WriteData(data, data_len, written, error);
435 }
436
437 void SetDelay(int delay) {
438 delay_ = delay;
439 }
440 int GetDelay() { return delay_; }
441
442 void SetLoseFirstPacket(bool lose) {
443 lose_first_packet_ = lose;
444 }
445 bool GetLoseFirstPacket() { return lose_first_packet_; }
446
447 void SetLoss(int percent) {
448 loss_ = percent;
449 }
450
451 void SetDamage() {
452 damage_ = true;
453 }
454
455 void SetMtu(size_t mtu) {
456 mtu_ = mtu;
457 }
458
459 void SetHandshakeWait(int wait) {
460 handshake_wait_ = wait;
461 }
462
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800463 void SetDtlsSrtpCryptoSuites(const std::vector<int>& ciphers, bool client) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000464 if (client)
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800465 client_ssl_->SetDtlsSrtpCryptoSuites(ciphers);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000466 else
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800467 server_ssl_->SetDtlsSrtpCryptoSuites(ciphers);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000468 }
469
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800470 bool GetDtlsSrtpCryptoSuite(bool client, int* retval) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000471 if (client)
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800472 return client_ssl_->GetDtlsSrtpCryptoSuite(retval);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000473 else
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800474 return server_ssl_->GetDtlsSrtpCryptoSuite(retval);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000475 }
476
477 bool GetPeerCertificate(bool client, rtc::SSLCertificate** cert) {
478 if (client)
479 return client_ssl_->GetPeerCertificate(cert);
480 else
481 return server_ssl_->GetPeerCertificate(cert);
482 }
483
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -0700484 bool GetSslCipherSuite(bool client, int* retval) {
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000485 if (client)
Guo-wei Shieh456696a2015-09-30 21:48:54 -0700486 return client_ssl_->GetSslCipherSuite(retval);
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000487 else
Guo-wei Shieh456696a2015-09-30 21:48:54 -0700488 return server_ssl_->GetSslCipherSuite(retval);
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000489 }
490
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000491 bool ExportKeyingMaterial(const char *label,
492 const unsigned char *context,
493 size_t context_len,
494 bool use_context,
495 bool client,
496 unsigned char *result,
497 size_t result_len) {
498 if (client)
499 return client_ssl_->ExportKeyingMaterial(label,
500 context, context_len,
501 use_context,
502 result, result_len);
503 else
504 return server_ssl_->ExportKeyingMaterial(label,
505 context, context_len,
506 use_context,
507 result, result_len);
508 }
509
510 // To be implemented by subclasses.
511 virtual void WriteData() = 0;
512 virtual void ReadData(rtc::StreamInterface *stream) = 0;
513 virtual void TestTransfer(int size) = 0;
514
515 protected:
jbauche488a0d2015-11-19 05:17:58 -0800516 std::string client_cert_pem_;
517 std::string client_private_key_pem_;
518 rtc::KeyParams client_key_type_;
519 rtc::KeyParams server_key_type_;
520 SSLDummyStreamBase *client_stream_; // freed by client_ssl_ destructor
521 SSLDummyStreamBase *server_stream_; // freed by server_ssl_ destructor
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000522 rtc::scoped_ptr<rtc::SSLStreamAdapter> client_ssl_;
523 rtc::scoped_ptr<rtc::SSLStreamAdapter> server_ssl_;
524 rtc::SSLIdentity *client_identity_; // freed by client_ssl_ destructor
525 rtc::SSLIdentity *server_identity_; // freed by server_ssl_ destructor
526 int delay_;
527 size_t mtu_;
528 int loss_;
529 bool lose_first_packet_;
530 bool damage_;
531 bool dtls_;
532 int handshake_wait_;
533 bool identities_set_;
534};
535
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200536class SSLStreamAdapterTestTLS
537 : public SSLStreamAdapterTestBase,
torbjorng4e572472015-10-08 09:42:49 -0700538 public WithParamInterface<tuple<rtc::KeyParams, rtc::KeyParams>> {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000539 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200540 SSLStreamAdapterTestTLS()
541 : SSLStreamAdapterTestBase("",
542 "",
543 false,
544 ::testing::get<0>(GetParam()),
jbauche488a0d2015-11-19 05:17:58 -0800545 ::testing::get<1>(GetParam())),
546 client_buffer_(kFifoBufferSize),
547 server_buffer_(kFifoBufferSize) {
548 }
549
torbjorng7593aad2015-11-19 12:20:51 -0800550 void CreateStreams() override {
jbauche488a0d2015-11-19 05:17:58 -0800551 client_stream_ =
552 new SSLDummyStreamTLS(this, "c2s", &client_buffer_, &server_buffer_);
553 server_stream_ =
554 new SSLDummyStreamTLS(this, "s2c", &server_buffer_, &client_buffer_);
555 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000556
557 // Test data transfer for TLS
558 virtual void TestTransfer(int size) {
559 LOG(LS_INFO) << "Starting transfer test with " << size << " bytes";
560 // Create some dummy data to send.
561 size_t received;
562
563 send_stream_.ReserveSize(size);
564 for (int i = 0; i < size; ++i) {
565 char ch = static_cast<char>(i);
566 send_stream_.Write(&ch, 1, NULL, NULL);
567 }
568 send_stream_.Rewind();
569
570 // Prepare the receive stream.
571 recv_stream_.ReserveSize(size);
572
573 // Start sending
574 WriteData();
575
576 // Wait for the client to close
577 EXPECT_TRUE_WAIT(server_ssl_->GetState() == rtc::SS_CLOSED, 10000);
578
579 // Now check the data
580 recv_stream_.GetSize(&received);
581
582 EXPECT_EQ(static_cast<size_t>(size), received);
583 EXPECT_EQ(0, memcmp(send_stream_.GetBuffer(),
584 recv_stream_.GetBuffer(), size));
585 }
586
587 void WriteData() {
588 size_t position, tosend, size;
589 rtc::StreamResult rv;
590 size_t sent;
591 char block[kBlockSize];
592
593 send_stream_.GetSize(&size);
594 if (!size)
595 return;
596
597 for (;;) {
598 send_stream_.GetPosition(&position);
599 if (send_stream_.Read(block, sizeof(block), &tosend, NULL) !=
600 rtc::SR_EOS) {
601 rv = client_ssl_->Write(block, tosend, &sent, 0);
602
603 if (rv == rtc::SR_SUCCESS) {
604 send_stream_.SetPosition(position + sent);
605 LOG(LS_VERBOSE) << "Sent: " << position + sent;
606 } else if (rv == rtc::SR_BLOCK) {
607 LOG(LS_VERBOSE) << "Blocked...";
608 send_stream_.SetPosition(position);
609 break;
610 } else {
611 ADD_FAILURE();
612 break;
613 }
614 } else {
615 // Now close
616 LOG(LS_INFO) << "Wrote " << position << " bytes. Closing";
617 client_ssl_->Close();
618 break;
619 }
620 }
621 };
622
623 virtual void ReadData(rtc::StreamInterface *stream) {
624 char buffer[1600];
625 size_t bread;
626 int err2;
627 rtc::StreamResult r;
628
629 for (;;) {
630 r = stream->Read(buffer, sizeof(buffer), &bread, &err2);
631
632 if (r == rtc::SR_ERROR || r == rtc::SR_EOS) {
633 // Unfortunately, errors are the way that the stream adapter
torbjorng7593aad2015-11-19 12:20:51 -0800634 // signals close in OpenSSL.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000635 stream->Close();
636 return;
637 }
638
639 if (r == rtc::SR_BLOCK)
640 break;
641
642 ASSERT_EQ(rtc::SR_SUCCESS, r);
643 LOG(LS_INFO) << "Read " << bread;
644
645 recv_stream_.Write(buffer, bread, NULL, NULL);
646 }
647 }
648
649 private:
jbauche488a0d2015-11-19 05:17:58 -0800650 rtc::FifoBuffer client_buffer_;
651 rtc::FifoBuffer server_buffer_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000652 rtc::MemoryStream send_stream_;
653 rtc::MemoryStream recv_stream_;
654};
655
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200656class SSLStreamAdapterTestDTLS
657 : public SSLStreamAdapterTestBase,
torbjorng4e572472015-10-08 09:42:49 -0700658 public WithParamInterface<tuple<rtc::KeyParams, rtc::KeyParams>> {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000659 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200660 SSLStreamAdapterTestDTLS()
661 : SSLStreamAdapterTestBase("",
662 "",
663 true,
664 ::testing::get<0>(GetParam()),
665 ::testing::get<1>(GetParam())),
jbauche488a0d2015-11-19 05:17:58 -0800666 client_buffer_(kBufferCapacity, kDefaultBufferSize),
667 server_buffer_(kBufferCapacity, kDefaultBufferSize),
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200668 packet_size_(1000),
669 count_(0),
670 sent_(0) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000671
672 SSLStreamAdapterTestDTLS(const std::string& cert_pem,
673 const std::string& private_key_pem) :
674 SSLStreamAdapterTestBase(cert_pem, private_key_pem, true),
jbauche488a0d2015-11-19 05:17:58 -0800675 client_buffer_(kBufferCapacity, kDefaultBufferSize),
676 server_buffer_(kBufferCapacity, kDefaultBufferSize),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000677 packet_size_(1000), count_(0), sent_(0) {
678 }
679
torbjorng7593aad2015-11-19 12:20:51 -0800680 void CreateStreams() override {
jbauche488a0d2015-11-19 05:17:58 -0800681 client_stream_ =
682 new SSLDummyStreamDTLS(this, "c2s", &client_buffer_, &server_buffer_);
683 server_stream_ =
684 new SSLDummyStreamDTLS(this, "s2c", &server_buffer_, &client_buffer_);
685 }
686
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000687 virtual void WriteData() {
688 unsigned char *packet = new unsigned char[1600];
689
jbauche488a0d2015-11-19 05:17:58 -0800690 while (sent_ < count_) {
torbjorng7593aad2015-11-19 12:20:51 -0800691 unsigned int rand_state = sent_;
692 packet[0] = sent_;
693 for (size_t i = 1; i < packet_size_; i++) {
694 // This is a simple LC PRNG. Keep in synch with identical code below.
695 rand_state = (rand_state * 251 + 19937) >> 7;
696 packet[i] = rand_state & 0xff;
697 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000698
699 size_t sent;
torbjorng7593aad2015-11-19 12:20:51 -0800700 rtc::StreamResult rv = client_ssl_->Write(packet, packet_size_, &sent, 0);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000701 if (rv == rtc::SR_SUCCESS) {
702 LOG(LS_VERBOSE) << "Sent: " << sent_;
703 sent_++;
704 } else if (rv == rtc::SR_BLOCK) {
705 LOG(LS_VERBOSE) << "Blocked...";
706 break;
707 } else {
708 ADD_FAILURE();
709 break;
710 }
jbauche488a0d2015-11-19 05:17:58 -0800711 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000712
713 delete [] packet;
714 }
715
716 virtual void ReadData(rtc::StreamInterface *stream) {
717 unsigned char buffer[2000];
718 size_t bread;
719 int err2;
720 rtc::StreamResult r;
721
722 for (;;) {
723 r = stream->Read(buffer, 2000, &bread, &err2);
724
725 if (r == rtc::SR_ERROR) {
726 // Unfortunately, errors are the way that the stream adapter
727 // signals close right now
728 stream->Close();
729 return;
730 }
731
732 if (r == rtc::SR_BLOCK)
733 break;
734
735 ASSERT_EQ(rtc::SR_SUCCESS, r);
736 LOG(LS_INFO) << "Read " << bread;
737
738 // Now parse the datagram
739 ASSERT_EQ(packet_size_, bread);
torbjorng7593aad2015-11-19 12:20:51 -0800740 unsigned char packet_num = buffer[0];
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000741
torbjorng7593aad2015-11-19 12:20:51 -0800742 unsigned int rand_state = packet_num;
743 for (size_t i = 1; i < packet_size_; i++) {
744 // This is a simple LC PRNG. Keep in synch with identical code above.
745 rand_state = (rand_state * 251 + 19937) >> 7;
746 ASSERT_EQ(rand_state & 0xff, buffer[i]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000747 }
748 received_.insert(packet_num);
749 }
750 }
751
752 virtual void TestTransfer(int count) {
753 count_ = count;
754
755 WriteData();
756
757 EXPECT_TRUE_WAIT(sent_ == count_, 10000);
758 LOG(LS_INFO) << "sent_ == " << sent_;
759
760 if (damage_) {
761 WAIT(false, 2000);
762 EXPECT_EQ(0U, received_.size());
763 } else if (loss_ == 0) {
764 EXPECT_EQ_WAIT(static_cast<size_t>(sent_), received_.size(), 1000);
765 } else {
766 LOG(LS_INFO) << "Sent " << sent_ << " packets; received " <<
767 received_.size();
768 }
769 };
770
771 private:
jbauche488a0d2015-11-19 05:17:58 -0800772 BufferQueueStream client_buffer_;
773 BufferQueueStream server_buffer_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000774 size_t packet_size_;
775 int count_;
776 int sent_;
777 std::set<int> received_;
778};
779
780
jbauche488a0d2015-11-19 05:17:58 -0800781rtc::StreamResult SSLDummyStreamBase::Write(const void* data, size_t data_len,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000782 size_t* written, int* error) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000783 LOG(LS_INFO) << "Writing to loopback " << data_len;
784
785 if (first_packet_) {
786 first_packet_ = false;
jbauche488a0d2015-11-19 05:17:58 -0800787 if (test_base_->GetLoseFirstPacket()) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000788 LOG(LS_INFO) << "Losing initial packet of length " << data_len;
torbjorng7593aad2015-11-19 12:20:51 -0800789 *written = data_len; // Fake successful writing also to writer.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000790 return rtc::SR_SUCCESS;
791 }
792 }
793
jbauche488a0d2015-11-19 05:17:58 -0800794 return test_base_->DataWritten(this, data, data_len, written, error);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000795};
796
797class SSLStreamAdapterTestDTLSFromPEMStrings : public SSLStreamAdapterTestDTLS {
798 public:
799 SSLStreamAdapterTestDTLSFromPEMStrings() :
800 SSLStreamAdapterTestDTLS(kCERT_PEM, kRSA_PRIVATE_KEY_PEM) {
801 }
802};
803
804// Basic tests: TLS
805
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000806// Test that we can make a handshake work
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200807TEST_P(SSLStreamAdapterTestTLS, TestTLSConnect) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000808 TestHandshake();
809};
810
jiayl@webrtc.orgf1d751c2014-09-25 16:38:46 +0000811// Test that closing the connection on one side updates the other side.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200812TEST_P(SSLStreamAdapterTestTLS, TestTLSClose) {
jiayl@webrtc.orgf1d751c2014-09-25 16:38:46 +0000813 TestHandshake();
814 client_ssl_->Close();
815 EXPECT_EQ_WAIT(rtc::SS_CLOSED, server_ssl_->GetState(), handshake_wait_);
816};
817
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000818// Test transfer -- trivial
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200819TEST_P(SSLStreamAdapterTestTLS, TestTLSTransfer) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000820 TestHandshake();
821 TestTransfer(100000);
822};
823
824// Test read-write after close.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200825TEST_P(SSLStreamAdapterTestTLS, ReadWriteAfterClose) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000826 TestHandshake();
827 TestTransfer(100000);
828 client_ssl_->Close();
829
830 rtc::StreamResult rv;
831 char block[kBlockSize];
832 size_t dummy;
833
834 // It's an error to write after closed.
835 rv = client_ssl_->Write(block, sizeof(block), &dummy, NULL);
836 ASSERT_EQ(rtc::SR_ERROR, rv);
837
838 // But after closed read gives you EOS.
839 rv = client_ssl_->Read(block, sizeof(block), &dummy, NULL);
840 ASSERT_EQ(rtc::SR_EOS, rv);
841};
842
843// Test a handshake with a bogus peer digest
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200844TEST_P(SSLStreamAdapterTestTLS, TestTLSBogusDigest) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000845 SetPeerIdentitiesByDigest(false);
846 TestHandshake(false);
847};
848
849// Test moving a bunch of data
850
851// Basic tests: DTLS
852// Test that we can make a handshake work
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200853TEST_P(SSLStreamAdapterTestDTLS, TestDTLSConnect) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000854 MAYBE_SKIP_TEST(HaveDtls);
855 TestHandshake();
856};
857
858// Test that we can make a handshake work if the first packet in
859// each direction is lost. This gives us predictable loss
860// rather than having to tune random
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200861TEST_P(SSLStreamAdapterTestDTLS, TestDTLSConnectWithLostFirstPacket) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000862 MAYBE_SKIP_TEST(HaveDtls);
863 SetLoseFirstPacket(true);
864 TestHandshake();
865};
866
867// Test a handshake with loss and delay
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200868TEST_P(SSLStreamAdapterTestDTLS, TestDTLSConnectWithLostFirstPacketDelay2s) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000869 MAYBE_SKIP_TEST(HaveDtls);
870 SetLoseFirstPacket(true);
871 SetDelay(2000);
872 SetHandshakeWait(20000);
873 TestHandshake();
874};
875
876// Test a handshake with small MTU
pbos@webrtc.org127ca3f2014-10-09 07:52:03 +0000877// Disabled due to https://code.google.com/p/webrtc/issues/detail?id=3910
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200878TEST_P(SSLStreamAdapterTestDTLS, DISABLED_TestDTLSConnectWithSmallMtu) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000879 MAYBE_SKIP_TEST(HaveDtls);
880 SetMtu(700);
881 SetHandshakeWait(20000);
882 TestHandshake();
883};
884
885// Test transfer -- trivial
jbauche488a0d2015-11-19 05:17:58 -0800886TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransfer) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000887 MAYBE_SKIP_TEST(HaveDtls);
888 TestHandshake();
889 TestTransfer(100);
890};
891
jbauche488a0d2015-11-19 05:17:58 -0800892TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransferWithLoss) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000893 MAYBE_SKIP_TEST(HaveDtls);
894 TestHandshake();
895 SetLoss(10);
896 TestTransfer(100);
897};
898
jbauche488a0d2015-11-19 05:17:58 -0800899TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransferWithDamage) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000900 MAYBE_SKIP_TEST(HaveDtls);
901 SetDamage(); // Must be called first because first packet
902 // write happens at end of handshake.
903 TestHandshake();
904 TestTransfer(100);
905};
906
907// Test DTLS-SRTP with all high ciphers
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200908TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpHigh) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000909 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800910 std::vector<int> high;
911 high.push_back(rtc::SRTP_AES128_CM_SHA1_80);
912 SetDtlsSrtpCryptoSuites(high, true);
913 SetDtlsSrtpCryptoSuites(high, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000914 TestHandshake();
915
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800916 int client_cipher;
917 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
918 int server_cipher;
919 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000920
921 ASSERT_EQ(client_cipher, server_cipher);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800922 ASSERT_EQ(client_cipher, rtc::SRTP_AES128_CM_SHA1_80);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000923};
924
925// Test DTLS-SRTP with all low ciphers
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200926TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpLow) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000927 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800928 std::vector<int> low;
929 low.push_back(rtc::SRTP_AES128_CM_SHA1_32);
930 SetDtlsSrtpCryptoSuites(low, true);
931 SetDtlsSrtpCryptoSuites(low, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000932 TestHandshake();
933
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800934 int client_cipher;
935 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
936 int server_cipher;
937 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000938
939 ASSERT_EQ(client_cipher, server_cipher);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800940 ASSERT_EQ(client_cipher, rtc::SRTP_AES128_CM_SHA1_32);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000941};
942
943
944// Test DTLS-SRTP with a mismatch -- should not converge
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200945TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpHighLow) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000946 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800947 std::vector<int> high;
948 high.push_back(rtc::SRTP_AES128_CM_SHA1_80);
949 std::vector<int> low;
950 low.push_back(rtc::SRTP_AES128_CM_SHA1_32);
951 SetDtlsSrtpCryptoSuites(high, true);
952 SetDtlsSrtpCryptoSuites(low, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000953 TestHandshake();
954
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800955 int client_cipher;
956 ASSERT_FALSE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
957 int server_cipher;
958 ASSERT_FALSE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000959};
960
961// Test DTLS-SRTP with each side being mixed -- should select high
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200962TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpMixed) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000963 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800964 std::vector<int> mixed;
965 mixed.push_back(rtc::SRTP_AES128_CM_SHA1_80);
966 mixed.push_back(rtc::SRTP_AES128_CM_SHA1_32);
967 SetDtlsSrtpCryptoSuites(mixed, true);
968 SetDtlsSrtpCryptoSuites(mixed, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000969 TestHandshake();
970
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800971 int client_cipher;
972 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
973 int server_cipher;
974 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000975
976 ASSERT_EQ(client_cipher, server_cipher);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800977 ASSERT_EQ(client_cipher, rtc::SRTP_AES128_CM_SHA1_80);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000978};
979
980// Test an exporter
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200981TEST_P(SSLStreamAdapterTestDTLS, TestDTLSExporter) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000982 MAYBE_SKIP_TEST(HaveExporter);
983 TestHandshake();
984 unsigned char client_out[20];
985 unsigned char server_out[20];
986
987 bool result;
988 result = ExportKeyingMaterial(kExporterLabel,
989 kExporterContext, kExporterContextLen,
990 true, true,
991 client_out, sizeof(client_out));
992 ASSERT_TRUE(result);
993
994 result = ExportKeyingMaterial(kExporterLabel,
995 kExporterContext, kExporterContextLen,
996 true, false,
997 server_out, sizeof(server_out));
998 ASSERT_TRUE(result);
999
1000 ASSERT_TRUE(!memcmp(client_out, server_out, sizeof(client_out)));
1001}
1002
1003// Test not yet valid certificates are not rejected.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +02001004TEST_P(SSLStreamAdapterTestDTLS, TestCertNotYetValid) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001005 MAYBE_SKIP_TEST(HaveDtls);
1006 long one_day = 60 * 60 * 24;
1007 // Make the certificates not valid until one day later.
1008 ResetIdentitiesWithValidity(one_day, one_day);
1009 TestHandshake();
1010}
1011
1012// Test expired certificates are not rejected.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +02001013TEST_P(SSLStreamAdapterTestDTLS, TestCertExpired) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001014 MAYBE_SKIP_TEST(HaveDtls);
1015 long one_day = 60 * 60 * 24;
1016 // Make the certificates already expired.
1017 ResetIdentitiesWithValidity(-one_day, -one_day);
1018 TestHandshake();
1019}
1020
1021// Test data transfer using certs created from strings.
torbjorng7593aad2015-11-19 12:20:51 -08001022TEST_F(SSLStreamAdapterTestDTLSFromPEMStrings, TestTransfer) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001023 MAYBE_SKIP_TEST(HaveDtls);
1024 TestHandshake();
1025 TestTransfer(100);
1026}
1027
1028// Test getting the remote certificate.
torbjorng7593aad2015-11-19 12:20:51 -08001029TEST_F(SSLStreamAdapterTestDTLSFromPEMStrings, TestDTLSGetPeerCertificate) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001030 MAYBE_SKIP_TEST(HaveDtls);
1031
1032 // Peer certificates haven't been received yet.
1033 rtc::scoped_ptr<rtc::SSLCertificate> client_peer_cert;
1034 ASSERT_FALSE(GetPeerCertificate(true, client_peer_cert.accept()));
1035 ASSERT_FALSE(client_peer_cert != NULL);
1036
1037 rtc::scoped_ptr<rtc::SSLCertificate> server_peer_cert;
1038 ASSERT_FALSE(GetPeerCertificate(false, server_peer_cert.accept()));
1039 ASSERT_FALSE(server_peer_cert != NULL);
1040
1041 TestHandshake();
1042
1043 // The client should have a peer certificate after the handshake.
1044 ASSERT_TRUE(GetPeerCertificate(true, client_peer_cert.accept()));
1045 ASSERT_TRUE(client_peer_cert != NULL);
1046
1047 // It's not kCERT_PEM.
1048 std::string client_peer_string = client_peer_cert->ToPEMString();
1049 ASSERT_NE(kCERT_PEM, client_peer_string);
1050
1051 // It must not have a chain, because the test certs are self-signed.
1052 rtc::SSLCertChain* client_peer_chain;
1053 ASSERT_FALSE(client_peer_cert->GetChain(&client_peer_chain));
1054
1055 // The server should have a peer certificate after the handshake.
1056 ASSERT_TRUE(GetPeerCertificate(false, server_peer_cert.accept()));
1057 ASSERT_TRUE(server_peer_cert != NULL);
1058
1059 // It's kCERT_PEM
1060 ASSERT_EQ(kCERT_PEM, server_peer_cert->ToPEMString());
1061
1062 // It must not have a chain, because the test certs are self-signed.
1063 rtc::SSLCertChain* server_peer_chain;
1064 ASSERT_FALSE(server_peer_cert->GetChain(&server_peer_chain));
1065}
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001066
1067// Test getting the used DTLS ciphers.
Joachim Bauch831c5582015-05-20 12:48:41 +02001068// DTLS 1.2 enabled for neither client nor server -> DTLS 1.0 will be used.
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001069TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuite) {
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001070 MAYBE_SKIP_TEST(HaveDtls);
Joachim Bauch831c5582015-05-20 12:48:41 +02001071 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10);
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001072 TestHandshake();
1073
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001074 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001075 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001076 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001077 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001078
1079 ASSERT_EQ(client_cipher, server_cipher);
torbjorng4e572472015-10-08 09:42:49 -07001080 ASSERT_EQ(
1081 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
1082 rtc::SSL_PROTOCOL_DTLS_10, ::testing::get<1>(GetParam()).type()),
1083 server_cipher);
Joachim Bauch831c5582015-05-20 12:48:41 +02001084}
1085
1086// Test getting the used DTLS 1.2 ciphers.
1087// DTLS 1.2 enabled for client and server -> DTLS 1.2 will be used.
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001088TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Both) {
Joachim Bauch831c5582015-05-20 12:48:41 +02001089 MAYBE_SKIP_TEST(HaveDtls);
1090 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_12);
1091 TestHandshake();
1092
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001093 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001094 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001095 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001096 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
Joachim Bauch831c5582015-05-20 12:48:41 +02001097
1098 ASSERT_EQ(client_cipher, server_cipher);
torbjorng4e572472015-10-08 09:42:49 -07001099 ASSERT_EQ(
1100 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
1101 rtc::SSL_PROTOCOL_DTLS_12, ::testing::get<1>(GetParam()).type()),
1102 server_cipher);
Joachim Bauch831c5582015-05-20 12:48:41 +02001103}
1104
1105// DTLS 1.2 enabled for client only -> DTLS 1.0 will be used.
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001106TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Client) {
Joachim Bauch831c5582015-05-20 12:48:41 +02001107 MAYBE_SKIP_TEST(HaveDtls);
1108 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_12);
1109 TestHandshake();
1110
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001111 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001112 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001113 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001114 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
Joachim Bauch831c5582015-05-20 12:48:41 +02001115
1116 ASSERT_EQ(client_cipher, server_cipher);
torbjorng4e572472015-10-08 09:42:49 -07001117 ASSERT_EQ(
1118 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
1119 rtc::SSL_PROTOCOL_DTLS_10, ::testing::get<1>(GetParam()).type()),
1120 server_cipher);
Joachim Bauch831c5582015-05-20 12:48:41 +02001121}
1122
1123// DTLS 1.2 enabled for server only -> DTLS 1.0 will be used.
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001124TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Server) {
Joachim Bauch831c5582015-05-20 12:48:41 +02001125 MAYBE_SKIP_TEST(HaveDtls);
1126 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_10);
1127 TestHandshake();
1128
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001129 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001130 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001131 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001132 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
Joachim Bauch831c5582015-05-20 12:48:41 +02001133
1134 ASSERT_EQ(client_cipher, server_cipher);
torbjorng4e572472015-10-08 09:42:49 -07001135 ASSERT_EQ(
1136 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
1137 rtc::SSL_PROTOCOL_DTLS_10, ::testing::get<1>(GetParam()).type()),
1138 server_cipher);
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001139}
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +02001140
torbjorng4e572472015-10-08 09:42:49 -07001141// The RSA keysizes here might look strange, why not include the RFC's size
1142// 2048?. The reason is test case slowness; testing two sizes to exercise
1143// parametrization is sufficient.
1144INSTANTIATE_TEST_CASE_P(
1145 SSLStreamAdapterTestsTLS,
1146 SSLStreamAdapterTestTLS,
1147 Combine(Values(rtc::KeyParams::RSA(1024, 65537),
1148 rtc::KeyParams::RSA(1152, 65537),
1149 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256)),
1150 Values(rtc::KeyParams::RSA(1024, 65537),
1151 rtc::KeyParams::RSA(1152, 65537),
1152 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256))));
kjellander2f042f22015-12-20 12:25:12 -08001153
1154#if !defined(MEMORY_SANITIZER)
1155// Fails under MemorySanitizer:
1156// See https://code.google.com/p/webrtc/issues/detail?id=5381.
torbjorng4e572472015-10-08 09:42:49 -07001157INSTANTIATE_TEST_CASE_P(
1158 SSLStreamAdapterTestsDTLS,
1159 SSLStreamAdapterTestDTLS,
1160 Combine(Values(rtc::KeyParams::RSA(1024, 65537),
1161 rtc::KeyParams::RSA(1152, 65537),
1162 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256)),
1163 Values(rtc::KeyParams::RSA(1024, 65537),
1164 rtc::KeyParams::RSA(1152, 65537),
1165 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256))));
kjellander2f042f22015-12-20 12:25:12 -08001166#endif