blob: b14a88707aec9d4066e4cdac9561d0f3bb101cdf [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
jbauche488a0d2015-11-19 05:17:58 -0800256 virtual void SetUp() override {
257 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
278 virtual void TearDown() override {
279 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
549 virtual void CreateStreams() override {
550 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
633 // signals close in OpenSSL
634 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
jbauche488a0d2015-11-19 05:17:58 -0800679 virtual void CreateStreams() override {
680 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_) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000690 memset(packet, sent_ & 0xff, packet_size_);
691 *(reinterpret_cast<uint32_t *>(packet)) = sent_;
692
693 size_t sent;
694 int rv = client_ssl_->Write(packet, packet_size_, &sent, 0);
695 if (rv == rtc::SR_SUCCESS) {
696 LOG(LS_VERBOSE) << "Sent: " << sent_;
697 sent_++;
698 } else if (rv == rtc::SR_BLOCK) {
699 LOG(LS_VERBOSE) << "Blocked...";
700 break;
701 } else {
702 ADD_FAILURE();
703 break;
704 }
jbauche488a0d2015-11-19 05:17:58 -0800705 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000706
707 delete [] packet;
708 }
709
710 virtual void ReadData(rtc::StreamInterface *stream) {
711 unsigned char buffer[2000];
712 size_t bread;
713 int err2;
714 rtc::StreamResult r;
715
716 for (;;) {
717 r = stream->Read(buffer, 2000, &bread, &err2);
718
719 if (r == rtc::SR_ERROR) {
720 // Unfortunately, errors are the way that the stream adapter
721 // signals close right now
722 stream->Close();
723 return;
724 }
725
726 if (r == rtc::SR_BLOCK)
727 break;
728
729 ASSERT_EQ(rtc::SR_SUCCESS, r);
730 LOG(LS_INFO) << "Read " << bread;
731
732 // Now parse the datagram
733 ASSERT_EQ(packet_size_, bread);
734 unsigned char* ptr_to_buffer = buffer;
735 uint32_t packet_num = *(reinterpret_cast<uint32_t *>(ptr_to_buffer));
736
737 for (size_t i = 4; i < packet_size_; i++) {
738 ASSERT_EQ((packet_num & 0xff), buffer[i]);
739 }
740 received_.insert(packet_num);
741 }
742 }
743
744 virtual void TestTransfer(int count) {
745 count_ = count;
746
747 WriteData();
748
749 EXPECT_TRUE_WAIT(sent_ == count_, 10000);
750 LOG(LS_INFO) << "sent_ == " << sent_;
751
752 if (damage_) {
753 WAIT(false, 2000);
754 EXPECT_EQ(0U, received_.size());
755 } else if (loss_ == 0) {
756 EXPECT_EQ_WAIT(static_cast<size_t>(sent_), received_.size(), 1000);
757 } else {
758 LOG(LS_INFO) << "Sent " << sent_ << " packets; received " <<
759 received_.size();
760 }
761 };
762
763 private:
jbauche488a0d2015-11-19 05:17:58 -0800764 BufferQueueStream client_buffer_;
765 BufferQueueStream server_buffer_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000766 size_t packet_size_;
767 int count_;
768 int sent_;
769 std::set<int> received_;
770};
771
772
jbauche488a0d2015-11-19 05:17:58 -0800773rtc::StreamResult SSLDummyStreamBase::Write(const void* data, size_t data_len,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000774 size_t* written, int* error) {
775 *written = data_len;
776
777 LOG(LS_INFO) << "Writing to loopback " << data_len;
778
779 if (first_packet_) {
780 first_packet_ = false;
jbauche488a0d2015-11-19 05:17:58 -0800781 if (test_base_->GetLoseFirstPacket()) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000782 LOG(LS_INFO) << "Losing initial packet of length " << data_len;
783 return rtc::SR_SUCCESS;
784 }
785 }
786
jbauche488a0d2015-11-19 05:17:58 -0800787 return test_base_->DataWritten(this, data, data_len, written, error);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000788};
789
790class SSLStreamAdapterTestDTLSFromPEMStrings : public SSLStreamAdapterTestDTLS {
791 public:
792 SSLStreamAdapterTestDTLSFromPEMStrings() :
793 SSLStreamAdapterTestDTLS(kCERT_PEM, kRSA_PRIVATE_KEY_PEM) {
794 }
795};
796
797// Basic tests: TLS
798
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000799// Test that we can make a handshake work
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200800TEST_P(SSLStreamAdapterTestTLS, TestTLSConnect) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000801 TestHandshake();
802};
803
jiayl@webrtc.orgf1d751c2014-09-25 16:38:46 +0000804// Test that closing the connection on one side updates the other side.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200805TEST_P(SSLStreamAdapterTestTLS, TestTLSClose) {
jiayl@webrtc.orgf1d751c2014-09-25 16:38:46 +0000806 TestHandshake();
807 client_ssl_->Close();
808 EXPECT_EQ_WAIT(rtc::SS_CLOSED, server_ssl_->GetState(), handshake_wait_);
809};
810
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000811// Test transfer -- trivial
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200812TEST_P(SSLStreamAdapterTestTLS, TestTLSTransfer) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000813 TestHandshake();
814 TestTransfer(100000);
815};
816
817// Test read-write after close.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200818TEST_P(SSLStreamAdapterTestTLS, ReadWriteAfterClose) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000819 TestHandshake();
820 TestTransfer(100000);
821 client_ssl_->Close();
822
823 rtc::StreamResult rv;
824 char block[kBlockSize];
825 size_t dummy;
826
827 // It's an error to write after closed.
828 rv = client_ssl_->Write(block, sizeof(block), &dummy, NULL);
829 ASSERT_EQ(rtc::SR_ERROR, rv);
830
831 // But after closed read gives you EOS.
832 rv = client_ssl_->Read(block, sizeof(block), &dummy, NULL);
833 ASSERT_EQ(rtc::SR_EOS, rv);
834};
835
836// Test a handshake with a bogus peer digest
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200837TEST_P(SSLStreamAdapterTestTLS, TestTLSBogusDigest) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000838 SetPeerIdentitiesByDigest(false);
839 TestHandshake(false);
840};
841
842// Test moving a bunch of data
843
844// Basic tests: DTLS
845// Test that we can make a handshake work
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200846TEST_P(SSLStreamAdapterTestDTLS, TestDTLSConnect) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000847 MAYBE_SKIP_TEST(HaveDtls);
848 TestHandshake();
849};
850
851// Test that we can make a handshake work if the first packet in
852// each direction is lost. This gives us predictable loss
853// rather than having to tune random
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200854TEST_P(SSLStreamAdapterTestDTLS, TestDTLSConnectWithLostFirstPacket) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000855 MAYBE_SKIP_TEST(HaveDtls);
856 SetLoseFirstPacket(true);
857 TestHandshake();
858};
859
860// Test a handshake with loss and delay
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200861TEST_P(SSLStreamAdapterTestDTLS, TestDTLSConnectWithLostFirstPacketDelay2s) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000862 MAYBE_SKIP_TEST(HaveDtls);
863 SetLoseFirstPacket(true);
864 SetDelay(2000);
865 SetHandshakeWait(20000);
866 TestHandshake();
867};
868
869// Test a handshake with small MTU
pbos@webrtc.org127ca3f2014-10-09 07:52:03 +0000870// Disabled due to https://code.google.com/p/webrtc/issues/detail?id=3910
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200871TEST_P(SSLStreamAdapterTestDTLS, DISABLED_TestDTLSConnectWithSmallMtu) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000872 MAYBE_SKIP_TEST(HaveDtls);
873 SetMtu(700);
874 SetHandshakeWait(20000);
875 TestHandshake();
876};
877
878// Test transfer -- trivial
jbauche488a0d2015-11-19 05:17:58 -0800879TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransfer) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000880 MAYBE_SKIP_TEST(HaveDtls);
881 TestHandshake();
882 TestTransfer(100);
883};
884
jbauche488a0d2015-11-19 05:17:58 -0800885TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransferWithLoss) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000886 MAYBE_SKIP_TEST(HaveDtls);
887 TestHandshake();
888 SetLoss(10);
889 TestTransfer(100);
890};
891
jbauche488a0d2015-11-19 05:17:58 -0800892TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransferWithDamage) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000893 MAYBE_SKIP_TEST(HaveDtls);
894 SetDamage(); // Must be called first because first packet
895 // write happens at end of handshake.
896 TestHandshake();
897 TestTransfer(100);
898};
899
900// Test DTLS-SRTP with all high ciphers
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200901TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpHigh) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000902 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800903 std::vector<int> high;
904 high.push_back(rtc::SRTP_AES128_CM_SHA1_80);
905 SetDtlsSrtpCryptoSuites(high, true);
906 SetDtlsSrtpCryptoSuites(high, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000907 TestHandshake();
908
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800909 int client_cipher;
910 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
911 int server_cipher;
912 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000913
914 ASSERT_EQ(client_cipher, server_cipher);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800915 ASSERT_EQ(client_cipher, rtc::SRTP_AES128_CM_SHA1_80);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000916};
917
918// Test DTLS-SRTP with all low ciphers
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200919TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpLow) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000920 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800921 std::vector<int> low;
922 low.push_back(rtc::SRTP_AES128_CM_SHA1_32);
923 SetDtlsSrtpCryptoSuites(low, true);
924 SetDtlsSrtpCryptoSuites(low, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000925 TestHandshake();
926
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800927 int client_cipher;
928 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
929 int server_cipher;
930 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000931
932 ASSERT_EQ(client_cipher, server_cipher);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800933 ASSERT_EQ(client_cipher, rtc::SRTP_AES128_CM_SHA1_32);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000934};
935
936
937// Test DTLS-SRTP with a mismatch -- should not converge
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200938TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpHighLow) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000939 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800940 std::vector<int> high;
941 high.push_back(rtc::SRTP_AES128_CM_SHA1_80);
942 std::vector<int> low;
943 low.push_back(rtc::SRTP_AES128_CM_SHA1_32);
944 SetDtlsSrtpCryptoSuites(high, true);
945 SetDtlsSrtpCryptoSuites(low, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000946 TestHandshake();
947
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800948 int client_cipher;
949 ASSERT_FALSE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
950 int server_cipher;
951 ASSERT_FALSE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000952};
953
954// Test DTLS-SRTP with each side being mixed -- should select high
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200955TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpMixed) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000956 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800957 std::vector<int> mixed;
958 mixed.push_back(rtc::SRTP_AES128_CM_SHA1_80);
959 mixed.push_back(rtc::SRTP_AES128_CM_SHA1_32);
960 SetDtlsSrtpCryptoSuites(mixed, true);
961 SetDtlsSrtpCryptoSuites(mixed, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000962 TestHandshake();
963
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800964 int client_cipher;
965 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
966 int server_cipher;
967 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000968
969 ASSERT_EQ(client_cipher, server_cipher);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800970 ASSERT_EQ(client_cipher, rtc::SRTP_AES128_CM_SHA1_80);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000971};
972
973// Test an exporter
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200974TEST_P(SSLStreamAdapterTestDTLS, TestDTLSExporter) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000975 MAYBE_SKIP_TEST(HaveExporter);
976 TestHandshake();
977 unsigned char client_out[20];
978 unsigned char server_out[20];
979
980 bool result;
981 result = ExportKeyingMaterial(kExporterLabel,
982 kExporterContext, kExporterContextLen,
983 true, true,
984 client_out, sizeof(client_out));
985 ASSERT_TRUE(result);
986
987 result = ExportKeyingMaterial(kExporterLabel,
988 kExporterContext, kExporterContextLen,
989 true, false,
990 server_out, sizeof(server_out));
991 ASSERT_TRUE(result);
992
993 ASSERT_TRUE(!memcmp(client_out, server_out, sizeof(client_out)));
994}
995
996// Test not yet valid certificates are not rejected.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200997TEST_P(SSLStreamAdapterTestDTLS, TestCertNotYetValid) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000998 MAYBE_SKIP_TEST(HaveDtls);
999 long one_day = 60 * 60 * 24;
1000 // Make the certificates not valid until one day later.
1001 ResetIdentitiesWithValidity(one_day, one_day);
1002 TestHandshake();
1003}
1004
1005// Test expired certificates are not rejected.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +02001006TEST_P(SSLStreamAdapterTestDTLS, TestCertExpired) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001007 MAYBE_SKIP_TEST(HaveDtls);
1008 long one_day = 60 * 60 * 24;
1009 // Make the certificates already expired.
1010 ResetIdentitiesWithValidity(-one_day, -one_day);
1011 TestHandshake();
1012}
1013
1014// Test data transfer using certs created from strings.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +02001015TEST_P(SSLStreamAdapterTestDTLSFromPEMStrings, TestTransfer) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001016 MAYBE_SKIP_TEST(HaveDtls);
1017 TestHandshake();
1018 TestTransfer(100);
1019}
1020
1021// Test getting the remote certificate.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +02001022TEST_P(SSLStreamAdapterTestDTLSFromPEMStrings, TestDTLSGetPeerCertificate) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001023 MAYBE_SKIP_TEST(HaveDtls);
1024
1025 // Peer certificates haven't been received yet.
1026 rtc::scoped_ptr<rtc::SSLCertificate> client_peer_cert;
1027 ASSERT_FALSE(GetPeerCertificate(true, client_peer_cert.accept()));
1028 ASSERT_FALSE(client_peer_cert != NULL);
1029
1030 rtc::scoped_ptr<rtc::SSLCertificate> server_peer_cert;
1031 ASSERT_FALSE(GetPeerCertificate(false, server_peer_cert.accept()));
1032 ASSERT_FALSE(server_peer_cert != NULL);
1033
1034 TestHandshake();
1035
1036 // The client should have a peer certificate after the handshake.
1037 ASSERT_TRUE(GetPeerCertificate(true, client_peer_cert.accept()));
1038 ASSERT_TRUE(client_peer_cert != NULL);
1039
1040 // It's not kCERT_PEM.
1041 std::string client_peer_string = client_peer_cert->ToPEMString();
1042 ASSERT_NE(kCERT_PEM, client_peer_string);
1043
1044 // It must not have a chain, because the test certs are self-signed.
1045 rtc::SSLCertChain* client_peer_chain;
1046 ASSERT_FALSE(client_peer_cert->GetChain(&client_peer_chain));
1047
1048 // The server should have a peer certificate after the handshake.
1049 ASSERT_TRUE(GetPeerCertificate(false, server_peer_cert.accept()));
1050 ASSERT_TRUE(server_peer_cert != NULL);
1051
1052 // It's kCERT_PEM
1053 ASSERT_EQ(kCERT_PEM, server_peer_cert->ToPEMString());
1054
1055 // It must not have a chain, because the test certs are self-signed.
1056 rtc::SSLCertChain* server_peer_chain;
1057 ASSERT_FALSE(server_peer_cert->GetChain(&server_peer_chain));
1058}
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001059
1060// Test getting the used DTLS ciphers.
Joachim Bauch831c5582015-05-20 12:48:41 +02001061// DTLS 1.2 enabled for neither client nor server -> DTLS 1.0 will be used.
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001062TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuite) {
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001063 MAYBE_SKIP_TEST(HaveDtls);
Joachim Bauch831c5582015-05-20 12:48:41 +02001064 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10);
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001065 TestHandshake();
1066
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001067 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001068 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001069 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001070 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001071
1072 ASSERT_EQ(client_cipher, server_cipher);
torbjorng4e572472015-10-08 09:42:49 -07001073 ASSERT_EQ(
1074 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
1075 rtc::SSL_PROTOCOL_DTLS_10, ::testing::get<1>(GetParam()).type()),
1076 server_cipher);
Joachim Bauch831c5582015-05-20 12:48:41 +02001077}
1078
1079// Test getting the used DTLS 1.2 ciphers.
1080// DTLS 1.2 enabled for client and server -> DTLS 1.2 will be used.
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001081TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Both) {
Joachim Bauch831c5582015-05-20 12:48:41 +02001082 MAYBE_SKIP_TEST(HaveDtls);
1083 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_12);
1084 TestHandshake();
1085
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001086 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001087 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001088 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001089 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
Joachim Bauch831c5582015-05-20 12:48:41 +02001090
1091 ASSERT_EQ(client_cipher, server_cipher);
torbjorng4e572472015-10-08 09:42:49 -07001092 ASSERT_EQ(
1093 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
1094 rtc::SSL_PROTOCOL_DTLS_12, ::testing::get<1>(GetParam()).type()),
1095 server_cipher);
Joachim Bauch831c5582015-05-20 12:48:41 +02001096}
1097
1098// DTLS 1.2 enabled for client only -> DTLS 1.0 will be used.
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001099TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Client) {
Joachim Bauch831c5582015-05-20 12:48:41 +02001100 MAYBE_SKIP_TEST(HaveDtls);
1101 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_12);
1102 TestHandshake();
1103
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001104 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001105 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001106 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001107 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
Joachim Bauch831c5582015-05-20 12:48:41 +02001108
1109 ASSERT_EQ(client_cipher, server_cipher);
torbjorng4e572472015-10-08 09:42:49 -07001110 ASSERT_EQ(
1111 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
1112 rtc::SSL_PROTOCOL_DTLS_10, ::testing::get<1>(GetParam()).type()),
1113 server_cipher);
Joachim Bauch831c5582015-05-20 12:48:41 +02001114}
1115
1116// DTLS 1.2 enabled for server only -> DTLS 1.0 will be used.
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001117TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Server) {
Joachim Bauch831c5582015-05-20 12:48:41 +02001118 MAYBE_SKIP_TEST(HaveDtls);
1119 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_10);
1120 TestHandshake();
1121
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001122 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001123 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001124 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001125 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
Joachim Bauch831c5582015-05-20 12:48:41 +02001126
1127 ASSERT_EQ(client_cipher, server_cipher);
torbjorng4e572472015-10-08 09:42:49 -07001128 ASSERT_EQ(
1129 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
1130 rtc::SSL_PROTOCOL_DTLS_10, ::testing::get<1>(GetParam()).type()),
1131 server_cipher);
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001132}
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +02001133
torbjorng4e572472015-10-08 09:42:49 -07001134// The RSA keysizes here might look strange, why not include the RFC's size
1135// 2048?. The reason is test case slowness; testing two sizes to exercise
1136// parametrization is sufficient.
1137INSTANTIATE_TEST_CASE_P(
1138 SSLStreamAdapterTestsTLS,
1139 SSLStreamAdapterTestTLS,
1140 Combine(Values(rtc::KeyParams::RSA(1024, 65537),
1141 rtc::KeyParams::RSA(1152, 65537),
1142 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256)),
1143 Values(rtc::KeyParams::RSA(1024, 65537),
1144 rtc::KeyParams::RSA(1152, 65537),
1145 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256))));
1146INSTANTIATE_TEST_CASE_P(
1147 SSLStreamAdapterTestsDTLS,
1148 SSLStreamAdapterTestDTLS,
1149 Combine(Values(rtc::KeyParams::RSA(1024, 65537),
1150 rtc::KeyParams::RSA(1152, 65537),
1151 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256)),
1152 Values(rtc::KeyParams::RSA(1024, 65537),
1153 rtc::KeyParams::RSA(1152, 65537),
1154 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256))));