blob: 831136c8396896fb476a25010bebbfcb8e84d33b [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
2 * Copyright 2004 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#if HAVE_CONFIG_H
12#include "config.h"
13#endif // HAVE_CONFIG_H
14
15#if HAVE_OPENSSL_SSL_H
16
17#include "webrtc/base/opensslstreamadapter.h"
18
19#include <openssl/bio.h>
20#include <openssl/crypto.h>
21#include <openssl/err.h>
22#include <openssl/rand.h>
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +000023#include <openssl/tls1.h>
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000024#include <openssl/x509v3.h>
25
26#include <vector>
27
28#include "webrtc/base/common.h"
29#include "webrtc/base/logging.h"
Tommid44c0772016-03-11 17:12:32 -080030#include "webrtc/base/safe_conversions.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000031#include "webrtc/base/stream.h"
32#include "webrtc/base/openssl.h"
33#include "webrtc/base/openssladapter.h"
34#include "webrtc/base/openssldigest.h"
35#include "webrtc/base/opensslidentity.h"
36#include "webrtc/base/stringutils.h"
37#include "webrtc/base/thread.h"
38
39namespace rtc {
40
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -080041// SRTP cipher suite table. |internal_name| is used to construct a
42// colon-separated profile strings which is needed by
43// SSL_CTX_set_tlsext_use_srtp().
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000044struct SrtpCipherMapEntry {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000045 const char* internal_name;
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -080046 const int id;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000047};
48
49// This isn't elegant, but it's better than an external reference
50static SrtpCipherMapEntry SrtpCipherMap[] = {
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -080051 {"SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80},
52 {"SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32},
53 {nullptr, 0}};
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +000054
Guo-wei Shieh456696a2015-09-30 21:48:54 -070055#if defined(_MSC_VER)
56#pragma warning(push)
57#pragma warning(disable : 4309)
58#pragma warning(disable : 4310)
59#endif // defined(_MSC_VER)
60
Guo-wei Shieh456696a2015-09-30 21:48:54 -070061#if defined(_MSC_VER)
62#pragma warning(pop)
63#endif // defined(_MSC_VER)
64
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000065//////////////////////////////////////////////////////////////////////
66// StreamBIO
67//////////////////////////////////////////////////////////////////////
68
69static int stream_write(BIO* h, const char* buf, int num);
70static int stream_read(BIO* h, char* buf, int size);
71static int stream_puts(BIO* h, const char* str);
72static long stream_ctrl(BIO* h, int cmd, long arg1, void* arg2);
73static int stream_new(BIO* h);
74static int stream_free(BIO* data);
75
davidben@webrtc.org36d5c3c2015-01-22 23:06:17 +000076// TODO(davidben): This should be const once BoringSSL is assumed.
77static BIO_METHOD methods_stream = {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000078 BIO_TYPE_BIO,
79 "stream",
80 stream_write,
81 stream_read,
82 stream_puts,
83 0,
84 stream_ctrl,
85 stream_new,
86 stream_free,
87 NULL,
88};
89
davidben@webrtc.org36d5c3c2015-01-22 23:06:17 +000090static BIO_METHOD* BIO_s_stream() { return(&methods_stream); }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000091
92static BIO* BIO_new_stream(StreamInterface* stream) {
93 BIO* ret = BIO_new(BIO_s_stream());
94 if (ret == NULL)
95 return NULL;
96 ret->ptr = stream;
97 return ret;
98}
99
100// bio methods return 1 (or at least non-zero) on success and 0 on failure.
101
102static int stream_new(BIO* b) {
103 b->shutdown = 0;
104 b->init = 1;
105 b->num = 0; // 1 means end-of-stream
106 b->ptr = 0;
107 return 1;
108}
109
110static int stream_free(BIO* b) {
111 if (b == NULL)
112 return 0;
113 return 1;
114}
115
116static int stream_read(BIO* b, char* out, int outl) {
117 if (!out)
118 return -1;
119 StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);
120 BIO_clear_retry_flags(b);
121 size_t read;
122 int error;
123 StreamResult result = stream->Read(out, outl, &read, &error);
124 if (result == SR_SUCCESS) {
henrike@webrtc.orgd89b69a2014-11-06 17:23:09 +0000125 return checked_cast<int>(read);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000126 } else if (result == SR_EOS) {
127 b->num = 1;
128 } else if (result == SR_BLOCK) {
129 BIO_set_retry_read(b);
130 }
131 return -1;
132}
133
134static int stream_write(BIO* b, const char* in, int inl) {
135 if (!in)
136 return -1;
137 StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);
138 BIO_clear_retry_flags(b);
139 size_t written;
140 int error;
141 StreamResult result = stream->Write(in, inl, &written, &error);
142 if (result == SR_SUCCESS) {
henrike@webrtc.orgd89b69a2014-11-06 17:23:09 +0000143 return checked_cast<int>(written);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000144 } else if (result == SR_BLOCK) {
145 BIO_set_retry_write(b);
146 }
147 return -1;
148}
149
150static int stream_puts(BIO* b, const char* str) {
henrike@webrtc.orgd89b69a2014-11-06 17:23:09 +0000151 return stream_write(b, str, checked_cast<int>(strlen(str)));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000152}
153
154static long stream_ctrl(BIO* b, int cmd, long num, void* ptr) {
henrike@webrtc.org14abcc72014-05-16 16:54:44 +0000155 RTC_UNUSED(num);
156 RTC_UNUSED(ptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000157
158 switch (cmd) {
159 case BIO_CTRL_RESET:
160 return 0;
161 case BIO_CTRL_EOF:
162 return b->num;
163 case BIO_CTRL_WPENDING:
164 case BIO_CTRL_PENDING:
165 return 0;
166 case BIO_CTRL_FLUSH:
167 return 1;
Henrik Lundinf4baca52015-06-10 09:45:58 +0200168 case BIO_CTRL_DGRAM_QUERY_MTU:
169 // openssl defaults to mtu=256 unless we return something here.
170 // The handshake doesn't actually need to send packets above 1k,
171 // so this seems like a sensible value that should work in most cases.
172 // Webrtc uses the same value for video packets.
173 return 1200;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000174 default:
175 return 0;
176 }
177}
178
179/////////////////////////////////////////////////////////////////////////////
180// OpenSSLStreamAdapter
181/////////////////////////////////////////////////////////////////////////////
182
183OpenSSLStreamAdapter::OpenSSLStreamAdapter(StreamInterface* stream)
184 : SSLStreamAdapter(stream),
185 state_(SSL_NONE),
186 role_(SSL_CLIENT),
Guo-wei Shieha7446d22016-01-11 15:27:03 -0800187 ssl_read_needs_write_(false),
188 ssl_write_needs_read_(false),
189 ssl_(NULL),
190 ssl_ctx_(NULL),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000191 custom_verification_succeeded_(false),
Joachim Bauch831c5582015-05-20 12:48:41 +0200192 ssl_mode_(SSL_MODE_TLS),
Guo-wei Shieha7446d22016-01-11 15:27:03 -0800193 ssl_max_version_(SSL_PROTOCOL_TLS_12) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000194
195OpenSSLStreamAdapter::~OpenSSLStreamAdapter() {
196 Cleanup();
197}
198
199void OpenSSLStreamAdapter::SetIdentity(SSLIdentity* identity) {
200 ASSERT(!identity_);
201 identity_.reset(static_cast<OpenSSLIdentity*>(identity));
202}
203
204void OpenSSLStreamAdapter::SetServerRole(SSLRole role) {
205 role_ = role;
206}
207
208bool OpenSSLStreamAdapter::GetPeerCertificate(SSLCertificate** cert) const {
209 if (!peer_certificate_)
210 return false;
211
212 *cert = peer_certificate_->GetReference();
213 return true;
214}
215
216bool OpenSSLStreamAdapter::SetPeerCertificateDigest(const std::string
217 &digest_alg,
218 const unsigned char*
219 digest_val,
220 size_t digest_len) {
221 ASSERT(!peer_certificate_);
222 ASSERT(peer_certificate_digest_algorithm_.size() == 0);
223 ASSERT(ssl_server_name_.empty());
224 size_t expected_len;
225
226 if (!OpenSSLDigest::GetDigestSize(digest_alg, &expected_len)) {
227 LOG(LS_WARNING) << "Unknown digest algorithm: " << digest_alg;
228 return false;
229 }
230 if (expected_len != digest_len)
231 return false;
232
233 peer_certificate_digest_value_.SetData(digest_val, digest_len);
234 peer_certificate_digest_algorithm_ = digest_alg;
235
236 return true;
237}
238
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800239std::string OpenSSLStreamAdapter::SslCipherSuiteToName(int cipher_suite) {
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800240 const SSL_CIPHER* ssl_cipher = SSL_get_cipher_by_value(cipher_suite);
Guo-wei Shieh456696a2015-09-30 21:48:54 -0700241 if (!ssl_cipher) {
242 return std::string();
243 }
244 char* cipher_name = SSL_CIPHER_get_rfc_name(ssl_cipher);
245 std::string rfc_name = std::string(cipher_name);
246 OPENSSL_free(cipher_name);
247 return rfc_name;
Guo-wei Shieh456696a2015-09-30 21:48:54 -0700248}
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000249
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800250bool OpenSSLStreamAdapter::GetSslCipherSuite(int* cipher_suite) {
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000251 if (state_ != SSL_CONNECTED)
252 return false;
253
254 const SSL_CIPHER* current_cipher = SSL_get_current_cipher(ssl_);
255 if (current_cipher == NULL) {
256 return false;
257 }
258
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800259 *cipher_suite = static_cast<uint16_t>(SSL_CIPHER_get_id(current_cipher));
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000260 return true;
261}
262
torbjorng43166b82016-03-11 00:06:47 -0800263int OpenSSLStreamAdapter::GetSslVersion() const {
264 if (state_ != SSL_CONNECTED)
265 return -1;
266
267 int ssl_version = SSL_version(ssl_);
268 if (ssl_mode_ == SSL_MODE_DTLS) {
269 if (ssl_version == DTLS1_VERSION)
270 return SSL_PROTOCOL_DTLS_10;
271 else if (ssl_version == DTLS1_2_VERSION)
272 return SSL_PROTOCOL_DTLS_12;
273 } else {
274 if (ssl_version == TLS1_VERSION)
275 return SSL_PROTOCOL_TLS_10;
276 else if (ssl_version == TLS1_1_VERSION)
277 return SSL_PROTOCOL_TLS_11;
278 else if (ssl_version == TLS1_2_VERSION)
279 return SSL_PROTOCOL_TLS_12;
280 }
281
282 return -1;
283}
284
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000285// Key Extractor interface
286bool OpenSSLStreamAdapter::ExportKeyingMaterial(const std::string& label,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200287 const uint8_t* context,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000288 size_t context_len,
289 bool use_context,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200290 uint8_t* result,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000291 size_t result_len) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000292 int i;
293
Peter Boström0c4e06b2015-10-07 12:23:21 +0200294 i = SSL_export_keying_material(ssl_, result, result_len, label.c_str(),
295 label.length(), const_cast<uint8_t*>(context),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000296 context_len, use_context);
297
298 if (i != 1)
299 return false;
300
301 return true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000302}
303
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800304bool OpenSSLStreamAdapter::SetDtlsSrtpCryptoSuites(
305 const std::vector<int>& ciphers) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000306 std::string internal_ciphers;
307
308 if (state_ != SSL_NONE)
309 return false;
310
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800311 for (std::vector<int>::const_iterator cipher = ciphers.begin();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000312 cipher != ciphers.end(); ++cipher) {
313 bool found = false;
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800314 for (SrtpCipherMapEntry* entry = SrtpCipherMap; entry->internal_name;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000315 ++entry) {
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800316 if (*cipher == entry->id) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000317 found = true;
318 if (!internal_ciphers.empty())
319 internal_ciphers += ":";
320 internal_ciphers += entry->internal_name;
321 break;
322 }
323 }
324
325 if (!found) {
326 LOG(LS_ERROR) << "Could not find cipher: " << *cipher;
327 return false;
328 }
329 }
330
331 if (internal_ciphers.empty())
332 return false;
333
334 srtp_ciphers_ = internal_ciphers;
335 return true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000336}
337
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800338bool OpenSSLStreamAdapter::GetDtlsSrtpCryptoSuite(int* crypto_suite) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000339 ASSERT(state_ == SSL_CONNECTED);
340 if (state_ != SSL_CONNECTED)
341 return false;
342
henrike@webrtc.orgc10ecea2015-01-07 17:59:28 +0000343 const SRTP_PROTECTION_PROFILE *srtp_profile =
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000344 SSL_get_selected_srtp_profile(ssl_);
345
346 if (!srtp_profile)
347 return false;
348
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800349 *crypto_suite = srtp_profile->id;
350 ASSERT(!SrtpCryptoSuiteToName(*crypto_suite).empty());
351 return true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000352}
353
354int OpenSSLStreamAdapter::StartSSLWithServer(const char* server_name) {
355 ASSERT(server_name != NULL && server_name[0] != '\0');
356 ssl_server_name_ = server_name;
357 return StartSSL();
358}
359
360int OpenSSLStreamAdapter::StartSSLWithPeer() {
361 ASSERT(ssl_server_name_.empty());
362 // It is permitted to specify peer_certificate_ only later.
363 return StartSSL();
364}
365
366void OpenSSLStreamAdapter::SetMode(SSLMode mode) {
367 ASSERT(state_ == SSL_NONE);
368 ssl_mode_ = mode;
369}
370
Joachim Bauch831c5582015-05-20 12:48:41 +0200371void OpenSSLStreamAdapter::SetMaxProtocolVersion(SSLProtocolVersion version) {
372 ASSERT(ssl_ctx_ == NULL);
373 ssl_max_version_ = version;
374}
375
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000376//
377// StreamInterface Implementation
378//
379
380StreamResult OpenSSLStreamAdapter::Write(const void* data, size_t data_len,
381 size_t* written, int* error) {
382 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Write(" << data_len << ")";
383
384 switch (state_) {
385 case SSL_NONE:
386 // pass-through in clear text
387 return StreamAdapterInterface::Write(data, data_len, written, error);
388
389 case SSL_WAIT:
390 case SSL_CONNECTING:
391 return SR_BLOCK;
392
393 case SSL_CONNECTED:
394 break;
395
396 case SSL_ERROR:
397 case SSL_CLOSED:
398 default:
399 if (error)
400 *error = ssl_error_code_;
401 return SR_ERROR;
402 }
403
404 // OpenSSL will return an error if we try to write zero bytes
405 if (data_len == 0) {
406 if (written)
407 *written = 0;
408 return SR_SUCCESS;
409 }
410
411 ssl_write_needs_read_ = false;
412
henrike@webrtc.orgd89b69a2014-11-06 17:23:09 +0000413 int code = SSL_write(ssl_, data, checked_cast<int>(data_len));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000414 int ssl_error = SSL_get_error(ssl_, code);
415 switch (ssl_error) {
416 case SSL_ERROR_NONE:
417 LOG(LS_VERBOSE) << " -- success";
418 ASSERT(0 < code && static_cast<unsigned>(code) <= data_len);
419 if (written)
420 *written = code;
421 return SR_SUCCESS;
422 case SSL_ERROR_WANT_READ:
423 LOG(LS_VERBOSE) << " -- error want read";
424 ssl_write_needs_read_ = true;
425 return SR_BLOCK;
426 case SSL_ERROR_WANT_WRITE:
427 LOG(LS_VERBOSE) << " -- error want write";
428 return SR_BLOCK;
429
430 case SSL_ERROR_ZERO_RETURN:
431 default:
432 Error("SSL_write", (ssl_error ? ssl_error : -1), false);
433 if (error)
434 *error = ssl_error_code_;
435 return SR_ERROR;
436 }
437 // not reached
438}
439
440StreamResult OpenSSLStreamAdapter::Read(void* data, size_t data_len,
441 size_t* read, int* error) {
442 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Read(" << data_len << ")";
443 switch (state_) {
444 case SSL_NONE:
445 // pass-through in clear text
446 return StreamAdapterInterface::Read(data, data_len, read, error);
447
448 case SSL_WAIT:
449 case SSL_CONNECTING:
450 return SR_BLOCK;
451
452 case SSL_CONNECTED:
453 break;
454
455 case SSL_CLOSED:
456 return SR_EOS;
457
458 case SSL_ERROR:
459 default:
460 if (error)
461 *error = ssl_error_code_;
462 return SR_ERROR;
463 }
464
465 // Don't trust OpenSSL with zero byte reads
466 if (data_len == 0) {
467 if (read)
468 *read = 0;
469 return SR_SUCCESS;
470 }
471
472 ssl_read_needs_write_ = false;
473
henrike@webrtc.orgd89b69a2014-11-06 17:23:09 +0000474 int code = SSL_read(ssl_, data, checked_cast<int>(data_len));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000475 int ssl_error = SSL_get_error(ssl_, code);
476 switch (ssl_error) {
477 case SSL_ERROR_NONE:
478 LOG(LS_VERBOSE) << " -- success";
479 ASSERT(0 < code && static_cast<unsigned>(code) <= data_len);
480 if (read)
481 *read = code;
482
483 if (ssl_mode_ == SSL_MODE_DTLS) {
484 // Enforce atomic reads -- this is a short read
485 unsigned int pending = SSL_pending(ssl_);
486
487 if (pending) {
488 LOG(LS_INFO) << " -- short DTLS read. flushing";
489 FlushInput(pending);
490 if (error)
491 *error = SSE_MSG_TRUNC;
492 return SR_ERROR;
493 }
494 }
495 return SR_SUCCESS;
496 case SSL_ERROR_WANT_READ:
497 LOG(LS_VERBOSE) << " -- error want read";
498 return SR_BLOCK;
499 case SSL_ERROR_WANT_WRITE:
500 LOG(LS_VERBOSE) << " -- error want write";
501 ssl_read_needs_write_ = true;
502 return SR_BLOCK;
503 case SSL_ERROR_ZERO_RETURN:
504 LOG(LS_VERBOSE) << " -- remote side closed";
guoweis4cc9f982016-02-24 11:10:06 -0800505 // When we're closed at SSL layer, also close the stream level which
506 // performs necessary clean up. Otherwise, a new incoming packet after
507 // this could overflow the stream buffer.
508 this->stream()->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000509 return SR_EOS;
510 break;
511 default:
512 LOG(LS_VERBOSE) << " -- error " << code;
513 Error("SSL_read", (ssl_error ? ssl_error : -1), false);
514 if (error)
515 *error = ssl_error_code_;
516 return SR_ERROR;
517 }
518 // not reached
519}
520
521void OpenSSLStreamAdapter::FlushInput(unsigned int left) {
522 unsigned char buf[2048];
523
524 while (left) {
525 // This should always succeed
526 int toread = (sizeof(buf) < left) ? sizeof(buf) : left;
527 int code = SSL_read(ssl_, buf, toread);
528
529 int ssl_error = SSL_get_error(ssl_, code);
530 ASSERT(ssl_error == SSL_ERROR_NONE);
531
532 if (ssl_error != SSL_ERROR_NONE) {
533 LOG(LS_VERBOSE) << " -- error " << code;
534 Error("SSL_read", (ssl_error ? ssl_error : -1), false);
535 return;
536 }
537
538 LOG(LS_VERBOSE) << " -- flushed " << code << " bytes";
539 left -= code;
540 }
541}
542
543void OpenSSLStreamAdapter::Close() {
544 Cleanup();
545 ASSERT(state_ == SSL_CLOSED || state_ == SSL_ERROR);
546 StreamAdapterInterface::Close();
547}
548
549StreamState OpenSSLStreamAdapter::GetState() const {
550 switch (state_) {
551 case SSL_WAIT:
552 case SSL_CONNECTING:
553 return SS_OPENING;
554 case SSL_CONNECTED:
555 return SS_OPEN;
556 default:
557 return SS_CLOSED;
558 };
559 // not reached
560}
561
562void OpenSSLStreamAdapter::OnEvent(StreamInterface* stream, int events,
563 int err) {
564 int events_to_signal = 0;
565 int signal_error = 0;
566 ASSERT(stream == this->stream());
567 if ((events & SE_OPEN)) {
568 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent SE_OPEN";
569 if (state_ != SSL_WAIT) {
570 ASSERT(state_ == SSL_NONE);
571 events_to_signal |= SE_OPEN;
572 } else {
573 state_ = SSL_CONNECTING;
574 if (int err = BeginSSL()) {
575 Error("BeginSSL", err, true);
576 return;
577 }
578 }
579 }
580 if ((events & (SE_READ|SE_WRITE))) {
581 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent"
582 << ((events & SE_READ) ? " SE_READ" : "")
583 << ((events & SE_WRITE) ? " SE_WRITE" : "");
584 if (state_ == SSL_NONE) {
585 events_to_signal |= events & (SE_READ|SE_WRITE);
586 } else if (state_ == SSL_CONNECTING) {
587 if (int err = ContinueSSL()) {
588 Error("ContinueSSL", err, true);
589 return;
590 }
591 } else if (state_ == SSL_CONNECTED) {
592 if (((events & SE_READ) && ssl_write_needs_read_) ||
593 (events & SE_WRITE)) {
594 LOG(LS_VERBOSE) << " -- onStreamWriteable";
595 events_to_signal |= SE_WRITE;
596 }
597 if (((events & SE_WRITE) && ssl_read_needs_write_) ||
598 (events & SE_READ)) {
599 LOG(LS_VERBOSE) << " -- onStreamReadable";
600 events_to_signal |= SE_READ;
601 }
602 }
603 }
604 if ((events & SE_CLOSE)) {
605 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent(SE_CLOSE, " << err << ")";
606 Cleanup();
607 events_to_signal |= SE_CLOSE;
608 // SE_CLOSE is the only event that uses the final parameter to OnEvent().
609 ASSERT(signal_error == 0);
610 signal_error = err;
611 }
612 if (events_to_signal)
613 StreamAdapterInterface::OnEvent(stream, events_to_signal, signal_error);
614}
615
616int OpenSSLStreamAdapter::StartSSL() {
617 ASSERT(state_ == SSL_NONE);
618
619 if (StreamAdapterInterface::GetState() != SS_OPEN) {
620 state_ = SSL_WAIT;
621 return 0;
622 }
623
624 state_ = SSL_CONNECTING;
625 if (int err = BeginSSL()) {
626 Error("BeginSSL", err, false);
627 return err;
628 }
629
630 return 0;
631}
632
633int OpenSSLStreamAdapter::BeginSSL() {
634 ASSERT(state_ == SSL_CONNECTING);
635 // The underlying stream has open. If we are in peer-to-peer mode
636 // then a peer certificate must have been specified by now.
637 ASSERT(!ssl_server_name_.empty() ||
638 !peer_certificate_digest_algorithm_.empty());
639 LOG(LS_INFO) << "BeginSSL: "
640 << (!ssl_server_name_.empty() ? ssl_server_name_ :
641 "with peer");
642
643 BIO* bio = NULL;
644
645 // First set up the context
646 ASSERT(ssl_ctx_ == NULL);
647 ssl_ctx_ = SetupSSLContext();
648 if (!ssl_ctx_)
649 return -1;
650
651 bio = BIO_new_stream(static_cast<StreamInterface*>(stream()));
652 if (!bio)
653 return -1;
654
655 ssl_ = SSL_new(ssl_ctx_);
656 if (!ssl_) {
657 BIO_free(bio);
658 return -1;
659 }
660
661 SSL_set_app_data(ssl_, this);
662
663 SSL_set_bio(ssl_, bio, bio); // the SSL object owns the bio now.
664
665 SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |
666 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
667
jiayl@webrtc.org11c6bde2014-08-28 16:14:38 +0000668 // Specify an ECDH group for ECDHE ciphers, otherwise they cannot be
669 // negotiated when acting as the server. Use NIST's P-256 which is commonly
670 // supported.
671 EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
672 if (ecdh == NULL)
673 return -1;
674 SSL_set_options(ssl_, SSL_OP_SINGLE_ECDH_USE);
675 SSL_set_tmp_ecdh(ssl_, ecdh);
676 EC_KEY_free(ecdh);
677
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000678 // Do the connect
679 return ContinueSSL();
680}
681
682int OpenSSLStreamAdapter::ContinueSSL() {
683 LOG(LS_VERBOSE) << "ContinueSSL";
684 ASSERT(state_ == SSL_CONNECTING);
685
686 // Clear the DTLS timer
687 Thread::Current()->Clear(this, MSG_TIMEOUT);
688
689 int code = (role_ == SSL_CLIENT) ? SSL_connect(ssl_) : SSL_accept(ssl_);
690 int ssl_error;
691 switch (ssl_error = SSL_get_error(ssl_, code)) {
692 case SSL_ERROR_NONE:
693 LOG(LS_VERBOSE) << " -- success";
694
695 if (!SSLPostConnectionCheck(ssl_, ssl_server_name_.c_str(), NULL,
696 peer_certificate_digest_algorithm_)) {
697 LOG(LS_ERROR) << "TLS post connection check failed";
698 return -1;
699 }
700
701 state_ = SSL_CONNECTED;
702 StreamAdapterInterface::OnEvent(stream(), SE_OPEN|SE_READ|SE_WRITE, 0);
703 break;
704
705 case SSL_ERROR_WANT_READ: {
706 LOG(LS_VERBOSE) << " -- error want read";
707 struct timeval timeout;
708 if (DTLSv1_get_timeout(ssl_, &timeout)) {
709 int delay = timeout.tv_sec * 1000 + timeout.tv_usec/1000;
710
711 Thread::Current()->PostDelayed(delay, this, MSG_TIMEOUT, 0);
712 }
713 }
714 break;
715
716 case SSL_ERROR_WANT_WRITE:
717 LOG(LS_VERBOSE) << " -- error want write";
718 break;
719
720 case SSL_ERROR_ZERO_RETURN:
721 default:
722 LOG(LS_VERBOSE) << " -- error " << code;
723 return (ssl_error != 0) ? ssl_error : -1;
724 }
725
726 return 0;
727}
728
729void OpenSSLStreamAdapter::Error(const char* context, int err, bool signal) {
730 LOG(LS_WARNING) << "OpenSSLStreamAdapter::Error("
731 << context << ", " << err << ")";
732 state_ = SSL_ERROR;
733 ssl_error_code_ = err;
734 Cleanup();
735 if (signal)
736 StreamAdapterInterface::OnEvent(stream(), SE_CLOSE, err);
737}
738
739void OpenSSLStreamAdapter::Cleanup() {
740 LOG(LS_INFO) << "Cleanup";
741
742 if (state_ != SSL_ERROR) {
743 state_ = SSL_CLOSED;
744 ssl_error_code_ = 0;
745 }
746
747 if (ssl_) {
jiayl@webrtc.orgf1d751c2014-09-25 16:38:46 +0000748 int ret = SSL_shutdown(ssl_);
749 if (ret < 0) {
750 LOG(LS_WARNING) << "SSL_shutdown failed, error = "
751 << SSL_get_error(ssl_, ret);
752 }
753
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000754 SSL_free(ssl_);
755 ssl_ = NULL;
756 }
757 if (ssl_ctx_) {
758 SSL_CTX_free(ssl_ctx_);
759 ssl_ctx_ = NULL;
760 }
761 identity_.reset();
762 peer_certificate_.reset();
763
764 // Clear the DTLS timer
765 Thread::Current()->Clear(this, MSG_TIMEOUT);
766}
767
768
769void OpenSSLStreamAdapter::OnMessage(Message* msg) {
770 // Process our own messages and then pass others to the superclass
771 if (MSG_TIMEOUT == msg->message_id) {
772 LOG(LS_INFO) << "DTLS timeout expired";
773 DTLSv1_handle_timeout(ssl_);
774 ContinueSSL();
775 } else {
776 StreamInterface::OnMessage(msg);
777 }
778}
779
780SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() {
781 SSL_CTX *ctx = NULL;
782
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000783 ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
Joachim Bauch831c5582015-05-20 12:48:41 +0200784 DTLS_method() : TLS_method());
785 // Version limiting for BoringSSL will be done below.
Joachim Bauch831c5582015-05-20 12:48:41 +0200786
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000787 if (ctx == NULL)
788 return NULL;
789
Joachim Bauch831c5582015-05-20 12:48:41 +0200790 SSL_CTX_set_min_version(ctx, ssl_mode_ == SSL_MODE_DTLS ?
791 DTLS1_VERSION : TLS1_VERSION);
792 switch (ssl_max_version_) {
793 case SSL_PROTOCOL_TLS_10:
794 SSL_CTX_set_max_version(ctx, ssl_mode_ == SSL_MODE_DTLS ?
795 DTLS1_VERSION : TLS1_VERSION);
796 break;
797 case SSL_PROTOCOL_TLS_11:
798 SSL_CTX_set_max_version(ctx, ssl_mode_ == SSL_MODE_DTLS ?
799 DTLS1_VERSION : TLS1_1_VERSION);
800 break;
801 case SSL_PROTOCOL_TLS_12:
802 default:
803 SSL_CTX_set_max_version(ctx, ssl_mode_ == SSL_MODE_DTLS ?
804 DTLS1_2_VERSION : TLS1_2_VERSION);
805 break;
806 }
Joachim Bauch831c5582015-05-20 12:48:41 +0200807
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000808 if (identity_ && !identity_->ConfigureIdentity(ctx)) {
809 SSL_CTX_free(ctx);
810 return NULL;
811 }
812
tfarinaa41ab932015-10-30 16:08:48 -0700813#if !defined(NDEBUG)
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000814 SSL_CTX_set_info_callback(ctx, OpenSSLAdapter::SSLInfoCallback);
815#endif
816
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000817 int mode = SSL_VERIFY_PEER;
818 if (client_auth_enabled()) {
819 // Require a certificate from the client.
820 // Note: Normally this is always true in production, but it may be disabled
821 // for testing purposes (e.g. SSLAdapter unit tests).
822 mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
823 }
824
825 SSL_CTX_set_verify(ctx, mode, SSLVerifyCallback);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000826 SSL_CTX_set_verify_depth(ctx, 4);
Joachim Bauch831c5582015-05-20 12:48:41 +0200827 // Select list of available ciphers. Note that !SHA256 and !SHA384 only
828 // remove HMAC-SHA256 and HMAC-SHA384 cipher suites, not GCM cipher suites
829 // with SHA256 or SHA384 as the handshake hash.
830 // This matches the list of SSLClientSocketOpenSSL in Chromium.
831 SSL_CTX_set_cipher_list(ctx,
832 "DEFAULT:!NULL:!aNULL:!SHA256:!SHA384:!aECDH:!AESGCM+AES256:!aPSK");
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000833
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000834 if (!srtp_ciphers_.empty()) {
835 if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_ciphers_.c_str())) {
836 SSL_CTX_free(ctx);
837 return NULL;
838 }
839 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000840
841 return ctx;
842}
843
844int OpenSSLStreamAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) {
845 // Get our SSL structure from the store
846 SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(
847 store,
848 SSL_get_ex_data_X509_STORE_CTX_idx()));
849 OpenSSLStreamAdapter* stream =
850 reinterpret_cast<OpenSSLStreamAdapter*>(SSL_get_app_data(ssl));
851
852 if (stream->peer_certificate_digest_algorithm_.empty()) {
853 return 0;
854 }
855 X509* cert = X509_STORE_CTX_get_current_cert(store);
henrike@webrtc.org4e5f65a2014-06-05 20:40:11 +0000856 int depth = X509_STORE_CTX_get_error_depth(store);
857
858 // For now We ignore the parent certificates and verify the leaf against
859 // the digest.
860 //
861 // TODO(jiayl): Verify the chain is a proper chain and report the chain to
torbjorng07d09362015-09-22 11:58:04 -0700862 // |stream->peer_certificate_|.
henrike@webrtc.org4e5f65a2014-06-05 20:40:11 +0000863 if (depth > 0) {
864 LOG(LS_INFO) << "Ignored chained certificate at depth " << depth;
865 return 1;
866 }
867
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000868 unsigned char digest[EVP_MAX_MD_SIZE];
869 size_t digest_length;
870 if (!OpenSSLCertificate::ComputeDigest(
871 cert,
872 stream->peer_certificate_digest_algorithm_,
873 digest, sizeof(digest),
874 &digest_length)) {
875 LOG(LS_WARNING) << "Failed to compute peer cert digest.";
876 return 0;
877 }
henrike@webrtc.org4e5f65a2014-06-05 20:40:11 +0000878
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000879 Buffer computed_digest(digest, digest_length);
880 if (computed_digest != stream->peer_certificate_digest_value_) {
881 LOG(LS_WARNING) << "Rejected peer certificate due to mismatched digest.";
882 return 0;
883 }
884 // Ignore any verification error if the digest matches, since there is no
885 // value in checking the validity of a self-signed cert issued by untrusted
886 // sources.
887 LOG(LS_INFO) << "Accepted peer certificate.";
henrike@webrtc.org4e5f65a2014-06-05 20:40:11 +0000888
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000889 // Record the peer's certificate.
890 stream->peer_certificate_.reset(new OpenSSLCertificate(cert));
891 return 1;
892}
893
894// This code is taken from the "Network Security with OpenSSL"
895// sample in chapter 5
896bool OpenSSLStreamAdapter::SSLPostConnectionCheck(SSL* ssl,
897 const char* server_name,
898 const X509* peer_cert,
899 const std::string
900 &peer_digest) {
901 ASSERT(server_name != NULL);
902 bool ok;
903 if (server_name[0] != '\0') { // traditional mode
904 ok = OpenSSLAdapter::VerifyServerName(ssl, server_name, ignore_bad_cert());
905
906 if (ok) {
907 ok = (SSL_get_verify_result(ssl) == X509_V_OK ||
908 custom_verification_succeeded_);
909 }
910 } else { // peer-to-peer mode
911 ASSERT((peer_cert != NULL) || (!peer_digest.empty()));
912 // no server name validation
913 ok = true;
914 }
915
916 if (!ok && ignore_bad_cert()) {
917 LOG(LS_ERROR) << "SSL_get_verify_result(ssl) = "
918 << SSL_get_verify_result(ssl);
919 LOG(LS_INFO) << "Other TLS post connection checks failed.";
920 ok = true;
921 }
922
923 return ok;
924}
925
926bool OpenSSLStreamAdapter::HaveDtls() {
927 return true;
928}
929
930bool OpenSSLStreamAdapter::HaveDtlsSrtp() {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000931 return true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000932}
933
934bool OpenSSLStreamAdapter::HaveExporter() {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000935 return true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000936}
937
torbjorng43166b82016-03-11 00:06:47 -0800938#define CDEF(X) \
939 { static_cast<uint16_t>(TLS1_CK_##X & 0xffff), "TLS_" #X }
940
941struct cipher_list {
942 uint16_t cipher;
943 const char* cipher_str;
944};
945
946// TODO(torbjorng): Perhaps add more cipher suites to these lists.
947static const cipher_list OK_RSA_ciphers[] = {
948 CDEF(ECDHE_RSA_WITH_AES_128_CBC_SHA),
949 CDEF(ECDHE_RSA_WITH_AES_256_CBC_SHA),
950 CDEF(ECDHE_RSA_WITH_AES_128_GCM_SHA256),
951#ifdef TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA256
952 CDEF(ECDHE_RSA_WITH_AES_256_GCM_SHA256),
953#endif
954 CDEF(ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256),
955};
956
957static const cipher_list OK_ECDSA_ciphers[] = {
958 CDEF(ECDHE_ECDSA_WITH_AES_128_CBC_SHA),
959 CDEF(ECDHE_ECDSA_WITH_AES_256_CBC_SHA),
960 CDEF(ECDHE_ECDSA_WITH_AES_128_GCM_SHA256),
961#ifdef TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA256
962 CDEF(ECDHE_ECDSA_WITH_AES_256_GCM_SHA256),
963#endif
964 CDEF(ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256),
965};
966#undef CDEF
967
968bool OpenSSLStreamAdapter::IsAcceptableCipher(int cipher, KeyType key_type) {
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200969 if (key_type == KT_RSA) {
torbjorng43166b82016-03-11 00:06:47 -0800970 for (const cipher_list& c : OK_RSA_ciphers) {
971 if (cipher == c.cipher)
972 return true;
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200973 }
Joachim Bauch831c5582015-05-20 12:48:41 +0200974 }
torbjorng43166b82016-03-11 00:06:47 -0800975
976 if (key_type == KT_ECDSA) {
977 for (const cipher_list& c : OK_ECDSA_ciphers) {
978 if (cipher == c.cipher)
979 return true;
980 }
981 }
982
983 return false;
984}
985
986bool OpenSSLStreamAdapter::IsAcceptableCipher(const std::string& cipher,
987 KeyType key_type) {
988 if (key_type == KT_RSA) {
989 for (const cipher_list& c : OK_RSA_ciphers) {
990 if (cipher == c.cipher_str)
991 return true;
992 }
993 }
994
995 if (key_type == KT_ECDSA) {
996 for (const cipher_list& c : OK_ECDSA_ciphers) {
997 if (cipher == c.cipher_str)
998 return true;
999 }
1000 }
1001
1002 return false;
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001003}
1004
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001005} // namespace rtc
1006
1007#endif // HAVE_OPENSSL_SSL_H