blob: 17bf4b10200d2190185f269fbd7b361a7073212d [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
297 rtc::SSLIdentityParams client_params;
torbjorng4e572472015-10-08 09:42:49 -0700298 client_params.key_params = rtc::KeyParams(rtc::KT_DEFAULT);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000299 client_params.common_name = "client";
300 client_params.not_before = not_before;
301 client_params.not_after = not_after;
302 client_identity_ = rtc::SSLIdentity::GenerateForTest(client_params);
303
304 rtc::SSLIdentityParams server_params;
torbjorng4e572472015-10-08 09:42:49 -0700305 server_params.key_params = rtc::KeyParams(rtc::KT_DEFAULT);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000306 server_params.common_name = "server";
307 server_params.not_before = not_before;
308 server_params.not_after = not_after;
309 server_identity_ = rtc::SSLIdentity::GenerateForTest(server_params);
310
311 client_ssl_->SetIdentity(client_identity_);
312 server_ssl_->SetIdentity(server_identity_);
313 }
314
315 virtual void OnEvent(rtc::StreamInterface *stream, int sig, int err) {
316 LOG(LS_INFO) << "SSLStreamAdapterTestBase::OnEvent sig=" << sig;
317
318 if (sig & rtc::SE_READ) {
319 ReadData(stream);
320 }
321
322 if ((stream == client_ssl_.get()) && (sig & rtc::SE_WRITE)) {
323 WriteData();
324 }
325 }
326
327 void SetPeerIdentitiesByDigest(bool correct) {
328 unsigned char digest[20];
329 size_t digest_len;
330 bool rv;
331
332 LOG(LS_INFO) << "Setting peer identities by digest";
333
334 rv = server_identity_->certificate().ComputeDigest(rtc::DIGEST_SHA_1,
335 digest, 20,
336 &digest_len);
337 ASSERT_TRUE(rv);
338 if (!correct) {
339 LOG(LS_INFO) << "Setting bogus digest for server cert";
340 digest[0]++;
341 }
342 rv = client_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, digest,
343 digest_len);
344 ASSERT_TRUE(rv);
345
346
347 rv = client_identity_->certificate().ComputeDigest(rtc::DIGEST_SHA_1,
348 digest, 20, &digest_len);
349 ASSERT_TRUE(rv);
350 if (!correct) {
351 LOG(LS_INFO) << "Setting bogus digest for client cert";
352 digest[0]++;
353 }
354 rv = server_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, digest,
355 digest_len);
356 ASSERT_TRUE(rv);
357
358 identities_set_ = true;
359 }
360
Joachim Bauch831c5582015-05-20 12:48:41 +0200361 void SetupProtocolVersions(rtc::SSLProtocolVersion server_version,
362 rtc::SSLProtocolVersion client_version) {
363 server_ssl_->SetMaxProtocolVersion(server_version);
364 client_ssl_->SetMaxProtocolVersion(client_version);
365 }
366
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000367 void TestHandshake(bool expect_success = true) {
368 server_ssl_->SetMode(dtls_ ? rtc::SSL_MODE_DTLS :
369 rtc::SSL_MODE_TLS);
370 client_ssl_->SetMode(dtls_ ? rtc::SSL_MODE_DTLS :
371 rtc::SSL_MODE_TLS);
372
373 if (!dtls_) {
374 // Make sure we simulate a reliable network for TLS.
375 // This is just a check to make sure that people don't write wrong
376 // tests.
377 ASSERT((mtu_ == 1460) && (loss_ == 0) && (lose_first_packet_ == 0));
378 }
379
380 if (!identities_set_)
381 SetPeerIdentitiesByDigest(true);
382
383 // Start the handshake
384 int rv;
385
386 server_ssl_->SetServerRole();
387 rv = server_ssl_->StartSSLWithPeer();
388 ASSERT_EQ(0, rv);
389
390 rv = client_ssl_->StartSSLWithPeer();
391 ASSERT_EQ(0, rv);
392
393 // Now run the handshake
394 if (expect_success) {
395 EXPECT_TRUE_WAIT((client_ssl_->GetState() == rtc::SS_OPEN)
396 && (server_ssl_->GetState() == rtc::SS_OPEN),
397 handshake_wait_);
398 } else {
399 EXPECT_TRUE_WAIT(client_ssl_->GetState() == rtc::SS_CLOSED,
400 handshake_wait_);
401 }
402 }
403
jbauche488a0d2015-11-19 05:17:58 -0800404 rtc::StreamResult DataWritten(SSLDummyStreamBase *from, const void *data,
405 size_t data_len, size_t *written,
406 int *error) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000407 // Randomly drop loss_ percent of packets
Peter Boström0c4e06b2015-10-07 12:23:21 +0200408 if (rtc::CreateRandomId() % 100 < static_cast<uint32_t>(loss_)) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000409 LOG(LS_INFO) << "Randomly dropping packet, size=" << data_len;
410 *written = data_len;
411 return rtc::SR_SUCCESS;
412 }
413 if (dtls_ && (data_len > mtu_)) {
414 LOG(LS_INFO) << "Dropping packet > mtu, size=" << data_len;
415 *written = data_len;
416 return rtc::SR_SUCCESS;
417 }
418
419 // Optionally damage application data (type 23). Note that we don't damage
420 // handshake packets and we damage the last byte to keep the header
421 // intact but break the MAC.
422 if (damage_ && (*static_cast<const unsigned char *>(data) == 23)) {
423 std::vector<char> buf(data_len);
424
425 LOG(LS_INFO) << "Damaging packet";
426
427 memcpy(&buf[0], data, data_len);
428 buf[data_len - 1]++;
429
430 return from->WriteData(&buf[0], data_len, written, error);
431 }
432
433 return from->WriteData(data, data_len, written, error);
434 }
435
436 void SetDelay(int delay) {
437 delay_ = delay;
438 }
439 int GetDelay() { return delay_; }
440
441 void SetLoseFirstPacket(bool lose) {
442 lose_first_packet_ = lose;
443 }
444 bool GetLoseFirstPacket() { return lose_first_packet_; }
445
446 void SetLoss(int percent) {
447 loss_ = percent;
448 }
449
450 void SetDamage() {
451 damage_ = true;
452 }
453
454 void SetMtu(size_t mtu) {
455 mtu_ = mtu;
456 }
457
458 void SetHandshakeWait(int wait) {
459 handshake_wait_ = wait;
460 }
461
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800462 void SetDtlsSrtpCryptoSuites(const std::vector<int>& ciphers, bool client) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000463 if (client)
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800464 client_ssl_->SetDtlsSrtpCryptoSuites(ciphers);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000465 else
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800466 server_ssl_->SetDtlsSrtpCryptoSuites(ciphers);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000467 }
468
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800469 bool GetDtlsSrtpCryptoSuite(bool client, int* retval) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000470 if (client)
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800471 return client_ssl_->GetDtlsSrtpCryptoSuite(retval);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000472 else
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800473 return server_ssl_->GetDtlsSrtpCryptoSuite(retval);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000474 }
475
476 bool GetPeerCertificate(bool client, rtc::SSLCertificate** cert) {
477 if (client)
478 return client_ssl_->GetPeerCertificate(cert);
479 else
480 return server_ssl_->GetPeerCertificate(cert);
481 }
482
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -0700483 bool GetSslCipherSuite(bool client, int* retval) {
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000484 if (client)
Guo-wei Shieh456696a2015-09-30 21:48:54 -0700485 return client_ssl_->GetSslCipherSuite(retval);
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000486 else
Guo-wei Shieh456696a2015-09-30 21:48:54 -0700487 return server_ssl_->GetSslCipherSuite(retval);
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000488 }
489
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000490 bool ExportKeyingMaterial(const char *label,
491 const unsigned char *context,
492 size_t context_len,
493 bool use_context,
494 bool client,
495 unsigned char *result,
496 size_t result_len) {
497 if (client)
498 return client_ssl_->ExportKeyingMaterial(label,
499 context, context_len,
500 use_context,
501 result, result_len);
502 else
503 return server_ssl_->ExportKeyingMaterial(label,
504 context, context_len,
505 use_context,
506 result, result_len);
507 }
508
509 // To be implemented by subclasses.
510 virtual void WriteData() = 0;
511 virtual void ReadData(rtc::StreamInterface *stream) = 0;
512 virtual void TestTransfer(int size) = 0;
513
514 protected:
jbauche488a0d2015-11-19 05:17:58 -0800515 std::string client_cert_pem_;
516 std::string client_private_key_pem_;
517 rtc::KeyParams client_key_type_;
518 rtc::KeyParams server_key_type_;
519 SSLDummyStreamBase *client_stream_; // freed by client_ssl_ destructor
520 SSLDummyStreamBase *server_stream_; // freed by server_ssl_ destructor
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000521 rtc::scoped_ptr<rtc::SSLStreamAdapter> client_ssl_;
522 rtc::scoped_ptr<rtc::SSLStreamAdapter> server_ssl_;
523 rtc::SSLIdentity *client_identity_; // freed by client_ssl_ destructor
524 rtc::SSLIdentity *server_identity_; // freed by server_ssl_ destructor
525 int delay_;
526 size_t mtu_;
527 int loss_;
528 bool lose_first_packet_;
529 bool damage_;
530 bool dtls_;
531 int handshake_wait_;
532 bool identities_set_;
533};
534
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200535class SSLStreamAdapterTestTLS
536 : public SSLStreamAdapterTestBase,
torbjorng4e572472015-10-08 09:42:49 -0700537 public WithParamInterface<tuple<rtc::KeyParams, rtc::KeyParams>> {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000538 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200539 SSLStreamAdapterTestTLS()
540 : SSLStreamAdapterTestBase("",
541 "",
542 false,
543 ::testing::get<0>(GetParam()),
jbauche488a0d2015-11-19 05:17:58 -0800544 ::testing::get<1>(GetParam())),
545 client_buffer_(kFifoBufferSize),
546 server_buffer_(kFifoBufferSize) {
547 }
548
torbjorng7593aad2015-11-19 12:20:51 -0800549 void CreateStreams() override {
jbauche488a0d2015-11-19 05:17:58 -0800550 client_stream_ =
551 new SSLDummyStreamTLS(this, "c2s", &client_buffer_, &server_buffer_);
552 server_stream_ =
553 new SSLDummyStreamTLS(this, "s2c", &server_buffer_, &client_buffer_);
554 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000555
556 // Test data transfer for TLS
557 virtual void TestTransfer(int size) {
558 LOG(LS_INFO) << "Starting transfer test with " << size << " bytes";
559 // Create some dummy data to send.
560 size_t received;
561
562 send_stream_.ReserveSize(size);
563 for (int i = 0; i < size; ++i) {
564 char ch = static_cast<char>(i);
565 send_stream_.Write(&ch, 1, NULL, NULL);
566 }
567 send_stream_.Rewind();
568
569 // Prepare the receive stream.
570 recv_stream_.ReserveSize(size);
571
572 // Start sending
573 WriteData();
574
575 // Wait for the client to close
576 EXPECT_TRUE_WAIT(server_ssl_->GetState() == rtc::SS_CLOSED, 10000);
577
578 // Now check the data
579 recv_stream_.GetSize(&received);
580
581 EXPECT_EQ(static_cast<size_t>(size), received);
582 EXPECT_EQ(0, memcmp(send_stream_.GetBuffer(),
583 recv_stream_.GetBuffer(), size));
584 }
585
586 void WriteData() {
587 size_t position, tosend, size;
588 rtc::StreamResult rv;
589 size_t sent;
590 char block[kBlockSize];
591
592 send_stream_.GetSize(&size);
593 if (!size)
594 return;
595
596 for (;;) {
597 send_stream_.GetPosition(&position);
598 if (send_stream_.Read(block, sizeof(block), &tosend, NULL) !=
599 rtc::SR_EOS) {
600 rv = client_ssl_->Write(block, tosend, &sent, 0);
601
602 if (rv == rtc::SR_SUCCESS) {
603 send_stream_.SetPosition(position + sent);
604 LOG(LS_VERBOSE) << "Sent: " << position + sent;
605 } else if (rv == rtc::SR_BLOCK) {
606 LOG(LS_VERBOSE) << "Blocked...";
607 send_stream_.SetPosition(position);
608 break;
609 } else {
610 ADD_FAILURE();
611 break;
612 }
613 } else {
614 // Now close
615 LOG(LS_INFO) << "Wrote " << position << " bytes. Closing";
616 client_ssl_->Close();
617 break;
618 }
619 }
620 };
621
622 virtual void ReadData(rtc::StreamInterface *stream) {
623 char buffer[1600];
624 size_t bread;
625 int err2;
626 rtc::StreamResult r;
627
628 for (;;) {
629 r = stream->Read(buffer, sizeof(buffer), &bread, &err2);
630
631 if (r == rtc::SR_ERROR || r == rtc::SR_EOS) {
632 // Unfortunately, errors are the way that the stream adapter
torbjorng7593aad2015-11-19 12:20:51 -0800633 // signals close in OpenSSL.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000634 stream->Close();
635 return;
636 }
637
638 if (r == rtc::SR_BLOCK)
639 break;
640
641 ASSERT_EQ(rtc::SR_SUCCESS, r);
642 LOG(LS_INFO) << "Read " << bread;
643
644 recv_stream_.Write(buffer, bread, NULL, NULL);
645 }
646 }
647
648 private:
jbauche488a0d2015-11-19 05:17:58 -0800649 rtc::FifoBuffer client_buffer_;
650 rtc::FifoBuffer server_buffer_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000651 rtc::MemoryStream send_stream_;
652 rtc::MemoryStream recv_stream_;
653};
654
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200655class SSLStreamAdapterTestDTLS
656 : public SSLStreamAdapterTestBase,
torbjorng4e572472015-10-08 09:42:49 -0700657 public WithParamInterface<tuple<rtc::KeyParams, rtc::KeyParams>> {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000658 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200659 SSLStreamAdapterTestDTLS()
660 : SSLStreamAdapterTestBase("",
661 "",
662 true,
663 ::testing::get<0>(GetParam()),
664 ::testing::get<1>(GetParam())),
jbauche488a0d2015-11-19 05:17:58 -0800665 client_buffer_(kBufferCapacity, kDefaultBufferSize),
666 server_buffer_(kBufferCapacity, kDefaultBufferSize),
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200667 packet_size_(1000),
668 count_(0),
669 sent_(0) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000670
671 SSLStreamAdapterTestDTLS(const std::string& cert_pem,
672 const std::string& private_key_pem) :
673 SSLStreamAdapterTestBase(cert_pem, private_key_pem, true),
jbauche488a0d2015-11-19 05:17:58 -0800674 client_buffer_(kBufferCapacity, kDefaultBufferSize),
675 server_buffer_(kBufferCapacity, kDefaultBufferSize),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000676 packet_size_(1000), count_(0), sent_(0) {
677 }
678
torbjorng7593aad2015-11-19 12:20:51 -0800679 void CreateStreams() override {
jbauche488a0d2015-11-19 05:17:58 -0800680 client_stream_ =
681 new SSLDummyStreamDTLS(this, "c2s", &client_buffer_, &server_buffer_);
682 server_stream_ =
683 new SSLDummyStreamDTLS(this, "s2c", &server_buffer_, &client_buffer_);
684 }
685
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000686 virtual void WriteData() {
687 unsigned char *packet = new unsigned char[1600];
688
jbauche488a0d2015-11-19 05:17:58 -0800689 while (sent_ < count_) {
torbjorng7593aad2015-11-19 12:20:51 -0800690 unsigned int rand_state = sent_;
691 packet[0] = sent_;
692 for (size_t i = 1; i < packet_size_; i++) {
693 // This is a simple LC PRNG. Keep in synch with identical code below.
694 rand_state = (rand_state * 251 + 19937) >> 7;
695 packet[i] = rand_state & 0xff;
696 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000697
698 size_t sent;
torbjorng7593aad2015-11-19 12:20:51 -0800699 rtc::StreamResult rv = client_ssl_->Write(packet, packet_size_, &sent, 0);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000700 if (rv == rtc::SR_SUCCESS) {
701 LOG(LS_VERBOSE) << "Sent: " << sent_;
702 sent_++;
703 } else if (rv == rtc::SR_BLOCK) {
704 LOG(LS_VERBOSE) << "Blocked...";
705 break;
706 } else {
707 ADD_FAILURE();
708 break;
709 }
jbauche488a0d2015-11-19 05:17:58 -0800710 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000711
712 delete [] packet;
713 }
714
715 virtual void ReadData(rtc::StreamInterface *stream) {
716 unsigned char buffer[2000];
717 size_t bread;
718 int err2;
719 rtc::StreamResult r;
720
721 for (;;) {
722 r = stream->Read(buffer, 2000, &bread, &err2);
723
724 if (r == rtc::SR_ERROR) {
725 // Unfortunately, errors are the way that the stream adapter
726 // signals close right now
727 stream->Close();
728 return;
729 }
730
731 if (r == rtc::SR_BLOCK)
732 break;
733
734 ASSERT_EQ(rtc::SR_SUCCESS, r);
735 LOG(LS_INFO) << "Read " << bread;
736
737 // Now parse the datagram
738 ASSERT_EQ(packet_size_, bread);
torbjorng7593aad2015-11-19 12:20:51 -0800739 unsigned char packet_num = buffer[0];
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000740
torbjorng7593aad2015-11-19 12:20:51 -0800741 unsigned int rand_state = packet_num;
742 for (size_t i = 1; i < packet_size_; i++) {
743 // This is a simple LC PRNG. Keep in synch with identical code above.
744 rand_state = (rand_state * 251 + 19937) >> 7;
745 ASSERT_EQ(rand_state & 0xff, buffer[i]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000746 }
747 received_.insert(packet_num);
748 }
749 }
750
751 virtual void TestTransfer(int count) {
752 count_ = count;
753
754 WriteData();
755
756 EXPECT_TRUE_WAIT(sent_ == count_, 10000);
757 LOG(LS_INFO) << "sent_ == " << sent_;
758
759 if (damage_) {
760 WAIT(false, 2000);
761 EXPECT_EQ(0U, received_.size());
762 } else if (loss_ == 0) {
763 EXPECT_EQ_WAIT(static_cast<size_t>(sent_), received_.size(), 1000);
764 } else {
765 LOG(LS_INFO) << "Sent " << sent_ << " packets; received " <<
766 received_.size();
767 }
768 };
769
770 private:
jbauche488a0d2015-11-19 05:17:58 -0800771 BufferQueueStream client_buffer_;
772 BufferQueueStream server_buffer_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000773 size_t packet_size_;
774 int count_;
775 int sent_;
776 std::set<int> received_;
777};
778
779
jbauche488a0d2015-11-19 05:17:58 -0800780rtc::StreamResult SSLDummyStreamBase::Write(const void* data, size_t data_len,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000781 size_t* written, int* error) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000782 LOG(LS_INFO) << "Writing to loopback " << data_len;
783
784 if (first_packet_) {
785 first_packet_ = false;
jbauche488a0d2015-11-19 05:17:58 -0800786 if (test_base_->GetLoseFirstPacket()) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000787 LOG(LS_INFO) << "Losing initial packet of length " << data_len;
torbjorng7593aad2015-11-19 12:20:51 -0800788 *written = data_len; // Fake successful writing also to writer.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000789 return rtc::SR_SUCCESS;
790 }
791 }
792
jbauche488a0d2015-11-19 05:17:58 -0800793 return test_base_->DataWritten(this, data, data_len, written, error);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000794};
795
796class SSLStreamAdapterTestDTLSFromPEMStrings : public SSLStreamAdapterTestDTLS {
797 public:
798 SSLStreamAdapterTestDTLSFromPEMStrings() :
799 SSLStreamAdapterTestDTLS(kCERT_PEM, kRSA_PRIVATE_KEY_PEM) {
800 }
801};
802
803// Basic tests: TLS
804
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000805// Test that we can make a handshake work
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200806TEST_P(SSLStreamAdapterTestTLS, TestTLSConnect) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000807 TestHandshake();
808};
809
jiayl@webrtc.orgf1d751c2014-09-25 16:38:46 +0000810// Test that closing the connection on one side updates the other side.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200811TEST_P(SSLStreamAdapterTestTLS, TestTLSClose) {
jiayl@webrtc.orgf1d751c2014-09-25 16:38:46 +0000812 TestHandshake();
813 client_ssl_->Close();
814 EXPECT_EQ_WAIT(rtc::SS_CLOSED, server_ssl_->GetState(), handshake_wait_);
815};
816
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000817// Test transfer -- trivial
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200818TEST_P(SSLStreamAdapterTestTLS, TestTLSTransfer) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000819 TestHandshake();
820 TestTransfer(100000);
821};
822
823// Test read-write after close.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200824TEST_P(SSLStreamAdapterTestTLS, ReadWriteAfterClose) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000825 TestHandshake();
826 TestTransfer(100000);
827 client_ssl_->Close();
828
829 rtc::StreamResult rv;
830 char block[kBlockSize];
831 size_t dummy;
832
833 // It's an error to write after closed.
834 rv = client_ssl_->Write(block, sizeof(block), &dummy, NULL);
835 ASSERT_EQ(rtc::SR_ERROR, rv);
836
837 // But after closed read gives you EOS.
838 rv = client_ssl_->Read(block, sizeof(block), &dummy, NULL);
839 ASSERT_EQ(rtc::SR_EOS, rv);
840};
841
842// Test a handshake with a bogus peer digest
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200843TEST_P(SSLStreamAdapterTestTLS, TestTLSBogusDigest) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000844 SetPeerIdentitiesByDigest(false);
845 TestHandshake(false);
846};
847
848// Test moving a bunch of data
849
850// Basic tests: DTLS
851// Test that we can make a handshake work
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200852TEST_P(SSLStreamAdapterTestDTLS, TestDTLSConnect) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000853 MAYBE_SKIP_TEST(HaveDtls);
854 TestHandshake();
855};
856
857// Test that we can make a handshake work if the first packet in
858// each direction is lost. This gives us predictable loss
859// rather than having to tune random
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200860TEST_P(SSLStreamAdapterTestDTLS, TestDTLSConnectWithLostFirstPacket) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000861 MAYBE_SKIP_TEST(HaveDtls);
862 SetLoseFirstPacket(true);
863 TestHandshake();
864};
865
866// Test a handshake with loss and delay
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200867TEST_P(SSLStreamAdapterTestDTLS, TestDTLSConnectWithLostFirstPacketDelay2s) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000868 MAYBE_SKIP_TEST(HaveDtls);
869 SetLoseFirstPacket(true);
870 SetDelay(2000);
871 SetHandshakeWait(20000);
872 TestHandshake();
873};
874
875// Test a handshake with small MTU
pbos@webrtc.org127ca3f2014-10-09 07:52:03 +0000876// Disabled due to https://code.google.com/p/webrtc/issues/detail?id=3910
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200877TEST_P(SSLStreamAdapterTestDTLS, DISABLED_TestDTLSConnectWithSmallMtu) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000878 MAYBE_SKIP_TEST(HaveDtls);
879 SetMtu(700);
880 SetHandshakeWait(20000);
881 TestHandshake();
882};
883
884// Test transfer -- trivial
jbauche488a0d2015-11-19 05:17:58 -0800885TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransfer) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000886 MAYBE_SKIP_TEST(HaveDtls);
887 TestHandshake();
888 TestTransfer(100);
889};
890
jbauche488a0d2015-11-19 05:17:58 -0800891TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransferWithLoss) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000892 MAYBE_SKIP_TEST(HaveDtls);
893 TestHandshake();
894 SetLoss(10);
895 TestTransfer(100);
896};
897
jbauche488a0d2015-11-19 05:17:58 -0800898TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransferWithDamage) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000899 MAYBE_SKIP_TEST(HaveDtls);
900 SetDamage(); // Must be called first because first packet
901 // write happens at end of handshake.
902 TestHandshake();
903 TestTransfer(100);
904};
905
906// Test DTLS-SRTP with all high ciphers
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200907TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpHigh) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000908 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800909 std::vector<int> high;
910 high.push_back(rtc::SRTP_AES128_CM_SHA1_80);
911 SetDtlsSrtpCryptoSuites(high, true);
912 SetDtlsSrtpCryptoSuites(high, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000913 TestHandshake();
914
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800915 int client_cipher;
916 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
917 int server_cipher;
918 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000919
920 ASSERT_EQ(client_cipher, server_cipher);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800921 ASSERT_EQ(client_cipher, rtc::SRTP_AES128_CM_SHA1_80);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000922};
923
924// Test DTLS-SRTP with all low ciphers
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200925TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpLow) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000926 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800927 std::vector<int> low;
928 low.push_back(rtc::SRTP_AES128_CM_SHA1_32);
929 SetDtlsSrtpCryptoSuites(low, true);
930 SetDtlsSrtpCryptoSuites(low, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000931 TestHandshake();
932
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800933 int client_cipher;
934 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
935 int server_cipher;
936 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000937
938 ASSERT_EQ(client_cipher, server_cipher);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800939 ASSERT_EQ(client_cipher, rtc::SRTP_AES128_CM_SHA1_32);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000940};
941
942
943// Test DTLS-SRTP with a mismatch -- should not converge
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200944TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpHighLow) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000945 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800946 std::vector<int> high;
947 high.push_back(rtc::SRTP_AES128_CM_SHA1_80);
948 std::vector<int> low;
949 low.push_back(rtc::SRTP_AES128_CM_SHA1_32);
950 SetDtlsSrtpCryptoSuites(high, true);
951 SetDtlsSrtpCryptoSuites(low, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000952 TestHandshake();
953
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800954 int client_cipher;
955 ASSERT_FALSE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
956 int server_cipher;
957 ASSERT_FALSE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000958};
959
960// Test DTLS-SRTP with each side being mixed -- should select high
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200961TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpMixed) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000962 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800963 std::vector<int> mixed;
964 mixed.push_back(rtc::SRTP_AES128_CM_SHA1_80);
965 mixed.push_back(rtc::SRTP_AES128_CM_SHA1_32);
966 SetDtlsSrtpCryptoSuites(mixed, true);
967 SetDtlsSrtpCryptoSuites(mixed, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000968 TestHandshake();
969
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800970 int client_cipher;
971 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
972 int server_cipher;
973 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000974
975 ASSERT_EQ(client_cipher, server_cipher);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800976 ASSERT_EQ(client_cipher, rtc::SRTP_AES128_CM_SHA1_80);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000977};
978
979// Test an exporter
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200980TEST_P(SSLStreamAdapterTestDTLS, TestDTLSExporter) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000981 MAYBE_SKIP_TEST(HaveExporter);
982 TestHandshake();
983 unsigned char client_out[20];
984 unsigned char server_out[20];
985
986 bool result;
987 result = ExportKeyingMaterial(kExporterLabel,
988 kExporterContext, kExporterContextLen,
989 true, true,
990 client_out, sizeof(client_out));
991 ASSERT_TRUE(result);
992
993 result = ExportKeyingMaterial(kExporterLabel,
994 kExporterContext, kExporterContextLen,
995 true, false,
996 server_out, sizeof(server_out));
997 ASSERT_TRUE(result);
998
999 ASSERT_TRUE(!memcmp(client_out, server_out, sizeof(client_out)));
1000}
1001
1002// Test not yet valid certificates are not rejected.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +02001003TEST_P(SSLStreamAdapterTestDTLS, TestCertNotYetValid) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001004 MAYBE_SKIP_TEST(HaveDtls);
1005 long one_day = 60 * 60 * 24;
1006 // Make the certificates not valid until one day later.
1007 ResetIdentitiesWithValidity(one_day, one_day);
1008 TestHandshake();
1009}
1010
1011// Test expired certificates are not rejected.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +02001012TEST_P(SSLStreamAdapterTestDTLS, TestCertExpired) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001013 MAYBE_SKIP_TEST(HaveDtls);
1014 long one_day = 60 * 60 * 24;
1015 // Make the certificates already expired.
1016 ResetIdentitiesWithValidity(-one_day, -one_day);
1017 TestHandshake();
1018}
1019
1020// Test data transfer using certs created from strings.
torbjorng7593aad2015-11-19 12:20:51 -08001021TEST_F(SSLStreamAdapterTestDTLSFromPEMStrings, TestTransfer) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001022 MAYBE_SKIP_TEST(HaveDtls);
1023 TestHandshake();
1024 TestTransfer(100);
1025}
1026
1027// Test getting the remote certificate.
torbjorng7593aad2015-11-19 12:20:51 -08001028TEST_F(SSLStreamAdapterTestDTLSFromPEMStrings, TestDTLSGetPeerCertificate) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001029 MAYBE_SKIP_TEST(HaveDtls);
1030
1031 // Peer certificates haven't been received yet.
1032 rtc::scoped_ptr<rtc::SSLCertificate> client_peer_cert;
1033 ASSERT_FALSE(GetPeerCertificate(true, client_peer_cert.accept()));
1034 ASSERT_FALSE(client_peer_cert != NULL);
1035
1036 rtc::scoped_ptr<rtc::SSLCertificate> server_peer_cert;
1037 ASSERT_FALSE(GetPeerCertificate(false, server_peer_cert.accept()));
1038 ASSERT_FALSE(server_peer_cert != NULL);
1039
1040 TestHandshake();
1041
1042 // The client should have a peer certificate after the handshake.
1043 ASSERT_TRUE(GetPeerCertificate(true, client_peer_cert.accept()));
1044 ASSERT_TRUE(client_peer_cert != NULL);
1045
1046 // It's not kCERT_PEM.
1047 std::string client_peer_string = client_peer_cert->ToPEMString();
1048 ASSERT_NE(kCERT_PEM, client_peer_string);
1049
1050 // It must not have a chain, because the test certs are self-signed.
1051 rtc::SSLCertChain* client_peer_chain;
1052 ASSERT_FALSE(client_peer_cert->GetChain(&client_peer_chain));
1053
1054 // The server should have a peer certificate after the handshake.
1055 ASSERT_TRUE(GetPeerCertificate(false, server_peer_cert.accept()));
1056 ASSERT_TRUE(server_peer_cert != NULL);
1057
1058 // It's kCERT_PEM
1059 ASSERT_EQ(kCERT_PEM, server_peer_cert->ToPEMString());
1060
1061 // It must not have a chain, because the test certs are self-signed.
1062 rtc::SSLCertChain* server_peer_chain;
1063 ASSERT_FALSE(server_peer_cert->GetChain(&server_peer_chain));
1064}
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001065
1066// Test getting the used DTLS ciphers.
Joachim Bauch831c5582015-05-20 12:48:41 +02001067// DTLS 1.2 enabled for neither client nor server -> DTLS 1.0 will be used.
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001068TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuite) {
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001069 MAYBE_SKIP_TEST(HaveDtls);
Joachim Bauch831c5582015-05-20 12:48:41 +02001070 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10);
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001071 TestHandshake();
1072
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001073 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001074 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001075 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001076 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001077
1078 ASSERT_EQ(client_cipher, server_cipher);
torbjorng4e572472015-10-08 09:42:49 -07001079 ASSERT_EQ(
1080 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
1081 rtc::SSL_PROTOCOL_DTLS_10, ::testing::get<1>(GetParam()).type()),
1082 server_cipher);
Joachim Bauch831c5582015-05-20 12:48:41 +02001083}
1084
1085// Test getting the used DTLS 1.2 ciphers.
1086// DTLS 1.2 enabled for client and server -> DTLS 1.2 will be used.
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001087TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Both) {
Joachim Bauch831c5582015-05-20 12:48:41 +02001088 MAYBE_SKIP_TEST(HaveDtls);
1089 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_12);
1090 TestHandshake();
1091
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001092 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001093 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001094 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001095 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
Joachim Bauch831c5582015-05-20 12:48:41 +02001096
1097 ASSERT_EQ(client_cipher, server_cipher);
torbjorng4e572472015-10-08 09:42:49 -07001098 ASSERT_EQ(
1099 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
1100 rtc::SSL_PROTOCOL_DTLS_12, ::testing::get<1>(GetParam()).type()),
1101 server_cipher);
Joachim Bauch831c5582015-05-20 12:48:41 +02001102}
1103
1104// DTLS 1.2 enabled for client only -> DTLS 1.0 will be used.
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001105TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Client) {
Joachim Bauch831c5582015-05-20 12:48:41 +02001106 MAYBE_SKIP_TEST(HaveDtls);
1107 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_12);
1108 TestHandshake();
1109
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001110 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001111 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001112 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001113 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
Joachim Bauch831c5582015-05-20 12:48:41 +02001114
1115 ASSERT_EQ(client_cipher, server_cipher);
torbjorng4e572472015-10-08 09:42:49 -07001116 ASSERT_EQ(
1117 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
1118 rtc::SSL_PROTOCOL_DTLS_10, ::testing::get<1>(GetParam()).type()),
1119 server_cipher);
Joachim Bauch831c5582015-05-20 12:48:41 +02001120}
1121
1122// DTLS 1.2 enabled for server only -> DTLS 1.0 will be used.
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001123TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Server) {
Joachim Bauch831c5582015-05-20 12:48:41 +02001124 MAYBE_SKIP_TEST(HaveDtls);
1125 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_10);
1126 TestHandshake();
1127
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001128 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001129 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001130 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001131 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
Joachim Bauch831c5582015-05-20 12:48:41 +02001132
1133 ASSERT_EQ(client_cipher, server_cipher);
torbjorng4e572472015-10-08 09:42:49 -07001134 ASSERT_EQ(
1135 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
1136 rtc::SSL_PROTOCOL_DTLS_10, ::testing::get<1>(GetParam()).type()),
1137 server_cipher);
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001138}
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +02001139
torbjorng4e572472015-10-08 09:42:49 -07001140// The RSA keysizes here might look strange, why not include the RFC's size
1141// 2048?. The reason is test case slowness; testing two sizes to exercise
1142// parametrization is sufficient.
1143INSTANTIATE_TEST_CASE_P(
1144 SSLStreamAdapterTestsTLS,
1145 SSLStreamAdapterTestTLS,
1146 Combine(Values(rtc::KeyParams::RSA(1024, 65537),
1147 rtc::KeyParams::RSA(1152, 65537),
1148 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256)),
1149 Values(rtc::KeyParams::RSA(1024, 65537),
1150 rtc::KeyParams::RSA(1152, 65537),
1151 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256))));
1152INSTANTIATE_TEST_CASE_P(
1153 SSLStreamAdapterTestsDTLS,
1154 SSLStreamAdapterTestDTLS,
1155 Combine(Values(rtc::KeyParams::RSA(1024, 65537),
1156 rtc::KeyParams::RSA(1152, 65537),
1157 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256)),
1158 Values(rtc::KeyParams::RSA(1024, 65537),
1159 rtc::KeyParams::RSA(1152, 65537),
1160 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256))));