blob: 8d5b275db8c19d6ecb9ea784f07edb8da4c98049 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
2 * Copyright 2011 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11
12#include <algorithm>
13#include <set>
14#include <string>
15
jbauche488a0d2015-11-19 05:17:58 -080016#include "webrtc/base/bufferqueue.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000017#include "webrtc/base/gunit.h"
18#include "webrtc/base/helpers.h"
19#include "webrtc/base/scoped_ptr.h"
20#include "webrtc/base/ssladapter.h"
21#include "webrtc/base/sslconfig.h"
22#include "webrtc/base/sslidentity.h"
23#include "webrtc/base/sslstreamadapter.h"
24#include "webrtc/base/stream.h"
25
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +020026using ::testing::WithParamInterface;
27using ::testing::Values;
28using ::testing::Combine;
29using ::testing::tuple;
30
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000031static const int kBlockSize = 4096;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000032static const char kExporterLabel[] = "label";
33static const unsigned char kExporterContext[] = "context";
34static int kExporterContextLen = sizeof(kExporterContext);
35
36static const char kRSA_PRIVATE_KEY_PEM[] =
37 "-----BEGIN RSA PRIVATE KEY-----\n"
38 "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMYRkbhmI7kVA/rM\n"
39 "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n"
40 "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n"
41 "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAECgYAvgOs4FJcgvp+TuREx7YtiYVsH\n"
42 "mwQPTum2z/8VzWGwR8BBHBvIpVe1MbD/Y4seyI2aco/7UaisatSgJhsU46/9Y4fq\n"
43 "2TwXH9QANf4at4d9n/R6rzwpAJOpgwZgKvdQjkfrKTtgLV+/dawvpxUYkRH4JZM1\n"
44 "CVGukMfKNrSVH4Ap4QJBAOJmGV1ASPnB4r4nc99at7JuIJmd7fmuVUwUgYi4XgaR\n"
45 "WhScBsgYwZ/JoywdyZJgnbcrTDuVcWG56B3vXbhdpMsCQQDf9zeJrjnPZ3Cqm79y\n"
46 "kdqANep0uwZciiNiWxsQrCHztywOvbFhdp8iYVFG9EK8DMY41Y5TxUwsHD+67zao\n"
47 "ZNqJAkEA1suLUP/GvL8IwuRneQd2tWDqqRQ/Td3qq03hP7e77XtF/buya3Ghclo5\n"
48 "54czUR89QyVfJEC6278nzA7n2h1uVQJAcG6mztNL6ja/dKZjYZye2CY44QjSlLo0\n"
49 "MTgTSjdfg/28fFn2Jjtqf9Pi/X+50LWI/RcYMC2no606wRk9kyOuIQJBAK6VSAim\n"
50 "1pOEjsYQn0X5KEIrz1G3bfCbB848Ime3U2/FWlCHMr6ch8kCZ5d1WUeJD3LbwMNG\n"
51 "UCXiYxSsu20QNVw=\n"
52 "-----END RSA PRIVATE KEY-----\n";
53
54static const char kCERT_PEM[] =
55 "-----BEGIN CERTIFICATE-----\n"
56 "MIIBmTCCAQKgAwIBAgIEbzBSAjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDEwZX\n"
57 "ZWJSVEMwHhcNMTQwMTAyMTgyNDQ3WhcNMTQwMjAxMTgyNDQ3WjARMQ8wDQYDVQQD\n"
58 "EwZXZWJSVEMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYRkbhmI7kVA/rM\n"
59 "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n"
60 "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n"
61 "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAEwDQYJKoZIhvcNAQELBQADgYEAUflI\n"
62 "VUe5Krqf5RVa5C3u/UTAOAUJBiDS3VANTCLBxjuMsvqOG0WvaYWP3HYPgrz0jXK2\n"
63 "LJE/mGw3MyFHEqi81jh95J+ypl6xKW6Rm8jKLR87gUvCaVYn/Z4/P3AqcQTB7wOv\n"
64 "UD0A8qfhfDM+LK6rPAnCsVN0NRDY3jvd6rzix9M=\n"
65 "-----END CERTIFICATE-----\n";
66
67#define MAYBE_SKIP_TEST(feature) \
68 if (!(rtc::SSLStreamAdapter::feature())) { \
69 LOG(LS_INFO) << "Feature disabled... skipping"; \
70 return; \
71 }
72
73class SSLStreamAdapterTestBase;
74
jbauche488a0d2015-11-19 05:17:58 -080075class SSLDummyStreamBase : public rtc::StreamInterface,
76 public sigslot::has_slots<> {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000077 public:
jbauche488a0d2015-11-19 05:17:58 -080078 SSLDummyStreamBase(SSLStreamAdapterTestBase* test,
79 const std::string &side,
80 rtc::StreamInterface* in,
81 rtc::StreamInterface* out) :
82 test_base_(test),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000083 side_(side),
84 in_(in),
85 out_(out),
86 first_packet_(true) {
jbauche488a0d2015-11-19 05:17:58 -080087 in_->SignalEvent.connect(this, &SSLDummyStreamBase::OnEventIn);
88 out_->SignalEvent.connect(this, &SSLDummyStreamBase::OnEventOut);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000089 }
90
jbauche488a0d2015-11-19 05:17:58 -080091 rtc::StreamState GetState() const override { return rtc::SS_OPEN; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000092
jbauche488a0d2015-11-19 05:17:58 -080093 rtc::StreamResult Read(void* buffer, size_t buffer_len,
94 size_t* read, int* error) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000095 rtc::StreamResult r;
96
97 r = in_->Read(buffer, buffer_len, read, error);
98 if (r == rtc::SR_BLOCK)
99 return rtc::SR_BLOCK;
100 if (r == rtc::SR_EOS)
101 return rtc::SR_EOS;
102
103 if (r != rtc::SR_SUCCESS) {
104 ADD_FAILURE();
105 return rtc::SR_ERROR;
106 }
107
108 return rtc::SR_SUCCESS;
109 }
110
111 // Catch readability events on in and pass them up.
jbauche488a0d2015-11-19 05:17:58 -0800112 void OnEventIn(rtc::StreamInterface* stream, int sig, int err) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000113 int mask = (rtc::SE_READ | rtc::SE_CLOSE);
114
115 if (sig & mask) {
jbauche488a0d2015-11-19 05:17:58 -0800116 LOG(LS_INFO) << "SSLDummyStreamBase::OnEvent side=" << side_ << " sig="
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000117 << sig << " forwarding upward";
118 PostEvent(sig & mask, 0);
119 }
120 }
121
122 // Catch writeability events on out and pass them up.
jbauche488a0d2015-11-19 05:17:58 -0800123 void OnEventOut(rtc::StreamInterface* stream, int sig, int err) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000124 if (sig & rtc::SE_WRITE) {
jbauche488a0d2015-11-19 05:17:58 -0800125 LOG(LS_INFO) << "SSLDummyStreamBase::OnEvent side=" << side_ << " sig="
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000126 << sig << " forwarding upward";
127
128 PostEvent(sig & rtc::SE_WRITE, 0);
129 }
130 }
131
132 // Write to the outgoing FifoBuffer
133 rtc::StreamResult WriteData(const void* data, size_t data_len,
jbauche488a0d2015-11-19 05:17:58 -0800134 size_t* written, int* error) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000135 return out_->Write(data, data_len, written, error);
136 }
137
jbauche488a0d2015-11-19 05:17:58 -0800138 rtc::StreamResult Write(const void* data, size_t data_len,
139 size_t* written, int* error) override;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000140
jbauche488a0d2015-11-19 05:17:58 -0800141 void Close() override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000142 LOG(LS_INFO) << "Closing outbound stream";
143 out_->Close();
144 }
145
jbauche488a0d2015-11-19 05:17:58 -0800146 protected:
147 SSLStreamAdapterTestBase* test_base_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000148 const std::string side_;
jbauche488a0d2015-11-19 05:17:58 -0800149 rtc::StreamInterface* in_;
150 rtc::StreamInterface* out_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000151 bool first_packet_;
152};
153
jbauche488a0d2015-11-19 05:17:58 -0800154class SSLDummyStreamTLS : public SSLDummyStreamBase {
155 public:
156 SSLDummyStreamTLS(SSLStreamAdapterTestBase* test,
157 const std::string& side,
158 rtc::FifoBuffer* in,
159 rtc::FifoBuffer* out) :
160 SSLDummyStreamBase(test, side, in, out) {
161 }
162};
163
164class BufferQueueStream : public rtc::BufferQueue,
165 public rtc::StreamInterface {
166 public:
167 BufferQueueStream(size_t capacity, size_t default_size)
168 : rtc::BufferQueue(capacity, default_size) {
169 }
170
171 // Implementation of abstract StreamInterface methods.
172
173 // A buffer queue stream is always "open".
174 rtc::StreamState GetState() const override { return rtc::SS_OPEN; }
175
176 // Reading a buffer queue stream will either succeed or block.
177 rtc::StreamResult Read(void* buffer, size_t buffer_len,
178 size_t* read, int* error) override {
179 if (!ReadFront(buffer, buffer_len, read)) {
180 return rtc::SR_BLOCK;
181 }
182 return rtc::SR_SUCCESS;
183 }
184
185 // Writing to a buffer queue stream will either succeed or block.
186 rtc::StreamResult Write(const void* data, size_t data_len,
187 size_t* written, int* error) override {
188 if (!WriteBack(data, data_len, written)) {
189 return rtc::SR_BLOCK;
190 }
191 return rtc::SR_SUCCESS;
192 }
193
194 // A buffer queue stream can not be closed.
195 void Close() override {}
196
197 protected:
198 void NotifyReadableForTest() override {
199 PostEvent(rtc::SE_READ, 0);
200 }
201
202 void NotifyWritableForTest() override {
203 PostEvent(rtc::SE_WRITE, 0);
204 }
205};
206
207class SSLDummyStreamDTLS : public SSLDummyStreamBase {
208 public:
209 SSLDummyStreamDTLS(SSLStreamAdapterTestBase* test,
210 const std::string& side,
211 BufferQueueStream* in,
212 BufferQueueStream* out) :
213 SSLDummyStreamBase(test, side, in, out) {
214 }
215};
216
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000217static const int kFifoBufferSize = 4096;
jbauche488a0d2015-11-19 05:17:58 -0800218static const int kBufferCapacity = 1;
219static const size_t kDefaultBufferSize = 2048;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000220
221class SSLStreamAdapterTestBase : public testing::Test,
222 public sigslot::has_slots<> {
223 public:
torbjorng4e572472015-10-08 09:42:49 -0700224 SSLStreamAdapterTestBase(
225 const std::string& client_cert_pem,
226 const std::string& client_private_key_pem,
227 bool dtls,
228 rtc::KeyParams client_key_type = rtc::KeyParams(rtc::KT_DEFAULT),
229 rtc::KeyParams server_key_type = rtc::KeyParams(rtc::KT_DEFAULT))
jbauche488a0d2015-11-19 05:17:58 -0800230 : client_cert_pem_(client_cert_pem),
231 client_private_key_pem_(client_private_key_pem),
232 client_key_type_(client_key_type),
233 server_key_type_(server_key_type),
234 client_stream_(NULL),
235 server_stream_(NULL),
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200236 client_identity_(NULL),
237 server_identity_(NULL),
238 delay_(0),
239 mtu_(1460),
240 loss_(0),
241 lose_first_packet_(false),
242 damage_(false),
243 dtls_(dtls),
244 handshake_wait_(5000),
245 identities_set_(false) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000246 // Set use of the test RNG to get predictable loss patterns.
247 rtc::SetRandomTestMode(true);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000248 }
249
250 ~SSLStreamAdapterTestBase() {
251 // Put it back for the next test.
252 rtc::SetRandomTestMode(false);
253 }
254
torbjorng7593aad2015-11-19 12:20:51 -0800255 void SetUp() override {
jbauche488a0d2015-11-19 05:17:58 -0800256 CreateStreams();
257
258 client_ssl_.reset(rtc::SSLStreamAdapter::Create(client_stream_));
259 server_ssl_.reset(rtc::SSLStreamAdapter::Create(server_stream_));
260
261 // Set up the slots
262 client_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
263 server_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
264
265 if (!client_cert_pem_.empty() && !client_private_key_pem_.empty()) {
266 client_identity_ = rtc::SSLIdentity::FromPEMStrings(
267 client_private_key_pem_, client_cert_pem_);
268 } else {
269 client_identity_ = rtc::SSLIdentity::Generate("client", client_key_type_);
270 }
271 server_identity_ = rtc::SSLIdentity::Generate("server", server_key_type_);
272
273 client_ssl_->SetIdentity(client_identity_);
274 server_ssl_->SetIdentity(server_identity_);
275 }
276
torbjorng7593aad2015-11-19 12:20:51 -0800277 void TearDown() override {
jbauche488a0d2015-11-19 05:17:58 -0800278 client_ssl_.reset(nullptr);
279 server_ssl_.reset(nullptr);
280 }
281
282 virtual void CreateStreams() = 0;
283
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000284 // Recreate the client/server identities with the specified validity period.
285 // |not_before| and |not_after| are offsets from the current time in number
286 // of seconds.
287 void ResetIdentitiesWithValidity(int not_before, int not_after) {
jbauche488a0d2015-11-19 05:17:58 -0800288 CreateStreams();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000289
290 client_ssl_.reset(rtc::SSLStreamAdapter::Create(client_stream_));
291 server_ssl_.reset(rtc::SSLStreamAdapter::Create(server_stream_));
292
293 client_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
294 server_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
295
Torbjorn Granlund46c9cc02015-12-01 13:06:34 +0100296 time_t now = time(nullptr);
297
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000298 rtc::SSLIdentityParams client_params;
torbjorng4e572472015-10-08 09:42:49 -0700299 client_params.key_params = rtc::KeyParams(rtc::KT_DEFAULT);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000300 client_params.common_name = "client";
Torbjorn Granlund46c9cc02015-12-01 13:06:34 +0100301 client_params.not_before = now + not_before;
302 client_params.not_after = now + not_after;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000303 client_identity_ = rtc::SSLIdentity::GenerateForTest(client_params);
304
305 rtc::SSLIdentityParams server_params;
torbjorng4e572472015-10-08 09:42:49 -0700306 server_params.key_params = rtc::KeyParams(rtc::KT_DEFAULT);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000307 server_params.common_name = "server";
Torbjorn Granlund46c9cc02015-12-01 13:06:34 +0100308 server_params.not_before = now + not_before;
309 server_params.not_after = now + not_after;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000310 server_identity_ = rtc::SSLIdentity::GenerateForTest(server_params);
311
312 client_ssl_->SetIdentity(client_identity_);
313 server_ssl_->SetIdentity(server_identity_);
314 }
315
316 virtual void OnEvent(rtc::StreamInterface *stream, int sig, int err) {
317 LOG(LS_INFO) << "SSLStreamAdapterTestBase::OnEvent sig=" << sig;
318
319 if (sig & rtc::SE_READ) {
320 ReadData(stream);
321 }
322
323 if ((stream == client_ssl_.get()) && (sig & rtc::SE_WRITE)) {
324 WriteData();
325 }
326 }
327
328 void SetPeerIdentitiesByDigest(bool correct) {
329 unsigned char digest[20];
330 size_t digest_len;
331 bool rv;
332
333 LOG(LS_INFO) << "Setting peer identities by digest";
334
335 rv = server_identity_->certificate().ComputeDigest(rtc::DIGEST_SHA_1,
336 digest, 20,
337 &digest_len);
338 ASSERT_TRUE(rv);
339 if (!correct) {
340 LOG(LS_INFO) << "Setting bogus digest for server cert";
341 digest[0]++;
342 }
343 rv = client_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, digest,
344 digest_len);
345 ASSERT_TRUE(rv);
346
347
348 rv = client_identity_->certificate().ComputeDigest(rtc::DIGEST_SHA_1,
349 digest, 20, &digest_len);
350 ASSERT_TRUE(rv);
351 if (!correct) {
352 LOG(LS_INFO) << "Setting bogus digest for client cert";
353 digest[0]++;
354 }
355 rv = server_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, digest,
356 digest_len);
357 ASSERT_TRUE(rv);
358
359 identities_set_ = true;
360 }
361
Joachim Bauch831c5582015-05-20 12:48:41 +0200362 void SetupProtocolVersions(rtc::SSLProtocolVersion server_version,
363 rtc::SSLProtocolVersion client_version) {
364 server_ssl_->SetMaxProtocolVersion(server_version);
365 client_ssl_->SetMaxProtocolVersion(client_version);
366 }
367
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000368 void TestHandshake(bool expect_success = true) {
369 server_ssl_->SetMode(dtls_ ? rtc::SSL_MODE_DTLS :
370 rtc::SSL_MODE_TLS);
371 client_ssl_->SetMode(dtls_ ? rtc::SSL_MODE_DTLS :
372 rtc::SSL_MODE_TLS);
373
374 if (!dtls_) {
375 // Make sure we simulate a reliable network for TLS.
376 // This is just a check to make sure that people don't write wrong
377 // tests.
378 ASSERT((mtu_ == 1460) && (loss_ == 0) && (lose_first_packet_ == 0));
379 }
380
381 if (!identities_set_)
382 SetPeerIdentitiesByDigest(true);
383
384 // Start the handshake
385 int rv;
386
387 server_ssl_->SetServerRole();
388 rv = server_ssl_->StartSSLWithPeer();
389 ASSERT_EQ(0, rv);
390
391 rv = client_ssl_->StartSSLWithPeer();
392 ASSERT_EQ(0, rv);
393
394 // Now run the handshake
395 if (expect_success) {
396 EXPECT_TRUE_WAIT((client_ssl_->GetState() == rtc::SS_OPEN)
397 && (server_ssl_->GetState() == rtc::SS_OPEN),
398 handshake_wait_);
399 } else {
400 EXPECT_TRUE_WAIT(client_ssl_->GetState() == rtc::SS_CLOSED,
401 handshake_wait_);
402 }
403 }
404
jbauche488a0d2015-11-19 05:17:58 -0800405 rtc::StreamResult DataWritten(SSLDummyStreamBase *from, const void *data,
406 size_t data_len, size_t *written,
407 int *error) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000408 // Randomly drop loss_ percent of packets
Peter Boström0c4e06b2015-10-07 12:23:21 +0200409 if (rtc::CreateRandomId() % 100 < static_cast<uint32_t>(loss_)) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000410 LOG(LS_INFO) << "Randomly dropping packet, size=" << data_len;
411 *written = data_len;
412 return rtc::SR_SUCCESS;
413 }
414 if (dtls_ && (data_len > mtu_)) {
415 LOG(LS_INFO) << "Dropping packet > mtu, size=" << data_len;
416 *written = data_len;
417 return rtc::SR_SUCCESS;
418 }
419
420 // Optionally damage application data (type 23). Note that we don't damage
421 // handshake packets and we damage the last byte to keep the header
422 // intact but break the MAC.
423 if (damage_ && (*static_cast<const unsigned char *>(data) == 23)) {
424 std::vector<char> buf(data_len);
425
426 LOG(LS_INFO) << "Damaging packet";
427
428 memcpy(&buf[0], data, data_len);
429 buf[data_len - 1]++;
430
431 return from->WriteData(&buf[0], data_len, written, error);
432 }
433
434 return from->WriteData(data, data_len, written, error);
435 }
436
437 void SetDelay(int delay) {
438 delay_ = delay;
439 }
440 int GetDelay() { return delay_; }
441
442 void SetLoseFirstPacket(bool lose) {
443 lose_first_packet_ = lose;
444 }
445 bool GetLoseFirstPacket() { return lose_first_packet_; }
446
447 void SetLoss(int percent) {
448 loss_ = percent;
449 }
450
451 void SetDamage() {
452 damage_ = true;
453 }
454
455 void SetMtu(size_t mtu) {
456 mtu_ = mtu;
457 }
458
459 void SetHandshakeWait(int wait) {
460 handshake_wait_ = wait;
461 }
462
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800463 void SetDtlsSrtpCryptoSuites(const std::vector<int>& ciphers, bool client) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000464 if (client)
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800465 client_ssl_->SetDtlsSrtpCryptoSuites(ciphers);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000466 else
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800467 server_ssl_->SetDtlsSrtpCryptoSuites(ciphers);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000468 }
469
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800470 bool GetDtlsSrtpCryptoSuite(bool client, int* retval) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000471 if (client)
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800472 return client_ssl_->GetDtlsSrtpCryptoSuite(retval);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000473 else
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800474 return server_ssl_->GetDtlsSrtpCryptoSuite(retval);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000475 }
476
kwibergb4d01c42016-04-06 05:15:06 -0700477 rtc::scoped_ptr<rtc::SSLCertificate> GetPeerCertificate(bool client) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000478 if (client)
kwibergb4d01c42016-04-06 05:15:06 -0700479 return client_ssl_->GetPeerCertificate();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000480 else
kwibergb4d01c42016-04-06 05:15:06 -0700481 return server_ssl_->GetPeerCertificate();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000482 }
483
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -0700484 bool GetSslCipherSuite(bool client, int* retval) {
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000485 if (client)
Guo-wei Shieh456696a2015-09-30 21:48:54 -0700486 return client_ssl_->GetSslCipherSuite(retval);
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000487 else
Guo-wei Shieh456696a2015-09-30 21:48:54 -0700488 return server_ssl_->GetSslCipherSuite(retval);
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000489 }
490
torbjorng43166b82016-03-11 00:06:47 -0800491 int GetSslVersion(bool client) {
492 if (client)
493 return client_ssl_->GetSslVersion();
494 else
495 return server_ssl_->GetSslVersion();
496 }
497
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000498 bool ExportKeyingMaterial(const char *label,
499 const unsigned char *context,
500 size_t context_len,
501 bool use_context,
502 bool client,
503 unsigned char *result,
504 size_t result_len) {
505 if (client)
506 return client_ssl_->ExportKeyingMaterial(label,
507 context, context_len,
508 use_context,
509 result, result_len);
510 else
511 return server_ssl_->ExportKeyingMaterial(label,
512 context, context_len,
513 use_context,
514 result, result_len);
515 }
516
517 // To be implemented by subclasses.
518 virtual void WriteData() = 0;
519 virtual void ReadData(rtc::StreamInterface *stream) = 0;
520 virtual void TestTransfer(int size) = 0;
521
522 protected:
jbauche488a0d2015-11-19 05:17:58 -0800523 std::string client_cert_pem_;
524 std::string client_private_key_pem_;
525 rtc::KeyParams client_key_type_;
526 rtc::KeyParams server_key_type_;
527 SSLDummyStreamBase *client_stream_; // freed by client_ssl_ destructor
528 SSLDummyStreamBase *server_stream_; // freed by server_ssl_ destructor
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000529 rtc::scoped_ptr<rtc::SSLStreamAdapter> client_ssl_;
530 rtc::scoped_ptr<rtc::SSLStreamAdapter> server_ssl_;
531 rtc::SSLIdentity *client_identity_; // freed by client_ssl_ destructor
532 rtc::SSLIdentity *server_identity_; // freed by server_ssl_ destructor
533 int delay_;
534 size_t mtu_;
535 int loss_;
536 bool lose_first_packet_;
537 bool damage_;
538 bool dtls_;
539 int handshake_wait_;
540 bool identities_set_;
541};
542
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200543class SSLStreamAdapterTestTLS
544 : public SSLStreamAdapterTestBase,
torbjorng4e572472015-10-08 09:42:49 -0700545 public WithParamInterface<tuple<rtc::KeyParams, rtc::KeyParams>> {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000546 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200547 SSLStreamAdapterTestTLS()
548 : SSLStreamAdapterTestBase("",
549 "",
550 false,
551 ::testing::get<0>(GetParam()),
jbauche488a0d2015-11-19 05:17:58 -0800552 ::testing::get<1>(GetParam())),
553 client_buffer_(kFifoBufferSize),
554 server_buffer_(kFifoBufferSize) {
555 }
556
torbjorng7593aad2015-11-19 12:20:51 -0800557 void CreateStreams() override {
jbauche488a0d2015-11-19 05:17:58 -0800558 client_stream_ =
559 new SSLDummyStreamTLS(this, "c2s", &client_buffer_, &server_buffer_);
560 server_stream_ =
561 new SSLDummyStreamTLS(this, "s2c", &server_buffer_, &client_buffer_);
562 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000563
564 // Test data transfer for TLS
565 virtual void TestTransfer(int size) {
566 LOG(LS_INFO) << "Starting transfer test with " << size << " bytes";
567 // Create some dummy data to send.
568 size_t received;
569
570 send_stream_.ReserveSize(size);
571 for (int i = 0; i < size; ++i) {
572 char ch = static_cast<char>(i);
573 send_stream_.Write(&ch, 1, NULL, NULL);
574 }
575 send_stream_.Rewind();
576
577 // Prepare the receive stream.
578 recv_stream_.ReserveSize(size);
579
580 // Start sending
581 WriteData();
582
583 // Wait for the client to close
584 EXPECT_TRUE_WAIT(server_ssl_->GetState() == rtc::SS_CLOSED, 10000);
585
586 // Now check the data
587 recv_stream_.GetSize(&received);
588
589 EXPECT_EQ(static_cast<size_t>(size), received);
590 EXPECT_EQ(0, memcmp(send_stream_.GetBuffer(),
591 recv_stream_.GetBuffer(), size));
592 }
593
594 void WriteData() {
595 size_t position, tosend, size;
596 rtc::StreamResult rv;
597 size_t sent;
598 char block[kBlockSize];
599
600 send_stream_.GetSize(&size);
601 if (!size)
602 return;
603
604 for (;;) {
605 send_stream_.GetPosition(&position);
606 if (send_stream_.Read(block, sizeof(block), &tosend, NULL) !=
607 rtc::SR_EOS) {
608 rv = client_ssl_->Write(block, tosend, &sent, 0);
609
610 if (rv == rtc::SR_SUCCESS) {
611 send_stream_.SetPosition(position + sent);
612 LOG(LS_VERBOSE) << "Sent: " << position + sent;
613 } else if (rv == rtc::SR_BLOCK) {
614 LOG(LS_VERBOSE) << "Blocked...";
615 send_stream_.SetPosition(position);
616 break;
617 } else {
618 ADD_FAILURE();
619 break;
620 }
621 } else {
622 // Now close
623 LOG(LS_INFO) << "Wrote " << position << " bytes. Closing";
624 client_ssl_->Close();
625 break;
626 }
627 }
628 };
629
630 virtual void ReadData(rtc::StreamInterface *stream) {
631 char buffer[1600];
632 size_t bread;
633 int err2;
634 rtc::StreamResult r;
635
636 for (;;) {
637 r = stream->Read(buffer, sizeof(buffer), &bread, &err2);
638
639 if (r == rtc::SR_ERROR || r == rtc::SR_EOS) {
640 // Unfortunately, errors are the way that the stream adapter
torbjorng7593aad2015-11-19 12:20:51 -0800641 // signals close in OpenSSL.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000642 stream->Close();
643 return;
644 }
645
646 if (r == rtc::SR_BLOCK)
647 break;
648
649 ASSERT_EQ(rtc::SR_SUCCESS, r);
650 LOG(LS_INFO) << "Read " << bread;
651
652 recv_stream_.Write(buffer, bread, NULL, NULL);
653 }
654 }
655
656 private:
jbauche488a0d2015-11-19 05:17:58 -0800657 rtc::FifoBuffer client_buffer_;
658 rtc::FifoBuffer server_buffer_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000659 rtc::MemoryStream send_stream_;
660 rtc::MemoryStream recv_stream_;
661};
662
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200663class SSLStreamAdapterTestDTLS
664 : public SSLStreamAdapterTestBase,
torbjorng4e572472015-10-08 09:42:49 -0700665 public WithParamInterface<tuple<rtc::KeyParams, rtc::KeyParams>> {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000666 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200667 SSLStreamAdapterTestDTLS()
668 : SSLStreamAdapterTestBase("",
669 "",
670 true,
671 ::testing::get<0>(GetParam()),
672 ::testing::get<1>(GetParam())),
jbauche488a0d2015-11-19 05:17:58 -0800673 client_buffer_(kBufferCapacity, kDefaultBufferSize),
674 server_buffer_(kBufferCapacity, kDefaultBufferSize),
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200675 packet_size_(1000),
676 count_(0),
677 sent_(0) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000678
679 SSLStreamAdapterTestDTLS(const std::string& cert_pem,
680 const std::string& private_key_pem) :
681 SSLStreamAdapterTestBase(cert_pem, private_key_pem, true),
jbauche488a0d2015-11-19 05:17:58 -0800682 client_buffer_(kBufferCapacity, kDefaultBufferSize),
683 server_buffer_(kBufferCapacity, kDefaultBufferSize),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000684 packet_size_(1000), count_(0), sent_(0) {
685 }
686
torbjorng7593aad2015-11-19 12:20:51 -0800687 void CreateStreams() override {
jbauche488a0d2015-11-19 05:17:58 -0800688 client_stream_ =
689 new SSLDummyStreamDTLS(this, "c2s", &client_buffer_, &server_buffer_);
690 server_stream_ =
691 new SSLDummyStreamDTLS(this, "s2c", &server_buffer_, &client_buffer_);
692 }
693
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000694 virtual void WriteData() {
695 unsigned char *packet = new unsigned char[1600];
696
jbauche488a0d2015-11-19 05:17:58 -0800697 while (sent_ < count_) {
torbjorng7593aad2015-11-19 12:20:51 -0800698 unsigned int rand_state = sent_;
699 packet[0] = sent_;
700 for (size_t i = 1; i < packet_size_; i++) {
701 // This is a simple LC PRNG. Keep in synch with identical code below.
702 rand_state = (rand_state * 251 + 19937) >> 7;
703 packet[i] = rand_state & 0xff;
704 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000705
706 size_t sent;
torbjorng7593aad2015-11-19 12:20:51 -0800707 rtc::StreamResult rv = client_ssl_->Write(packet, packet_size_, &sent, 0);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000708 if (rv == rtc::SR_SUCCESS) {
709 LOG(LS_VERBOSE) << "Sent: " << sent_;
710 sent_++;
711 } else if (rv == rtc::SR_BLOCK) {
712 LOG(LS_VERBOSE) << "Blocked...";
713 break;
714 } else {
715 ADD_FAILURE();
716 break;
717 }
jbauche488a0d2015-11-19 05:17:58 -0800718 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000719
720 delete [] packet;
721 }
722
723 virtual void ReadData(rtc::StreamInterface *stream) {
724 unsigned char buffer[2000];
725 size_t bread;
726 int err2;
727 rtc::StreamResult r;
728
729 for (;;) {
730 r = stream->Read(buffer, 2000, &bread, &err2);
731
732 if (r == rtc::SR_ERROR) {
733 // Unfortunately, errors are the way that the stream adapter
734 // signals close right now
735 stream->Close();
736 return;
737 }
738
739 if (r == rtc::SR_BLOCK)
740 break;
741
742 ASSERT_EQ(rtc::SR_SUCCESS, r);
743 LOG(LS_INFO) << "Read " << bread;
744
745 // Now parse the datagram
746 ASSERT_EQ(packet_size_, bread);
torbjorng7593aad2015-11-19 12:20:51 -0800747 unsigned char packet_num = buffer[0];
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000748
torbjorng7593aad2015-11-19 12:20:51 -0800749 unsigned int rand_state = packet_num;
750 for (size_t i = 1; i < packet_size_; i++) {
751 // This is a simple LC PRNG. Keep in synch with identical code above.
752 rand_state = (rand_state * 251 + 19937) >> 7;
753 ASSERT_EQ(rand_state & 0xff, buffer[i]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000754 }
755 received_.insert(packet_num);
756 }
757 }
758
759 virtual void TestTransfer(int count) {
760 count_ = count;
761
762 WriteData();
763
764 EXPECT_TRUE_WAIT(sent_ == count_, 10000);
765 LOG(LS_INFO) << "sent_ == " << sent_;
766
767 if (damage_) {
768 WAIT(false, 2000);
769 EXPECT_EQ(0U, received_.size());
770 } else if (loss_ == 0) {
771 EXPECT_EQ_WAIT(static_cast<size_t>(sent_), received_.size(), 1000);
772 } else {
773 LOG(LS_INFO) << "Sent " << sent_ << " packets; received " <<
774 received_.size();
775 }
776 };
777
778 private:
jbauche488a0d2015-11-19 05:17:58 -0800779 BufferQueueStream client_buffer_;
780 BufferQueueStream server_buffer_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000781 size_t packet_size_;
782 int count_;
783 int sent_;
784 std::set<int> received_;
785};
786
787
jbauche488a0d2015-11-19 05:17:58 -0800788rtc::StreamResult SSLDummyStreamBase::Write(const void* data, size_t data_len,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000789 size_t* written, int* error) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000790 LOG(LS_INFO) << "Writing to loopback " << data_len;
791
792 if (first_packet_) {
793 first_packet_ = false;
jbauche488a0d2015-11-19 05:17:58 -0800794 if (test_base_->GetLoseFirstPacket()) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000795 LOG(LS_INFO) << "Losing initial packet of length " << data_len;
torbjorng7593aad2015-11-19 12:20:51 -0800796 *written = data_len; // Fake successful writing also to writer.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000797 return rtc::SR_SUCCESS;
798 }
799 }
800
jbauche488a0d2015-11-19 05:17:58 -0800801 return test_base_->DataWritten(this, data, data_len, written, error);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000802};
803
804class SSLStreamAdapterTestDTLSFromPEMStrings : public SSLStreamAdapterTestDTLS {
805 public:
806 SSLStreamAdapterTestDTLSFromPEMStrings() :
807 SSLStreamAdapterTestDTLS(kCERT_PEM, kRSA_PRIVATE_KEY_PEM) {
808 }
809};
810
811// Basic tests: TLS
812
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000813// Test that we can make a handshake work
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200814TEST_P(SSLStreamAdapterTestTLS, TestTLSConnect) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000815 TestHandshake();
816};
817
jiayl@webrtc.orgf1d751c2014-09-25 16:38:46 +0000818// Test that closing the connection on one side updates the other side.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200819TEST_P(SSLStreamAdapterTestTLS, TestTLSClose) {
jiayl@webrtc.orgf1d751c2014-09-25 16:38:46 +0000820 TestHandshake();
821 client_ssl_->Close();
822 EXPECT_EQ_WAIT(rtc::SS_CLOSED, server_ssl_->GetState(), handshake_wait_);
823};
824
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000825// Test transfer -- trivial
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200826TEST_P(SSLStreamAdapterTestTLS, TestTLSTransfer) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000827 TestHandshake();
828 TestTransfer(100000);
829};
830
831// Test read-write after close.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200832TEST_P(SSLStreamAdapterTestTLS, ReadWriteAfterClose) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000833 TestHandshake();
834 TestTransfer(100000);
835 client_ssl_->Close();
836
837 rtc::StreamResult rv;
838 char block[kBlockSize];
839 size_t dummy;
840
841 // It's an error to write after closed.
842 rv = client_ssl_->Write(block, sizeof(block), &dummy, NULL);
843 ASSERT_EQ(rtc::SR_ERROR, rv);
844
845 // But after closed read gives you EOS.
846 rv = client_ssl_->Read(block, sizeof(block), &dummy, NULL);
847 ASSERT_EQ(rtc::SR_EOS, rv);
848};
849
850// Test a handshake with a bogus peer digest
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200851TEST_P(SSLStreamAdapterTestTLS, TestTLSBogusDigest) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000852 SetPeerIdentitiesByDigest(false);
853 TestHandshake(false);
854};
855
856// Test moving a bunch of data
857
858// Basic tests: DTLS
859// Test that we can make a handshake work
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200860TEST_P(SSLStreamAdapterTestDTLS, TestDTLSConnect) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000861 MAYBE_SKIP_TEST(HaveDtls);
862 TestHandshake();
863};
864
865// Test that we can make a handshake work if the first packet in
866// each direction is lost. This gives us predictable loss
867// rather than having to tune random
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200868TEST_P(SSLStreamAdapterTestDTLS, TestDTLSConnectWithLostFirstPacket) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000869 MAYBE_SKIP_TEST(HaveDtls);
870 SetLoseFirstPacket(true);
871 TestHandshake();
872};
873
874// Test a handshake with loss and delay
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200875TEST_P(SSLStreamAdapterTestDTLS, TestDTLSConnectWithLostFirstPacketDelay2s) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000876 MAYBE_SKIP_TEST(HaveDtls);
877 SetLoseFirstPacket(true);
878 SetDelay(2000);
879 SetHandshakeWait(20000);
880 TestHandshake();
881};
882
883// Test a handshake with small MTU
pbos@webrtc.org127ca3f2014-10-09 07:52:03 +0000884// Disabled due to https://code.google.com/p/webrtc/issues/detail?id=3910
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200885TEST_P(SSLStreamAdapterTestDTLS, DISABLED_TestDTLSConnectWithSmallMtu) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000886 MAYBE_SKIP_TEST(HaveDtls);
887 SetMtu(700);
888 SetHandshakeWait(20000);
889 TestHandshake();
890};
891
892// Test transfer -- trivial
jbauche488a0d2015-11-19 05:17:58 -0800893TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransfer) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000894 MAYBE_SKIP_TEST(HaveDtls);
895 TestHandshake();
896 TestTransfer(100);
897};
898
jbauche488a0d2015-11-19 05:17:58 -0800899TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransferWithLoss) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000900 MAYBE_SKIP_TEST(HaveDtls);
901 TestHandshake();
902 SetLoss(10);
903 TestTransfer(100);
904};
905
jbauche488a0d2015-11-19 05:17:58 -0800906TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransferWithDamage) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000907 MAYBE_SKIP_TEST(HaveDtls);
908 SetDamage(); // Must be called first because first packet
909 // write happens at end of handshake.
910 TestHandshake();
911 TestTransfer(100);
912};
913
914// Test DTLS-SRTP with all high ciphers
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200915TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpHigh) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000916 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800917 std::vector<int> high;
918 high.push_back(rtc::SRTP_AES128_CM_SHA1_80);
919 SetDtlsSrtpCryptoSuites(high, true);
920 SetDtlsSrtpCryptoSuites(high, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000921 TestHandshake();
922
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800923 int client_cipher;
924 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
925 int server_cipher;
926 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000927
928 ASSERT_EQ(client_cipher, server_cipher);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800929 ASSERT_EQ(client_cipher, rtc::SRTP_AES128_CM_SHA1_80);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000930};
931
932// Test DTLS-SRTP with all low ciphers
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200933TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpLow) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000934 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800935 std::vector<int> low;
936 low.push_back(rtc::SRTP_AES128_CM_SHA1_32);
937 SetDtlsSrtpCryptoSuites(low, true);
938 SetDtlsSrtpCryptoSuites(low, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000939 TestHandshake();
940
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800941 int client_cipher;
942 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
943 int server_cipher;
944 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000945
946 ASSERT_EQ(client_cipher, server_cipher);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800947 ASSERT_EQ(client_cipher, rtc::SRTP_AES128_CM_SHA1_32);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000948};
949
950
951// Test DTLS-SRTP with a mismatch -- should not converge
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200952TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpHighLow) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000953 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800954 std::vector<int> high;
955 high.push_back(rtc::SRTP_AES128_CM_SHA1_80);
956 std::vector<int> low;
957 low.push_back(rtc::SRTP_AES128_CM_SHA1_32);
958 SetDtlsSrtpCryptoSuites(high, true);
959 SetDtlsSrtpCryptoSuites(low, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000960 TestHandshake();
961
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800962 int client_cipher;
963 ASSERT_FALSE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
964 int server_cipher;
965 ASSERT_FALSE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000966};
967
968// Test DTLS-SRTP with each side being mixed -- should select high
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200969TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpMixed) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000970 MAYBE_SKIP_TEST(HaveDtlsSrtp);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800971 std::vector<int> mixed;
972 mixed.push_back(rtc::SRTP_AES128_CM_SHA1_80);
973 mixed.push_back(rtc::SRTP_AES128_CM_SHA1_32);
974 SetDtlsSrtpCryptoSuites(mixed, true);
975 SetDtlsSrtpCryptoSuites(mixed, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000976 TestHandshake();
977
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800978 int client_cipher;
979 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
980 int server_cipher;
981 ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000982
983 ASSERT_EQ(client_cipher, server_cipher);
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800984 ASSERT_EQ(client_cipher, rtc::SRTP_AES128_CM_SHA1_80);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000985};
986
987// Test an exporter
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200988TEST_P(SSLStreamAdapterTestDTLS, TestDTLSExporter) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000989 MAYBE_SKIP_TEST(HaveExporter);
990 TestHandshake();
991 unsigned char client_out[20];
992 unsigned char server_out[20];
993
994 bool result;
995 result = ExportKeyingMaterial(kExporterLabel,
996 kExporterContext, kExporterContextLen,
997 true, true,
998 client_out, sizeof(client_out));
999 ASSERT_TRUE(result);
1000
1001 result = ExportKeyingMaterial(kExporterLabel,
1002 kExporterContext, kExporterContextLen,
1003 true, false,
1004 server_out, sizeof(server_out));
1005 ASSERT_TRUE(result);
1006
1007 ASSERT_TRUE(!memcmp(client_out, server_out, sizeof(client_out)));
1008}
1009
1010// Test not yet valid certificates are not rejected.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +02001011TEST_P(SSLStreamAdapterTestDTLS, TestCertNotYetValid) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001012 MAYBE_SKIP_TEST(HaveDtls);
1013 long one_day = 60 * 60 * 24;
1014 // Make the certificates not valid until one day later.
1015 ResetIdentitiesWithValidity(one_day, one_day);
1016 TestHandshake();
1017}
1018
1019// Test expired certificates are not rejected.
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +02001020TEST_P(SSLStreamAdapterTestDTLS, TestCertExpired) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001021 MAYBE_SKIP_TEST(HaveDtls);
1022 long one_day = 60 * 60 * 24;
1023 // Make the certificates already expired.
1024 ResetIdentitiesWithValidity(-one_day, -one_day);
1025 TestHandshake();
1026}
1027
1028// Test data transfer using certs created from strings.
torbjorng7593aad2015-11-19 12:20:51 -08001029TEST_F(SSLStreamAdapterTestDTLSFromPEMStrings, TestTransfer) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001030 MAYBE_SKIP_TEST(HaveDtls);
1031 TestHandshake();
1032 TestTransfer(100);
1033}
1034
1035// Test getting the remote certificate.
torbjorng7593aad2015-11-19 12:20:51 -08001036TEST_F(SSLStreamAdapterTestDTLSFromPEMStrings, TestDTLSGetPeerCertificate) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001037 MAYBE_SKIP_TEST(HaveDtls);
1038
1039 // Peer certificates haven't been received yet.
kwibergb4d01c42016-04-06 05:15:06 -07001040 ASSERT_FALSE(GetPeerCertificate(true));
1041 ASSERT_FALSE(GetPeerCertificate(false));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001042
1043 TestHandshake();
1044
1045 // The client should have a peer certificate after the handshake.
kwibergb4d01c42016-04-06 05:15:06 -07001046 rtc::scoped_ptr<rtc::SSLCertificate> client_peer_cert =
1047 GetPeerCertificate(true);
1048 ASSERT_TRUE(client_peer_cert);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001049
1050 // It's not kCERT_PEM.
1051 std::string client_peer_string = client_peer_cert->ToPEMString();
1052 ASSERT_NE(kCERT_PEM, client_peer_string);
1053
1054 // It must not have a chain, because the test certs are self-signed.
kwibergf5d47862016-03-15 12:53:24 -07001055 ASSERT_FALSE(client_peer_cert->GetChain());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001056
1057 // The server should have a peer certificate after the handshake.
kwibergb4d01c42016-04-06 05:15:06 -07001058 rtc::scoped_ptr<rtc::SSLCertificate> server_peer_cert =
1059 GetPeerCertificate(false);
1060 ASSERT_TRUE(server_peer_cert);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001061
1062 // It's kCERT_PEM
1063 ASSERT_EQ(kCERT_PEM, server_peer_cert->ToPEMString());
1064
1065 // It must not have a chain, because the test certs are self-signed.
kwibergf5d47862016-03-15 12:53:24 -07001066 ASSERT_FALSE(server_peer_cert->GetChain());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001067}
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001068
1069// Test getting the used DTLS ciphers.
Joachim Bauch831c5582015-05-20 12:48:41 +02001070// DTLS 1.2 enabled for neither client nor server -> DTLS 1.0 will be used.
torbjorng43166b82016-03-11 00:06:47 -08001071TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuite) {
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001072 MAYBE_SKIP_TEST(HaveDtls);
Joachim Bauch831c5582015-05-20 12:48:41 +02001073 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10);
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001074 TestHandshake();
1075
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001076 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001077 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001078 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001079 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001080
torbjorng43166b82016-03-11 00:06:47 -08001081 ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_10, GetSslVersion(true));
1082 ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_10, GetSslVersion(false));
1083
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001084 ASSERT_EQ(client_cipher, server_cipher);
torbjorng43166b82016-03-11 00:06:47 -08001085 ASSERT_TRUE(rtc::SSLStreamAdapter::IsAcceptableCipher(
1086 server_cipher, ::testing::get<1>(GetParam()).type()));
Joachim Bauch831c5582015-05-20 12:48:41 +02001087}
1088
1089// Test getting the used DTLS 1.2 ciphers.
1090// DTLS 1.2 enabled for client and server -> DTLS 1.2 will be used.
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001091TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Both) {
Joachim Bauch831c5582015-05-20 12:48:41 +02001092 MAYBE_SKIP_TEST(HaveDtls);
1093 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_12);
1094 TestHandshake();
1095
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001096 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001097 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001098 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001099 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
Joachim Bauch831c5582015-05-20 12:48:41 +02001100
torbjorng43166b82016-03-11 00:06:47 -08001101 ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_12, GetSslVersion(true));
1102 ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_12, GetSslVersion(false));
1103
Joachim Bauch831c5582015-05-20 12:48:41 +02001104 ASSERT_EQ(client_cipher, server_cipher);
torbjorng43166b82016-03-11 00:06:47 -08001105 ASSERT_TRUE(rtc::SSLStreamAdapter::IsAcceptableCipher(
1106 server_cipher, ::testing::get<1>(GetParam()).type()));
Joachim Bauch831c5582015-05-20 12:48:41 +02001107}
1108
1109// DTLS 1.2 enabled for client only -> DTLS 1.0 will be used.
torbjorng43166b82016-03-11 00:06:47 -08001110TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Client) {
Joachim Bauch831c5582015-05-20 12:48:41 +02001111 MAYBE_SKIP_TEST(HaveDtls);
1112 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_12);
1113 TestHandshake();
1114
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001115 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001116 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001117 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001118 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
Joachim Bauch831c5582015-05-20 12:48:41 +02001119
torbjorng43166b82016-03-11 00:06:47 -08001120 ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_10, GetSslVersion(true));
1121 ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_10, GetSslVersion(false));
1122
Joachim Bauch831c5582015-05-20 12:48:41 +02001123 ASSERT_EQ(client_cipher, server_cipher);
torbjorng43166b82016-03-11 00:06:47 -08001124 ASSERT_TRUE(rtc::SSLStreamAdapter::IsAcceptableCipher(
1125 server_cipher, ::testing::get<1>(GetParam()).type()));
Joachim Bauch831c5582015-05-20 12:48:41 +02001126}
1127
1128// DTLS 1.2 enabled for server only -> DTLS 1.0 will be used.
torbjorng43166b82016-03-11 00:06:47 -08001129TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Server) {
Joachim Bauch831c5582015-05-20 12:48:41 +02001130 MAYBE_SKIP_TEST(HaveDtls);
1131 SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_10);
1132 TestHandshake();
1133
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001134 int client_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001135 ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
Guo-wei Shieh6caafbe2015-10-05 12:43:27 -07001136 int server_cipher;
Guo-wei Shieh456696a2015-09-30 21:48:54 -07001137 ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
Joachim Bauch831c5582015-05-20 12:48:41 +02001138
torbjorng43166b82016-03-11 00:06:47 -08001139 ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_10, GetSslVersion(true));
1140 ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_10, GetSslVersion(false));
1141
Joachim Bauch831c5582015-05-20 12:48:41 +02001142 ASSERT_EQ(client_cipher, server_cipher);
torbjorng43166b82016-03-11 00:06:47 -08001143 ASSERT_TRUE(rtc::SSLStreamAdapter::IsAcceptableCipher(
1144 server_cipher, ::testing::get<1>(GetParam()).type()));
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001145}
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +02001146
torbjorng4e572472015-10-08 09:42:49 -07001147// The RSA keysizes here might look strange, why not include the RFC's size
1148// 2048?. The reason is test case slowness; testing two sizes to exercise
1149// parametrization is sufficient.
1150INSTANTIATE_TEST_CASE_P(
1151 SSLStreamAdapterTestsTLS,
1152 SSLStreamAdapterTestTLS,
1153 Combine(Values(rtc::KeyParams::RSA(1024, 65537),
1154 rtc::KeyParams::RSA(1152, 65537),
1155 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256)),
1156 Values(rtc::KeyParams::RSA(1024, 65537),
1157 rtc::KeyParams::RSA(1152, 65537),
1158 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256))));
1159INSTANTIATE_TEST_CASE_P(
1160 SSLStreamAdapterTestsDTLS,
1161 SSLStreamAdapterTestDTLS,
1162 Combine(Values(rtc::KeyParams::RSA(1024, 65537),
1163 rtc::KeyParams::RSA(1152, 65537),
1164 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256)),
1165 Values(rtc::KeyParams::RSA(1024, 65537),
1166 rtc::KeyParams::RSA(1152, 65537),
1167 rtc::KeyParams::ECDSA(rtc::EC_NIST_P256))));