Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(123)

Side by Side Diff: webrtc/base/openssladapter.cc

Issue 2877023002: Move webrtc/{base => rtc_base} (Closed)
Patch Set: update presubmit.py and DEPS include rules Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/base/openssladapter.h ('k') | webrtc/base/openssldigest.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2008 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 #include "webrtc/base/openssladapter.h"
12
13 #if defined(WEBRTC_POSIX)
14 #include <unistd.h>
15 #endif
16
17 // Must be included first before openssl headers.
18 #include "webrtc/base/win32.h" // NOLINT
19
20 #include <openssl/bio.h>
21 #include <openssl/crypto.h>
22 #include <openssl/err.h>
23 #include <openssl/opensslv.h>
24 #include <openssl/rand.h>
25 #include <openssl/x509.h>
26 #include <openssl/x509v3.h>
27
28 #include "webrtc/base/arraysize.h"
29 #include "webrtc/base/checks.h"
30 #include "webrtc/base/logging.h"
31 #include "webrtc/base/openssl.h"
32 #include "webrtc/base/safe_conversions.h"
33 #include "webrtc/base/sslroots.h"
34 #include "webrtc/base/stringutils.h"
35 #include "webrtc/base/thread.h"
36
37 #ifndef OPENSSL_IS_BORINGSSL
38
39 // TODO: Use a nicer abstraction for mutex.
40
41 #if defined(WEBRTC_WIN)
42 #define MUTEX_TYPE HANDLE
43 #define MUTEX_SETUP(x) (x) = CreateMutex(nullptr, FALSE, nullptr)
44 #define MUTEX_CLEANUP(x) CloseHandle(x)
45 #define MUTEX_LOCK(x) WaitForSingleObject((x), INFINITE)
46 #define MUTEX_UNLOCK(x) ReleaseMutex(x)
47 #define THREAD_ID GetCurrentThreadId()
48 #elif defined(WEBRTC_POSIX)
49 #define MUTEX_TYPE pthread_mutex_t
50 #define MUTEX_SETUP(x) pthread_mutex_init(&(x), nullptr)
51 #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
52 #define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
53 #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
54 #define THREAD_ID pthread_self()
55 #else
56 #error You must define mutex operations appropriate for your platform!
57 #endif
58
59 struct CRYPTO_dynlock_value {
60 MUTEX_TYPE mutex;
61 };
62
63 #endif // #ifndef OPENSSL_IS_BORINGSSL
64
65 //////////////////////////////////////////////////////////////////////
66 // SocketBIO
67 //////////////////////////////////////////////////////////////////////
68
69 static int socket_write(BIO* h, const char* buf, int num);
70 static int socket_read(BIO* h, char* buf, int size);
71 static int socket_puts(BIO* h, const char* str);
72 static long socket_ctrl(BIO* h, int cmd, long arg1, void* arg2);
73 static int socket_new(BIO* h);
74 static int socket_free(BIO* data);
75
76 // TODO(davidben): This should be const once BoringSSL is assumed.
77 static BIO_METHOD methods_socket = {
78 BIO_TYPE_BIO, "socket", socket_write, socket_read, socket_puts, 0,
79 socket_ctrl, socket_new, socket_free, nullptr,
80 };
81
82 static BIO_METHOD* BIO_s_socket2() { return(&methods_socket); }
83
84 static BIO* BIO_new_socket(rtc::AsyncSocket* socket) {
85 BIO* ret = BIO_new(BIO_s_socket2());
86 if (ret == nullptr) {
87 return nullptr;
88 }
89 ret->ptr = socket;
90 return ret;
91 }
92
93 static int socket_new(BIO* b) {
94 b->shutdown = 0;
95 b->init = 1;
96 b->num = 0; // 1 means socket closed
97 b->ptr = 0;
98 return 1;
99 }
100
101 static int socket_free(BIO* b) {
102 if (b == nullptr)
103 return 0;
104 return 1;
105 }
106
107 static int socket_read(BIO* b, char* out, int outl) {
108 if (!out)
109 return -1;
110 rtc::AsyncSocket* socket = static_cast<rtc::AsyncSocket*>(b->ptr);
111 BIO_clear_retry_flags(b);
112 int result = socket->Recv(out, outl, nullptr);
113 if (result > 0) {
114 return result;
115 } else if (result == 0) {
116 b->num = 1;
117 } else if (socket->IsBlocking()) {
118 BIO_set_retry_read(b);
119 }
120 return -1;
121 }
122
123 static int socket_write(BIO* b, const char* in, int inl) {
124 if (!in)
125 return -1;
126 rtc::AsyncSocket* socket = static_cast<rtc::AsyncSocket*>(b->ptr);
127 BIO_clear_retry_flags(b);
128 int result = socket->Send(in, inl);
129 if (result > 0) {
130 return result;
131 } else if (socket->IsBlocking()) {
132 BIO_set_retry_write(b);
133 }
134 return -1;
135 }
136
137 static int socket_puts(BIO* b, const char* str) {
138 return socket_write(b, str, rtc::checked_cast<int>(strlen(str)));
139 }
140
141 static long socket_ctrl(BIO* b, int cmd, long num, void* ptr) {
142 switch (cmd) {
143 case BIO_CTRL_RESET:
144 return 0;
145 case BIO_CTRL_EOF:
146 return b->num;
147 case BIO_CTRL_WPENDING:
148 case BIO_CTRL_PENDING:
149 return 0;
150 case BIO_CTRL_FLUSH:
151 return 1;
152 default:
153 return 0;
154 }
155 }
156
157 static void LogSslError() {
158 // Walk down the error stack to find the SSL error.
159 uint32_t error_code;
160 const char* file;
161 int line;
162 do {
163 error_code = ERR_get_error_line(&file, &line);
164 if (ERR_GET_LIB(error_code) == ERR_LIB_SSL) {
165 LOG(LS_ERROR) << "ERR_LIB_SSL: " << error_code << ", " << file << ":"
166 << line;
167 break;
168 }
169 } while (error_code != 0);
170 }
171
172 /////////////////////////////////////////////////////////////////////////////
173 // OpenSSLAdapter
174 /////////////////////////////////////////////////////////////////////////////
175
176 namespace rtc {
177
178 #ifndef OPENSSL_IS_BORINGSSL
179
180 // This array will store all of the mutexes available to OpenSSL.
181 static MUTEX_TYPE* mutex_buf = nullptr;
182
183 static void locking_function(int mode, int n, const char * file, int line) {
184 if (mode & CRYPTO_LOCK) {
185 MUTEX_LOCK(mutex_buf[n]);
186 } else {
187 MUTEX_UNLOCK(mutex_buf[n]);
188 }
189 }
190
191 static unsigned long id_function() { // NOLINT
192 // Use old-style C cast because THREAD_ID's type varies with the platform,
193 // in some cases requiring static_cast, and in others requiring
194 // reinterpret_cast.
195 return (unsigned long)THREAD_ID; // NOLINT
196 }
197
198 static CRYPTO_dynlock_value* dyn_create_function(const char* file, int line) {
199 CRYPTO_dynlock_value* value = new CRYPTO_dynlock_value;
200 if (!value)
201 return nullptr;
202 MUTEX_SETUP(value->mutex);
203 return value;
204 }
205
206 static void dyn_lock_function(int mode, CRYPTO_dynlock_value* l,
207 const char* file, int line) {
208 if (mode & CRYPTO_LOCK) {
209 MUTEX_LOCK(l->mutex);
210 } else {
211 MUTEX_UNLOCK(l->mutex);
212 }
213 }
214
215 static void dyn_destroy_function(CRYPTO_dynlock_value* l,
216 const char* file, int line) {
217 MUTEX_CLEANUP(l->mutex);
218 delete l;
219 }
220
221 #endif // #ifndef OPENSSL_IS_BORINGSSL
222
223 VerificationCallback OpenSSLAdapter::custom_verify_callback_ = nullptr;
224
225 bool OpenSSLAdapter::InitializeSSL(VerificationCallback callback) {
226 if (!InitializeSSLThread() || !SSL_library_init())
227 return false;
228 #if !defined(ADDRESS_SANITIZER) || !defined(WEBRTC_MAC) || defined(WEBRTC_IOS)
229 // Loading the error strings crashes mac_asan. Omit this debugging aid there.
230 SSL_load_error_strings();
231 #endif
232 ERR_load_BIO_strings();
233 OpenSSL_add_all_algorithms();
234 RAND_poll();
235 custom_verify_callback_ = callback;
236 return true;
237 }
238
239 bool OpenSSLAdapter::InitializeSSLThread() {
240 // BoringSSL is doing the locking internally, so the callbacks are not used
241 // in this case (and are no-ops anyways).
242 #ifndef OPENSSL_IS_BORINGSSL
243 mutex_buf = new MUTEX_TYPE[CRYPTO_num_locks()];
244 if (!mutex_buf)
245 return false;
246 for (int i = 0; i < CRYPTO_num_locks(); ++i)
247 MUTEX_SETUP(mutex_buf[i]);
248
249 // we need to cast our id_function to return an unsigned long -- pthread_t is
250 // a pointer
251 CRYPTO_set_id_callback(id_function);
252 CRYPTO_set_locking_callback(locking_function);
253 CRYPTO_set_dynlock_create_callback(dyn_create_function);
254 CRYPTO_set_dynlock_lock_callback(dyn_lock_function);
255 CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function);
256 #endif // #ifndef OPENSSL_IS_BORINGSSL
257 return true;
258 }
259
260 bool OpenSSLAdapter::CleanupSSL() {
261 #ifndef OPENSSL_IS_BORINGSSL
262 if (!mutex_buf)
263 return false;
264 CRYPTO_set_id_callback(nullptr);
265 CRYPTO_set_locking_callback(nullptr);
266 CRYPTO_set_dynlock_create_callback(nullptr);
267 CRYPTO_set_dynlock_lock_callback(nullptr);
268 CRYPTO_set_dynlock_destroy_callback(nullptr);
269 for (int i = 0; i < CRYPTO_num_locks(); ++i)
270 MUTEX_CLEANUP(mutex_buf[i]);
271 delete [] mutex_buf;
272 mutex_buf = nullptr;
273 #endif // #ifndef OPENSSL_IS_BORINGSSL
274 return true;
275 }
276
277 OpenSSLAdapter::OpenSSLAdapter(AsyncSocket* socket)
278 : SSLAdapter(socket),
279 state_(SSL_NONE),
280 ssl_read_needs_write_(false),
281 ssl_write_needs_read_(false),
282 restartable_(false),
283 ssl_(nullptr),
284 ssl_ctx_(nullptr),
285 ssl_mode_(SSL_MODE_TLS),
286 custom_verification_succeeded_(false) {}
287
288 OpenSSLAdapter::~OpenSSLAdapter() {
289 Cleanup();
290 }
291
292 void
293 OpenSSLAdapter::SetMode(SSLMode mode) {
294 RTC_DCHECK(state_ == SSL_NONE);
295 ssl_mode_ = mode;
296 }
297
298 int
299 OpenSSLAdapter::StartSSL(const char* hostname, bool restartable) {
300 if (state_ != SSL_NONE)
301 return -1;
302
303 ssl_host_name_ = hostname;
304 restartable_ = restartable;
305
306 if (socket_->GetState() != Socket::CS_CONNECTED) {
307 state_ = SSL_WAIT;
308 return 0;
309 }
310
311 state_ = SSL_CONNECTING;
312 if (int err = BeginSSL()) {
313 Error("BeginSSL", err, false);
314 return err;
315 }
316
317 return 0;
318 }
319
320 int
321 OpenSSLAdapter::BeginSSL() {
322 LOG(LS_INFO) << "BeginSSL: " << ssl_host_name_;
323 RTC_DCHECK(state_ == SSL_CONNECTING);
324
325 int err = 0;
326 BIO* bio = nullptr;
327
328 // First set up the context
329 if (!ssl_ctx_)
330 ssl_ctx_ = SetupSSLContext();
331
332 if (!ssl_ctx_) {
333 err = -1;
334 goto ssl_error;
335 }
336
337 bio = BIO_new_socket(socket_);
338 if (!bio) {
339 err = -1;
340 goto ssl_error;
341 }
342
343 ssl_ = SSL_new(ssl_ctx_);
344 if (!ssl_) {
345 err = -1;
346 goto ssl_error;
347 }
348
349 SSL_set_app_data(ssl_, this);
350
351 SSL_set_bio(ssl_, bio, bio);
352 // SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER allows different buffers to be passed
353 // into SSL_write when a record could only be partially transmitted (and thus
354 // requires another call to SSL_write to finish transmission). This allows us
355 // to copy the data into our own buffer when this occurs, since the original
356 // buffer can't safely be accessed after control exits Send.
357 // TODO(deadbeef): Do we want SSL_MODE_ENABLE_PARTIAL_WRITE? It doesn't
358 // appear Send handles partial writes properly, though maybe we never notice
359 // since we never send more than 16KB at once..
360 SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |
361 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
362
363 // Enable SNI.
364 if (!ssl_host_name_.empty()) {
365 SSL_set_tlsext_host_name(ssl_, ssl_host_name_.c_str());
366 }
367
368 // the SSL object owns the bio now
369 bio = nullptr;
370
371 // Do the connect
372 err = ContinueSSL();
373 if (err != 0)
374 goto ssl_error;
375
376 return err;
377
378 ssl_error:
379 Cleanup();
380 if (bio)
381 BIO_free(bio);
382
383 return err;
384 }
385
386 int
387 OpenSSLAdapter::ContinueSSL() {
388 RTC_DCHECK(state_ == SSL_CONNECTING);
389
390 // Clear the DTLS timer
391 Thread::Current()->Clear(this, MSG_TIMEOUT);
392
393 int code = SSL_connect(ssl_);
394 switch (SSL_get_error(ssl_, code)) {
395 case SSL_ERROR_NONE:
396 if (!SSLPostConnectionCheck(ssl_, ssl_host_name_.c_str())) {
397 LOG(LS_ERROR) << "TLS post connection check failed";
398 // make sure we close the socket
399 Cleanup();
400 // The connect failed so return -1 to shut down the socket
401 return -1;
402 }
403
404 state_ = SSL_CONNECTED;
405 AsyncSocketAdapter::OnConnectEvent(this);
406 #if 0 // TODO: worry about this
407 // Don't let ourselves go away during the callbacks
408 PRefPtr<OpenSSLAdapter> lock(this);
409 LOG(LS_INFO) << " -- onStreamReadable";
410 AsyncSocketAdapter::OnReadEvent(this);
411 LOG(LS_INFO) << " -- onStreamWriteable";
412 AsyncSocketAdapter::OnWriteEvent(this);
413 #endif
414 break;
415
416 case SSL_ERROR_WANT_READ:
417 LOG(LS_VERBOSE) << " -- error want read";
418 struct timeval timeout;
419 if (DTLSv1_get_timeout(ssl_, &timeout)) {
420 int delay = timeout.tv_sec * 1000 + timeout.tv_usec/1000;
421
422 Thread::Current()->PostDelayed(RTC_FROM_HERE, delay, this, MSG_TIMEOUT,
423 0);
424 }
425 break;
426
427 case SSL_ERROR_WANT_WRITE:
428 break;
429
430 case SSL_ERROR_ZERO_RETURN:
431 default:
432 LOG(LS_WARNING) << "ContinueSSL -- error " << code;
433 return (code != 0) ? code : -1;
434 }
435
436 return 0;
437 }
438
439 void
440 OpenSSLAdapter::Error(const char* context, int err, bool signal) {
441 LOG(LS_WARNING) << "OpenSSLAdapter::Error("
442 << context << ", " << err << ")";
443 state_ = SSL_ERROR;
444 SetError(err);
445 if (signal)
446 AsyncSocketAdapter::OnCloseEvent(this, err);
447 }
448
449 void
450 OpenSSLAdapter::Cleanup() {
451 LOG(LS_INFO) << "Cleanup";
452
453 state_ = SSL_NONE;
454 ssl_read_needs_write_ = false;
455 ssl_write_needs_read_ = false;
456 custom_verification_succeeded_ = false;
457 pending_data_.Clear();
458
459 if (ssl_) {
460 SSL_free(ssl_);
461 ssl_ = nullptr;
462 }
463
464 if (ssl_ctx_) {
465 SSL_CTX_free(ssl_ctx_);
466 ssl_ctx_ = nullptr;
467 }
468
469 // Clear the DTLS timer
470 Thread::Current()->Clear(this, MSG_TIMEOUT);
471 }
472
473 int OpenSSLAdapter::DoSslWrite(const void* pv, size_t cb, int* error) {
474 // If we have pending data (that was previously only partially written by
475 // SSL_write), we shouldn't be attempting to write anything else.
476 RTC_DCHECK(pending_data_.empty() || pv == pending_data_.data());
477 RTC_DCHECK(error != nullptr);
478
479 ssl_write_needs_read_ = false;
480 int ret = SSL_write(ssl_, pv, checked_cast<int>(cb));
481 *error = SSL_get_error(ssl_, ret);
482 switch (*error) {
483 case SSL_ERROR_NONE:
484 // Success!
485 return ret;
486 case SSL_ERROR_WANT_READ:
487 LOG(LS_INFO) << " -- error want read";
488 ssl_write_needs_read_ = true;
489 SetError(EWOULDBLOCK);
490 break;
491 case SSL_ERROR_WANT_WRITE:
492 LOG(LS_INFO) << " -- error want write";
493 SetError(EWOULDBLOCK);
494 break;
495 case SSL_ERROR_ZERO_RETURN:
496 // LOG(LS_INFO) << " -- remote side closed";
497 SetError(EWOULDBLOCK);
498 // do we need to signal closure?
499 break;
500 case SSL_ERROR_SSL:
501 LogSslError();
502 Error("SSL_write", ret ? ret : -1, false);
503 break;
504 default:
505 LOG(LS_WARNING) << "Unknown error from SSL_write: " << *error;
506 Error("SSL_write", ret ? ret : -1, false);
507 break;
508 }
509
510 return SOCKET_ERROR;
511 }
512
513 //
514 // AsyncSocket Implementation
515 //
516
517 int
518 OpenSSLAdapter::Send(const void* pv, size_t cb) {
519 //LOG(LS_INFO) << "OpenSSLAdapter::Send(" << cb << ")";
520
521 switch (state_) {
522 case SSL_NONE:
523 return AsyncSocketAdapter::Send(pv, cb);
524
525 case SSL_WAIT:
526 case SSL_CONNECTING:
527 SetError(ENOTCONN);
528 return SOCKET_ERROR;
529
530 case SSL_CONNECTED:
531 break;
532
533 case SSL_ERROR:
534 default:
535 return SOCKET_ERROR;
536 }
537
538 int ret;
539 int error;
540
541 if (!pending_data_.empty()) {
542 ret = DoSslWrite(pending_data_.data(), pending_data_.size(), &error);
543 if (ret != static_cast<int>(pending_data_.size())) {
544 // We couldn't finish sending the pending data, so we definitely can't
545 // send any more data. Return with an EWOULDBLOCK error.
546 SetError(EWOULDBLOCK);
547 return SOCKET_ERROR;
548 }
549 // We completed sending the data previously passed into SSL_write! Now
550 // we're allowed to send more data.
551 pending_data_.Clear();
552 }
553
554 // OpenSSL will return an error if we try to write zero bytes
555 if (cb == 0)
556 return 0;
557
558 ret = DoSslWrite(pv, cb, &error);
559
560 // If SSL_write fails with SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, this
561 // means the underlying socket is blocked on reading or (more typically)
562 // writing. When this happens, OpenSSL requires that the next call to
563 // SSL_write uses the same arguments (though, with
564 // SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, the actual buffer pointer may be
565 // different).
566 //
567 // However, after Send exits, we will have lost access to data the user of
568 // this class is trying to send, and there's no guarantee that the user of
569 // this class will call Send with the same arguements when it fails. So, we
570 // buffer the data ourselves. When we know the underlying socket is writable
571 // again from OnWriteEvent (or if Send is called again before that happens),
572 // we'll retry sending this buffered data.
573 if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) {
574 // Shouldn't be able to get to this point if we already have pending data.
575 RTC_DCHECK(pending_data_.empty());
576 LOG(LS_WARNING)
577 << "SSL_write couldn't write to the underlying socket; buffering data.";
578 pending_data_.SetData(static_cast<const uint8_t*>(pv), cb);
579 // Since we're taking responsibility for sending this data, return its full
580 // size. The user of this class can consider it sent.
581 return cb;
582 }
583
584 return ret;
585 }
586
587 int
588 OpenSSLAdapter::SendTo(const void* pv, size_t cb, const SocketAddress& addr) {
589 if (socket_->GetState() == Socket::CS_CONNECTED &&
590 addr == socket_->GetRemoteAddress()) {
591 return Send(pv, cb);
592 }
593
594 SetError(ENOTCONN);
595
596 return SOCKET_ERROR;
597 }
598
599 int OpenSSLAdapter::Recv(void* pv, size_t cb, int64_t* timestamp) {
600 //LOG(LS_INFO) << "OpenSSLAdapter::Recv(" << cb << ")";
601 switch (state_) {
602
603 case SSL_NONE:
604 return AsyncSocketAdapter::Recv(pv, cb, timestamp);
605
606 case SSL_WAIT:
607 case SSL_CONNECTING:
608 SetError(ENOTCONN);
609 return SOCKET_ERROR;
610
611 case SSL_CONNECTED:
612 break;
613
614 case SSL_ERROR:
615 default:
616 return SOCKET_ERROR;
617 }
618
619 // Don't trust OpenSSL with zero byte reads
620 if (cb == 0)
621 return 0;
622
623 ssl_read_needs_write_ = false;
624
625 int code = SSL_read(ssl_, pv, checked_cast<int>(cb));
626 int error = SSL_get_error(ssl_, code);
627 switch (error) {
628 case SSL_ERROR_NONE:
629 // LOG(LS_INFO) << " -- success";
630 return code;
631 case SSL_ERROR_WANT_READ:
632 // LOG(LS_INFO) << " -- error want read";
633 SetError(EWOULDBLOCK);
634 break;
635 case SSL_ERROR_WANT_WRITE:
636 // LOG(LS_INFO) << " -- error want write";
637 ssl_read_needs_write_ = true;
638 SetError(EWOULDBLOCK);
639 break;
640 case SSL_ERROR_ZERO_RETURN:
641 // LOG(LS_INFO) << " -- remote side closed";
642 SetError(EWOULDBLOCK);
643 // do we need to signal closure?
644 break;
645 case SSL_ERROR_SSL:
646 LogSslError();
647 Error("SSL_read", (code ? code : -1), false);
648 break;
649 default:
650 LOG(LS_WARNING) << "Unknown error from SSL_read: " << error;
651 Error("SSL_read", (code ? code : -1), false);
652 break;
653 }
654
655 return SOCKET_ERROR;
656 }
657
658 int OpenSSLAdapter::RecvFrom(void* pv,
659 size_t cb,
660 SocketAddress* paddr,
661 int64_t* timestamp) {
662 if (socket_->GetState() == Socket::CS_CONNECTED) {
663 int ret = Recv(pv, cb, timestamp);
664
665 *paddr = GetRemoteAddress();
666
667 return ret;
668 }
669
670 SetError(ENOTCONN);
671
672 return SOCKET_ERROR;
673 }
674
675 int
676 OpenSSLAdapter::Close() {
677 Cleanup();
678 state_ = restartable_ ? SSL_WAIT : SSL_NONE;
679 return AsyncSocketAdapter::Close();
680 }
681
682 Socket::ConnState
683 OpenSSLAdapter::GetState() const {
684 //if (signal_close_)
685 // return CS_CONNECTED;
686 ConnState state = socket_->GetState();
687 if ((state == CS_CONNECTED)
688 && ((state_ == SSL_WAIT) || (state_ == SSL_CONNECTING)))
689 state = CS_CONNECTING;
690 return state;
691 }
692
693 void
694 OpenSSLAdapter::OnMessage(Message* msg) {
695 if (MSG_TIMEOUT == msg->message_id) {
696 LOG(LS_INFO) << "DTLS timeout expired";
697 DTLSv1_handle_timeout(ssl_);
698 ContinueSSL();
699 }
700 }
701
702 void
703 OpenSSLAdapter::OnConnectEvent(AsyncSocket* socket) {
704 LOG(LS_INFO) << "OpenSSLAdapter::OnConnectEvent";
705 if (state_ != SSL_WAIT) {
706 RTC_DCHECK(state_ == SSL_NONE);
707 AsyncSocketAdapter::OnConnectEvent(socket);
708 return;
709 }
710
711 state_ = SSL_CONNECTING;
712 if (int err = BeginSSL()) {
713 AsyncSocketAdapter::OnCloseEvent(socket, err);
714 }
715 }
716
717 void
718 OpenSSLAdapter::OnReadEvent(AsyncSocket* socket) {
719 //LOG(LS_INFO) << "OpenSSLAdapter::OnReadEvent";
720
721 if (state_ == SSL_NONE) {
722 AsyncSocketAdapter::OnReadEvent(socket);
723 return;
724 }
725
726 if (state_ == SSL_CONNECTING) {
727 if (int err = ContinueSSL()) {
728 Error("ContinueSSL", err);
729 }
730 return;
731 }
732
733 if (state_ != SSL_CONNECTED)
734 return;
735
736 // Don't let ourselves go away during the callbacks
737 //PRefPtr<OpenSSLAdapter> lock(this); // TODO: fix this
738 if (ssl_write_needs_read_) {
739 //LOG(LS_INFO) << " -- onStreamWriteable";
740 AsyncSocketAdapter::OnWriteEvent(socket);
741 }
742
743 //LOG(LS_INFO) << " -- onStreamReadable";
744 AsyncSocketAdapter::OnReadEvent(socket);
745 }
746
747 void
748 OpenSSLAdapter::OnWriteEvent(AsyncSocket* socket) {
749 //LOG(LS_INFO) << "OpenSSLAdapter::OnWriteEvent";
750
751 if (state_ == SSL_NONE) {
752 AsyncSocketAdapter::OnWriteEvent(socket);
753 return;
754 }
755
756 if (state_ == SSL_CONNECTING) {
757 if (int err = ContinueSSL()) {
758 Error("ContinueSSL", err);
759 }
760 return;
761 }
762
763 if (state_ != SSL_CONNECTED)
764 return;
765
766 // Don't let ourselves go away during the callbacks
767 //PRefPtr<OpenSSLAdapter> lock(this); // TODO: fix this
768
769 if (ssl_read_needs_write_) {
770 //LOG(LS_INFO) << " -- onStreamReadable";
771 AsyncSocketAdapter::OnReadEvent(socket);
772 }
773
774 // If a previous SSL_write failed due to the underlying socket being blocked,
775 // this will attempt finishing the write operation.
776 if (!pending_data_.empty()) {
777 int error;
778 if (DoSslWrite(pending_data_.data(), pending_data_.size(), &error) ==
779 static_cast<int>(pending_data_.size())) {
780 pending_data_.Clear();
781 }
782 }
783
784 //LOG(LS_INFO) << " -- onStreamWriteable";
785 AsyncSocketAdapter::OnWriteEvent(socket);
786 }
787
788 void
789 OpenSSLAdapter::OnCloseEvent(AsyncSocket* socket, int err) {
790 LOG(LS_INFO) << "OpenSSLAdapter::OnCloseEvent(" << err << ")";
791 AsyncSocketAdapter::OnCloseEvent(socket, err);
792 }
793
794 bool OpenSSLAdapter::VerifyServerName(SSL* ssl, const char* host,
795 bool ignore_bad_cert) {
796 if (!host)
797 return false;
798
799 // Checking the return from SSL_get_peer_certificate here is not strictly
800 // necessary. With our setup, it is not possible for it to return
801 // null. However, it is good form to check the return.
802 X509* certificate = SSL_get_peer_certificate(ssl);
803 if (!certificate)
804 return false;
805
806 // Logging certificates is extremely verbose. So it is disabled by default.
807 #ifdef LOG_CERTIFICATES
808 {
809 LOG(LS_INFO) << "Certificate from server:";
810 BIO* mem = BIO_new(BIO_s_mem());
811 X509_print_ex(mem, certificate, XN_FLAG_SEP_CPLUS_SPC, X509_FLAG_NO_HEADER);
812 BIO_write(mem, "\0", 1);
813 char* buffer;
814 BIO_get_mem_data(mem, &buffer);
815 LOG(LS_INFO) << buffer;
816 BIO_free(mem);
817
818 char* cipher_description =
819 SSL_CIPHER_description(SSL_get_current_cipher(ssl), nullptr, 128);
820 LOG(LS_INFO) << "Cipher: " << cipher_description;
821 OPENSSL_free(cipher_description);
822 }
823 #endif
824
825 bool ok = false;
826 GENERAL_NAMES* names = reinterpret_cast<GENERAL_NAMES*>(
827 X509_get_ext_d2i(certificate, NID_subject_alt_name, nullptr, nullptr));
828 if (names) {
829 for (size_t i = 0; i < sk_GENERAL_NAME_num(names); i++) {
830 const GENERAL_NAME* name = sk_GENERAL_NAME_value(names, i);
831 if (name->type != GEN_DNS)
832 continue;
833 std::string value(
834 reinterpret_cast<const char*>(ASN1_STRING_data(name->d.dNSName)),
835 ASN1_STRING_length(name->d.dNSName));
836 // string_match takes NUL-terminated strings, so check for embedded NULs.
837 if (value.find('\0') != std::string::npos)
838 continue;
839 if (string_match(host, value.c_str())) {
840 ok = true;
841 break;
842 }
843 }
844 GENERAL_NAMES_free(names);
845 }
846
847 char data[256];
848 X509_NAME* subject;
849 if (!ok && ((subject = X509_get_subject_name(certificate)) != nullptr) &&
850 (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) >
851 0)) {
852 data[sizeof(data)-1] = 0;
853 if (_stricmp(data, host) == 0)
854 ok = true;
855 }
856
857 X509_free(certificate);
858
859 // This should only ever be turned on for debugging and development.
860 if (!ok && ignore_bad_cert) {
861 LOG(LS_WARNING) << "TLS certificate check FAILED. "
862 << "Allowing connection anyway.";
863 ok = true;
864 }
865
866 return ok;
867 }
868
869 bool OpenSSLAdapter::SSLPostConnectionCheck(SSL* ssl, const char* host) {
870 bool ok = VerifyServerName(ssl, host, ignore_bad_cert());
871
872 if (ok) {
873 ok = (SSL_get_verify_result(ssl) == X509_V_OK ||
874 custom_verification_succeeded_);
875 }
876
877 if (!ok && ignore_bad_cert()) {
878 LOG(LS_INFO) << "Other TLS post connection checks failed.";
879 ok = true;
880 }
881
882 return ok;
883 }
884
885 #if !defined(NDEBUG)
886
887 // We only use this for tracing and so it is only needed in debug mode
888
889 void
890 OpenSSLAdapter::SSLInfoCallback(const SSL* s, int where, int ret) {
891 const char* str = "undefined";
892 int w = where & ~SSL_ST_MASK;
893 if (w & SSL_ST_CONNECT) {
894 str = "SSL_connect";
895 } else if (w & SSL_ST_ACCEPT) {
896 str = "SSL_accept";
897 }
898 if (where & SSL_CB_LOOP) {
899 LOG(LS_INFO) << str << ":" << SSL_state_string_long(s);
900 } else if (where & SSL_CB_ALERT) {
901 str = (where & SSL_CB_READ) ? "read" : "write";
902 LOG(LS_INFO) << "SSL3 alert " << str
903 << ":" << SSL_alert_type_string_long(ret)
904 << ":" << SSL_alert_desc_string_long(ret);
905 } else if (where & SSL_CB_EXIT) {
906 if (ret == 0) {
907 LOG(LS_INFO) << str << ":failed in " << SSL_state_string_long(s);
908 } else if (ret < 0) {
909 LOG(LS_INFO) << str << ":error in " << SSL_state_string_long(s);
910 }
911 }
912 }
913
914 #endif
915
916 int
917 OpenSSLAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) {
918 #if !defined(NDEBUG)
919 if (!ok) {
920 char data[256];
921 X509* cert = X509_STORE_CTX_get_current_cert(store);
922 int depth = X509_STORE_CTX_get_error_depth(store);
923 int err = X509_STORE_CTX_get_error(store);
924
925 LOG(LS_INFO) << "Error with certificate at depth: " << depth;
926 X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data));
927 LOG(LS_INFO) << " issuer = " << data;
928 X509_NAME_oneline(X509_get_subject_name(cert), data, sizeof(data));
929 LOG(LS_INFO) << " subject = " << data;
930 LOG(LS_INFO) << " err = " << err
931 << ":" << X509_verify_cert_error_string(err);
932 }
933 #endif
934
935 // Get our stream pointer from the store
936 SSL* ssl = reinterpret_cast<SSL*>(
937 X509_STORE_CTX_get_ex_data(store,
938 SSL_get_ex_data_X509_STORE_CTX_idx()));
939
940 OpenSSLAdapter* stream =
941 reinterpret_cast<OpenSSLAdapter*>(SSL_get_app_data(ssl));
942
943 if (!ok && custom_verify_callback_) {
944 void* cert =
945 reinterpret_cast<void*>(X509_STORE_CTX_get_current_cert(store));
946 if (custom_verify_callback_(cert)) {
947 stream->custom_verification_succeeded_ = true;
948 LOG(LS_INFO) << "validated certificate using custom callback";
949 ok = true;
950 }
951 }
952
953 // Should only be used for debugging and development.
954 if (!ok && stream->ignore_bad_cert()) {
955 LOG(LS_WARNING) << "Ignoring cert error while verifying cert chain";
956 ok = 1;
957 }
958
959 return ok;
960 }
961
962 bool OpenSSLAdapter::ConfigureTrustedRootCertificates(SSL_CTX* ctx) {
963 // Add the root cert that we care about to the SSL context
964 int count_of_added_certs = 0;
965 for (size_t i = 0; i < arraysize(kSSLCertCertificateList); i++) {
966 const unsigned char* cert_buffer = kSSLCertCertificateList[i];
967 size_t cert_buffer_len = kSSLCertCertificateSizeList[i];
968 X509* cert =
969 d2i_X509(nullptr, &cert_buffer, checked_cast<long>(cert_buffer_len));
970 if (cert) {
971 int return_value = X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), cert);
972 if (return_value == 0) {
973 LOG(LS_WARNING) << "Unable to add certificate.";
974 } else {
975 count_of_added_certs++;
976 }
977 X509_free(cert);
978 }
979 }
980 return count_of_added_certs > 0;
981 }
982
983 SSL_CTX*
984 OpenSSLAdapter::SetupSSLContext() {
985 // Use (D)TLS 1.2.
986 // Note: BoringSSL supports a range of versions by setting max/min version
987 // (Default V1.0 to V1.2). However (D)TLSv1_2_client_method functions used
988 // below in OpenSSL only support V1.2.
989 SSL_CTX* ctx = nullptr;
990 #ifdef OPENSSL_IS_BORINGSSL
991 ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ? DTLS_method() : TLS_method());
992 #else
993 ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ? DTLSv1_2_client_method()
994 : TLSv1_2_client_method());
995 #endif // OPENSSL_IS_BORINGSSL
996 if (ctx == nullptr) {
997 unsigned long error = ERR_get_error(); // NOLINT: type used by OpenSSL.
998 LOG(LS_WARNING) << "SSL_CTX creation failed: "
999 << '"' << ERR_reason_error_string(error) << "\" "
1000 << "(error=" << error << ')';
1001 return nullptr;
1002 }
1003 if (!ConfigureTrustedRootCertificates(ctx)) {
1004 SSL_CTX_free(ctx);
1005 return nullptr;
1006 }
1007
1008 #if !defined(NDEBUG)
1009 SSL_CTX_set_info_callback(ctx, SSLInfoCallback);
1010 #endif
1011
1012 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, SSLVerifyCallback);
1013 SSL_CTX_set_verify_depth(ctx, 4);
1014 // Use defaults, but disable HMAC-SHA256 and HMAC-SHA384 ciphers
1015 // (note that SHA256 and SHA384 only select legacy CBC ciphers).
1016 // Additionally disable HMAC-SHA1 ciphers in ECDSA. These are the remaining
1017 // CBC-mode ECDSA ciphers.
1018 SSL_CTX_set_cipher_list(
1019 ctx, "ALL:!SHA256:!SHA384:!aPSK:!ECDSA+SHA1:!ADH:!LOW:!EXP:!MD5");
1020
1021 if (ssl_mode_ == SSL_MODE_DTLS) {
1022 SSL_CTX_set_read_ahead(ctx, 1);
1023 }
1024
1025 return ctx;
1026 }
1027
1028 } // namespace rtc
OLDNEW
« no previous file with comments | « webrtc/base/openssladapter.h ('k') | webrtc/base/openssldigest.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698