blob: 818e326940ff25900fae7736d79c5318fecca16c [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
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#if HAVE_OPENSSL_SSL_H
12
13#include "webrtc/base/openssladapter.h"
14
15#if defined(WEBRTC_POSIX)
16#include <unistd.h>
17#endif
18
19// Must be included first before openssl headers.
20#include "webrtc/base/win32.h" // NOLINT
21
22#include <openssl/bio.h>
23#include <openssl/crypto.h>
24#include <openssl/err.h>
25#include <openssl/opensslv.h>
26#include <openssl/rand.h>
henrike@webrtc.orgd5a05062014-06-30 20:38:56 +000027#include <openssl/x509.h>
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000028#include <openssl/x509v3.h>
29
30#if HAVE_CONFIG_H
31#include "config.h"
32#endif // HAVE_CONFIG_H
33
tfarina5237aaf2015-11-10 23:44:30 -080034#include "webrtc/base/arraysize.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000035#include "webrtc/base/common.h"
36#include "webrtc/base/logging.h"
37#include "webrtc/base/openssl.h"
Tommid44c0772016-03-11 17:12:32 -080038#include "webrtc/base/safe_conversions.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000039#include "webrtc/base/sslroots.h"
40#include "webrtc/base/stringutils.h"
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +000041#include "webrtc/base/thread.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000042
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000043//////////////////////////////////////////////////////////////////////
44// SocketBIO
45//////////////////////////////////////////////////////////////////////
46
47static int socket_write(BIO* h, const char* buf, int num);
48static int socket_read(BIO* h, char* buf, int size);
49static int socket_puts(BIO* h, const char* str);
50static long socket_ctrl(BIO* h, int cmd, long arg1, void* arg2);
51static int socket_new(BIO* h);
52static int socket_free(BIO* data);
53
davidben@webrtc.org36d5c3c2015-01-22 23:06:17 +000054// TODO(davidben): This should be const once BoringSSL is assumed.
55static BIO_METHOD methods_socket = {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000056 BIO_TYPE_BIO,
57 "socket",
58 socket_write,
59 socket_read,
60 socket_puts,
61 0,
62 socket_ctrl,
63 socket_new,
64 socket_free,
65 NULL,
66};
67
davidben@webrtc.org36d5c3c2015-01-22 23:06:17 +000068static BIO_METHOD* BIO_s_socket2() { return(&methods_socket); }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000069
henrike@webrtc.orgc50bf7c2014-05-14 18:24:13 +000070static BIO* BIO_new_socket(rtc::AsyncSocket* socket) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000071 BIO* ret = BIO_new(BIO_s_socket2());
72 if (ret == NULL) {
73 return NULL;
74 }
75 ret->ptr = socket;
76 return ret;
77}
78
79static int socket_new(BIO* b) {
80 b->shutdown = 0;
81 b->init = 1;
82 b->num = 0; // 1 means socket closed
83 b->ptr = 0;
84 return 1;
85}
86
87static int socket_free(BIO* b) {
88 if (b == NULL)
89 return 0;
90 return 1;
91}
92
93static int socket_read(BIO* b, char* out, int outl) {
94 if (!out)
95 return -1;
96 rtc::AsyncSocket* socket = static_cast<rtc::AsyncSocket*>(b->ptr);
97 BIO_clear_retry_flags(b);
98 int result = socket->Recv(out, outl);
99 if (result > 0) {
100 return result;
101 } else if (result == 0) {
102 b->num = 1;
103 } else if (socket->IsBlocking()) {
104 BIO_set_retry_read(b);
105 }
106 return -1;
107}
108
109static int socket_write(BIO* b, const char* in, int inl) {
110 if (!in)
111 return -1;
112 rtc::AsyncSocket* socket = static_cast<rtc::AsyncSocket*>(b->ptr);
113 BIO_clear_retry_flags(b);
114 int result = socket->Send(in, inl);
115 if (result > 0) {
116 return result;
117 } else if (socket->IsBlocking()) {
118 BIO_set_retry_write(b);
119 }
120 return -1;
121}
122
123static int socket_puts(BIO* b, const char* str) {
henrike@webrtc.orgd89b69a2014-11-06 17:23:09 +0000124 return socket_write(b, str, rtc::checked_cast<int>(strlen(str)));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000125}
126
127static long socket_ctrl(BIO* b, int cmd, long num, void* ptr) {
henrike@webrtc.org14abcc72014-05-16 16:54:44 +0000128 RTC_UNUSED(num);
129 RTC_UNUSED(ptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000130
131 switch (cmd) {
132 case BIO_CTRL_RESET:
133 return 0;
134 case BIO_CTRL_EOF:
135 return b->num;
136 case BIO_CTRL_WPENDING:
137 case BIO_CTRL_PENDING:
138 return 0;
139 case BIO_CTRL_FLUSH:
140 return 1;
141 default:
142 return 0;
143 }
144}
145
146/////////////////////////////////////////////////////////////////////////////
147// OpenSSLAdapter
148/////////////////////////////////////////////////////////////////////////////
149
150namespace rtc {
151
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000152VerificationCallback OpenSSLAdapter::custom_verify_callback_ = NULL;
153
154bool OpenSSLAdapter::InitializeSSL(VerificationCallback callback) {
torbjorng4cd331b2016-03-17 11:53:14 -0700155 CRYPTO_library_init();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000156 custom_verify_callback_ = callback;
157 return true;
158}
159
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000160OpenSSLAdapter::OpenSSLAdapter(AsyncSocket* socket)
161 : SSLAdapter(socket),
162 state_(SSL_NONE),
163 ssl_read_needs_write_(false),
164 ssl_write_needs_read_(false),
165 restartable_(false),
166 ssl_(NULL), ssl_ctx_(NULL),
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000167 ssl_mode_(SSL_MODE_TLS),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000168 custom_verification_succeeded_(false) {
169}
170
171OpenSSLAdapter::~OpenSSLAdapter() {
172 Cleanup();
173}
174
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000175void
176OpenSSLAdapter::SetMode(SSLMode mode) {
177 ASSERT(state_ == SSL_NONE);
178 ssl_mode_ = mode;
179}
180
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000181int
182OpenSSLAdapter::StartSSL(const char* hostname, bool restartable) {
183 if (state_ != SSL_NONE)
184 return -1;
185
186 ssl_host_name_ = hostname;
187 restartable_ = restartable;
188
189 if (socket_->GetState() != Socket::CS_CONNECTED) {
190 state_ = SSL_WAIT;
191 return 0;
192 }
193
194 state_ = SSL_CONNECTING;
195 if (int err = BeginSSL()) {
196 Error("BeginSSL", err, false);
197 return err;
198 }
199
200 return 0;
201}
202
203int
204OpenSSLAdapter::BeginSSL() {
205 LOG(LS_INFO) << "BeginSSL: " << ssl_host_name_;
206 ASSERT(state_ == SSL_CONNECTING);
207
208 int err = 0;
209 BIO* bio = NULL;
210
211 // First set up the context
212 if (!ssl_ctx_)
213 ssl_ctx_ = SetupSSLContext();
214
215 if (!ssl_ctx_) {
216 err = -1;
217 goto ssl_error;
218 }
219
Peter Boström0b518bf2016-01-27 12:35:40 +0100220 bio = BIO_new_socket(socket_);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000221 if (!bio) {
222 err = -1;
223 goto ssl_error;
224 }
225
226 ssl_ = SSL_new(ssl_ctx_);
227 if (!ssl_) {
228 err = -1;
229 goto ssl_error;
230 }
231
232 SSL_set_app_data(ssl_, this);
233
234 SSL_set_bio(ssl_, bio, bio);
235 SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |
236 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
237
238 // the SSL object owns the bio now
239 bio = NULL;
240
241 // Do the connect
242 err = ContinueSSL();
243 if (err != 0)
244 goto ssl_error;
245
246 return err;
247
248ssl_error:
249 Cleanup();
250 if (bio)
251 BIO_free(bio);
252
253 return err;
254}
255
256int
257OpenSSLAdapter::ContinueSSL() {
258 ASSERT(state_ == SSL_CONNECTING);
259
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000260 // Clear the DTLS timer
261 Thread::Current()->Clear(this, MSG_TIMEOUT);
262
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000263 int code = SSL_connect(ssl_);
264 switch (SSL_get_error(ssl_, code)) {
265 case SSL_ERROR_NONE:
266 if (!SSLPostConnectionCheck(ssl_, ssl_host_name_.c_str())) {
267 LOG(LS_ERROR) << "TLS post connection check failed";
268 // make sure we close the socket
269 Cleanup();
270 // The connect failed so return -1 to shut down the socket
271 return -1;
272 }
273
274 state_ = SSL_CONNECTED;
275 AsyncSocketAdapter::OnConnectEvent(this);
276#if 0 // TODO: worry about this
277 // Don't let ourselves go away during the callbacks
278 PRefPtr<OpenSSLAdapter> lock(this);
279 LOG(LS_INFO) << " -- onStreamReadable";
280 AsyncSocketAdapter::OnReadEvent(this);
281 LOG(LS_INFO) << " -- onStreamWriteable";
282 AsyncSocketAdapter::OnWriteEvent(this);
283#endif
284 break;
285
286 case SSL_ERROR_WANT_READ:
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000287 LOG(LS_VERBOSE) << " -- error want read";
288 struct timeval timeout;
289 if (DTLSv1_get_timeout(ssl_, &timeout)) {
290 int delay = timeout.tv_sec * 1000 + timeout.tv_usec/1000;
291
292 Thread::Current()->PostDelayed(delay, this, MSG_TIMEOUT, 0);
293 }
294 break;
295
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000296 case SSL_ERROR_WANT_WRITE:
297 break;
298
299 case SSL_ERROR_ZERO_RETURN:
300 default:
301 LOG(LS_WARNING) << "ContinueSSL -- error " << code;
302 return (code != 0) ? code : -1;
303 }
304
305 return 0;
306}
307
308void
309OpenSSLAdapter::Error(const char* context, int err, bool signal) {
310 LOG(LS_WARNING) << "OpenSSLAdapter::Error("
311 << context << ", " << err << ")";
312 state_ = SSL_ERROR;
313 SetError(err);
314 if (signal)
315 AsyncSocketAdapter::OnCloseEvent(this, err);
316}
317
318void
319OpenSSLAdapter::Cleanup() {
320 LOG(LS_INFO) << "Cleanup";
321
322 state_ = SSL_NONE;
323 ssl_read_needs_write_ = false;
324 ssl_write_needs_read_ = false;
325 custom_verification_succeeded_ = false;
326
327 if (ssl_) {
328 SSL_free(ssl_);
329 ssl_ = NULL;
330 }
331
332 if (ssl_ctx_) {
333 SSL_CTX_free(ssl_ctx_);
334 ssl_ctx_ = NULL;
335 }
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000336
337 // Clear the DTLS timer
338 Thread::Current()->Clear(this, MSG_TIMEOUT);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000339}
340
341//
342// AsyncSocket Implementation
343//
344
345int
346OpenSSLAdapter::Send(const void* pv, size_t cb) {
347 //LOG(LS_INFO) << "OpenSSLAdapter::Send(" << cb << ")";
348
349 switch (state_) {
350 case SSL_NONE:
351 return AsyncSocketAdapter::Send(pv, cb);
352
353 case SSL_WAIT:
354 case SSL_CONNECTING:
355 SetError(EWOULDBLOCK);
356 return SOCKET_ERROR;
357
358 case SSL_CONNECTED:
359 break;
360
361 case SSL_ERROR:
362 default:
363 return SOCKET_ERROR;
364 }
365
366 // OpenSSL will return an error if we try to write zero bytes
367 if (cb == 0)
368 return 0;
369
370 ssl_write_needs_read_ = false;
371
henrike@webrtc.orgd89b69a2014-11-06 17:23:09 +0000372 int code = SSL_write(ssl_, pv, checked_cast<int>(cb));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000373 switch (SSL_get_error(ssl_, code)) {
374 case SSL_ERROR_NONE:
375 //LOG(LS_INFO) << " -- success";
376 return code;
377 case SSL_ERROR_WANT_READ:
378 //LOG(LS_INFO) << " -- error want read";
379 ssl_write_needs_read_ = true;
380 SetError(EWOULDBLOCK);
381 break;
382 case SSL_ERROR_WANT_WRITE:
383 //LOG(LS_INFO) << " -- error want write";
384 SetError(EWOULDBLOCK);
385 break;
386 case SSL_ERROR_ZERO_RETURN:
387 //LOG(LS_INFO) << " -- remote side closed";
388 SetError(EWOULDBLOCK);
389 // do we need to signal closure?
390 break;
391 default:
392 //LOG(LS_INFO) << " -- error " << code;
393 Error("SSL_write", (code ? code : -1), false);
394 break;
395 }
396
397 return SOCKET_ERROR;
398}
399
400int
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000401OpenSSLAdapter::SendTo(const void* pv, size_t cb, const SocketAddress& addr) {
402 if (socket_->GetState() == Socket::CS_CONNECTED &&
403 addr == socket_->GetRemoteAddress()) {
404 return Send(pv, cb);
405 }
406
407 SetError(ENOTCONN);
408
409 return SOCKET_ERROR;
410}
411
412int
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000413OpenSSLAdapter::Recv(void* pv, size_t cb) {
414 //LOG(LS_INFO) << "OpenSSLAdapter::Recv(" << cb << ")";
415 switch (state_) {
416
417 case SSL_NONE:
418 return AsyncSocketAdapter::Recv(pv, cb);
419
420 case SSL_WAIT:
421 case SSL_CONNECTING:
422 SetError(EWOULDBLOCK);
423 return SOCKET_ERROR;
424
425 case SSL_CONNECTED:
426 break;
427
428 case SSL_ERROR:
429 default:
430 return SOCKET_ERROR;
431 }
432
433 // Don't trust OpenSSL with zero byte reads
434 if (cb == 0)
435 return 0;
436
437 ssl_read_needs_write_ = false;
438
henrike@webrtc.orgd89b69a2014-11-06 17:23:09 +0000439 int code = SSL_read(ssl_, pv, checked_cast<int>(cb));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000440 switch (SSL_get_error(ssl_, code)) {
441 case SSL_ERROR_NONE:
442 //LOG(LS_INFO) << " -- success";
443 return code;
444 case SSL_ERROR_WANT_READ:
445 //LOG(LS_INFO) << " -- error want read";
446 SetError(EWOULDBLOCK);
447 break;
448 case SSL_ERROR_WANT_WRITE:
449 //LOG(LS_INFO) << " -- error want write";
450 ssl_read_needs_write_ = true;
451 SetError(EWOULDBLOCK);
452 break;
453 case SSL_ERROR_ZERO_RETURN:
454 //LOG(LS_INFO) << " -- remote side closed";
455 SetError(EWOULDBLOCK);
456 // do we need to signal closure?
457 break;
458 default:
459 //LOG(LS_INFO) << " -- error " << code;
460 Error("SSL_read", (code ? code : -1), false);
461 break;
462 }
463
464 return SOCKET_ERROR;
465}
466
467int
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000468OpenSSLAdapter::RecvFrom(void* pv, size_t cb, SocketAddress* paddr) {
469 if (socket_->GetState() == Socket::CS_CONNECTED) {
470 int ret = Recv(pv, cb);
471
472 *paddr = GetRemoteAddress();
473
474 return ret;
475 }
476
477 SetError(ENOTCONN);
478
479 return SOCKET_ERROR;
480}
481
482int
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000483OpenSSLAdapter::Close() {
484 Cleanup();
485 state_ = restartable_ ? SSL_WAIT : SSL_NONE;
486 return AsyncSocketAdapter::Close();
487}
488
489Socket::ConnState
490OpenSSLAdapter::GetState() const {
491 //if (signal_close_)
492 // return CS_CONNECTED;
493 ConnState state = socket_->GetState();
494 if ((state == CS_CONNECTED)
495 && ((state_ == SSL_WAIT) || (state_ == SSL_CONNECTING)))
496 state = CS_CONNECTING;
497 return state;
498}
499
500void
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000501OpenSSLAdapter::OnMessage(Message* msg) {
502 if (MSG_TIMEOUT == msg->message_id) {
503 LOG(LS_INFO) << "DTLS timeout expired";
504 DTLSv1_handle_timeout(ssl_);
505 ContinueSSL();
506 }
507}
508
509void
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000510OpenSSLAdapter::OnConnectEvent(AsyncSocket* socket) {
511 LOG(LS_INFO) << "OpenSSLAdapter::OnConnectEvent";
512 if (state_ != SSL_WAIT) {
513 ASSERT(state_ == SSL_NONE);
514 AsyncSocketAdapter::OnConnectEvent(socket);
515 return;
516 }
517
518 state_ = SSL_CONNECTING;
519 if (int err = BeginSSL()) {
520 AsyncSocketAdapter::OnCloseEvent(socket, err);
521 }
522}
523
524void
525OpenSSLAdapter::OnReadEvent(AsyncSocket* socket) {
526 //LOG(LS_INFO) << "OpenSSLAdapter::OnReadEvent";
527
528 if (state_ == SSL_NONE) {
529 AsyncSocketAdapter::OnReadEvent(socket);
530 return;
531 }
532
533 if (state_ == SSL_CONNECTING) {
534 if (int err = ContinueSSL()) {
535 Error("ContinueSSL", err);
536 }
537 return;
538 }
539
540 if (state_ != SSL_CONNECTED)
541 return;
542
543 // Don't let ourselves go away during the callbacks
544 //PRefPtr<OpenSSLAdapter> lock(this); // TODO: fix this
545 if (ssl_write_needs_read_) {
546 //LOG(LS_INFO) << " -- onStreamWriteable";
547 AsyncSocketAdapter::OnWriteEvent(socket);
548 }
549
550 //LOG(LS_INFO) << " -- onStreamReadable";
551 AsyncSocketAdapter::OnReadEvent(socket);
552}
553
554void
555OpenSSLAdapter::OnWriteEvent(AsyncSocket* socket) {
556 //LOG(LS_INFO) << "OpenSSLAdapter::OnWriteEvent";
557
558 if (state_ == SSL_NONE) {
559 AsyncSocketAdapter::OnWriteEvent(socket);
560 return;
561 }
562
563 if (state_ == SSL_CONNECTING) {
564 if (int err = ContinueSSL()) {
565 Error("ContinueSSL", err);
566 }
567 return;
568 }
569
570 if (state_ != SSL_CONNECTED)
571 return;
572
573 // Don't let ourselves go away during the callbacks
574 //PRefPtr<OpenSSLAdapter> lock(this); // TODO: fix this
575
576 if (ssl_read_needs_write_) {
577 //LOG(LS_INFO) << " -- onStreamReadable";
578 AsyncSocketAdapter::OnReadEvent(socket);
579 }
580
581 //LOG(LS_INFO) << " -- onStreamWriteable";
582 AsyncSocketAdapter::OnWriteEvent(socket);
583}
584
585void
586OpenSSLAdapter::OnCloseEvent(AsyncSocket* socket, int err) {
587 LOG(LS_INFO) << "OpenSSLAdapter::OnCloseEvent(" << err << ")";
588 AsyncSocketAdapter::OnCloseEvent(socket, err);
589}
590
591// This code is taken from the "Network Security with OpenSSL"
592// sample in chapter 5
593
594bool OpenSSLAdapter::VerifyServerName(SSL* ssl, const char* host,
595 bool ignore_bad_cert) {
596 if (!host)
597 return false;
598
599 // Checking the return from SSL_get_peer_certificate here is not strictly
600 // necessary. With our setup, it is not possible for it to return
601 // NULL. However, it is good form to check the return.
602 X509* certificate = SSL_get_peer_certificate(ssl);
603 if (!certificate)
604 return false;
605
606 // Logging certificates is extremely verbose. So it is disabled by default.
607#ifdef LOG_CERTIFICATES
608 {
609 LOG(LS_INFO) << "Certificate from server:";
610 BIO* mem = BIO_new(BIO_s_mem());
611 X509_print_ex(mem, certificate, XN_FLAG_SEP_CPLUS_SPC, X509_FLAG_NO_HEADER);
612 BIO_write(mem, "\0", 1);
613 char* buffer;
614 BIO_get_mem_data(mem, &buffer);
615 LOG(LS_INFO) << buffer;
616 BIO_free(mem);
617
618 char* cipher_description =
619 SSL_CIPHER_description(SSL_get_current_cipher(ssl), NULL, 128);
620 LOG(LS_INFO) << "Cipher: " << cipher_description;
621 OPENSSL_free(cipher_description);
622 }
623#endif
624
625 bool ok = false;
626 int extension_count = X509_get_ext_count(certificate);
627 for (int i = 0; i < extension_count; ++i) {
628 X509_EXTENSION* extension = X509_get_ext(certificate, i);
629 int extension_nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension));
630
631 if (extension_nid == NID_subject_alt_name) {
632 const X509V3_EXT_METHOD* meth = X509V3_EXT_get(extension);
633 if (!meth)
634 break;
635
636 void* ext_str = NULL;
637
638 // We assign this to a local variable, instead of passing the address
639 // directly to ASN1_item_d2i.
640 // See http://readlist.com/lists/openssl.org/openssl-users/0/4761.html.
641 unsigned char* ext_value_data = extension->value->data;
642
643 const unsigned char **ext_value_data_ptr =
644 (const_cast<const unsigned char **>(&ext_value_data));
645
646 if (meth->it) {
647 ext_str = ASN1_item_d2i(NULL, ext_value_data_ptr,
648 extension->value->length,
649 ASN1_ITEM_ptr(meth->it));
650 } else {
651 ext_str = meth->d2i(NULL, ext_value_data_ptr, extension->value->length);
652 }
653
654 STACK_OF(CONF_VALUE)* value = meth->i2v(meth, ext_str, NULL);
henrike@webrtc.org92a9bac2014-07-14 22:03:57 +0000655
656 // Cast to size_t to be compilable for both OpenSSL and BoringSSL.
657 for (size_t j = 0; j < static_cast<size_t>(sk_CONF_VALUE_num(value));
658 ++j) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000659 CONF_VALUE* nval = sk_CONF_VALUE_value(value, j);
660 // The value for nval can contain wildcards
661 if (!strcmp(nval->name, "DNS") && string_match(host, nval->value)) {
662 ok = true;
663 break;
664 }
665 }
666 sk_CONF_VALUE_pop_free(value, X509V3_conf_free);
667 value = NULL;
668
669 if (meth->it) {
670 ASN1_item_free(reinterpret_cast<ASN1_VALUE*>(ext_str),
671 ASN1_ITEM_ptr(meth->it));
672 } else {
673 meth->ext_free(ext_str);
674 }
675 ext_str = NULL;
676 }
677 if (ok)
678 break;
679 }
680
681 char data[256];
henrike@webrtc.orgd5a05062014-06-30 20:38:56 +0000682 X509_NAME* subject;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000683 if (!ok
684 && ((subject = X509_get_subject_name(certificate)) != NULL)
685 && (X509_NAME_get_text_by_NID(subject, NID_commonName,
686 data, sizeof(data)) > 0)) {
687 data[sizeof(data)-1] = 0;
688 if (_stricmp(data, host) == 0)
689 ok = true;
690 }
691
692 X509_free(certificate);
693
694 // This should only ever be turned on for debugging and development.
695 if (!ok && ignore_bad_cert) {
696 LOG(LS_WARNING) << "TLS certificate check FAILED. "
697 << "Allowing connection anyway.";
698 ok = true;
699 }
700
701 return ok;
702}
703
704bool OpenSSLAdapter::SSLPostConnectionCheck(SSL* ssl, const char* host) {
705 bool ok = VerifyServerName(ssl, host, ignore_bad_cert());
706
707 if (ok) {
708 ok = (SSL_get_verify_result(ssl) == X509_V_OK ||
709 custom_verification_succeeded_);
710 }
711
712 if (!ok && ignore_bad_cert()) {
713 LOG(LS_INFO) << "Other TLS post connection checks failed.";
714 ok = true;
715 }
716
717 return ok;
718}
719
tfarinaa41ab932015-10-30 16:08:48 -0700720#if !defined(NDEBUG)
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000721
722// We only use this for tracing and so it is only needed in debug mode
723
724void
725OpenSSLAdapter::SSLInfoCallback(const SSL* s, int where, int ret) {
726 const char* str = "undefined";
727 int w = where & ~SSL_ST_MASK;
728 if (w & SSL_ST_CONNECT) {
729 str = "SSL_connect";
730 } else if (w & SSL_ST_ACCEPT) {
731 str = "SSL_accept";
732 }
733 if (where & SSL_CB_LOOP) {
734 LOG(LS_INFO) << str << ":" << SSL_state_string_long(s);
735 } else if (where & SSL_CB_ALERT) {
736 str = (where & SSL_CB_READ) ? "read" : "write";
737 LOG(LS_INFO) << "SSL3 alert " << str
738 << ":" << SSL_alert_type_string_long(ret)
739 << ":" << SSL_alert_desc_string_long(ret);
740 } else if (where & SSL_CB_EXIT) {
741 if (ret == 0) {
742 LOG(LS_INFO) << str << ":failed in " << SSL_state_string_long(s);
743 } else if (ret < 0) {
744 LOG(LS_INFO) << str << ":error in " << SSL_state_string_long(s);
745 }
746 }
747}
748
tfarinaa41ab932015-10-30 16:08:48 -0700749#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000750
751int
752OpenSSLAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) {
tfarinaa41ab932015-10-30 16:08:48 -0700753#if !defined(NDEBUG)
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000754 if (!ok) {
755 char data[256];
756 X509* cert = X509_STORE_CTX_get_current_cert(store);
757 int depth = X509_STORE_CTX_get_error_depth(store);
758 int err = X509_STORE_CTX_get_error(store);
759
760 LOG(LS_INFO) << "Error with certificate at depth: " << depth;
761 X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data));
762 LOG(LS_INFO) << " issuer = " << data;
763 X509_NAME_oneline(X509_get_subject_name(cert), data, sizeof(data));
764 LOG(LS_INFO) << " subject = " << data;
765 LOG(LS_INFO) << " err = " << err
766 << ":" << X509_verify_cert_error_string(err);
767 }
768#endif
769
770 // Get our stream pointer from the store
771 SSL* ssl = reinterpret_cast<SSL*>(
772 X509_STORE_CTX_get_ex_data(store,
773 SSL_get_ex_data_X509_STORE_CTX_idx()));
774
775 OpenSSLAdapter* stream =
776 reinterpret_cast<OpenSSLAdapter*>(SSL_get_app_data(ssl));
777
778 if (!ok && custom_verify_callback_) {
779 void* cert =
780 reinterpret_cast<void*>(X509_STORE_CTX_get_current_cert(store));
781 if (custom_verify_callback_(cert)) {
782 stream->custom_verification_succeeded_ = true;
783 LOG(LS_INFO) << "validated certificate using custom callback";
784 ok = true;
785 }
786 }
787
788 // Should only be used for debugging and development.
789 if (!ok && stream->ignore_bad_cert()) {
790 LOG(LS_WARNING) << "Ignoring cert error while verifying cert chain";
791 ok = 1;
792 }
793
794 return ok;
795}
796
797bool OpenSSLAdapter::ConfigureTrustedRootCertificates(SSL_CTX* ctx) {
798 // Add the root cert that we care about to the SSL context
799 int count_of_added_certs = 0;
tfarina5237aaf2015-11-10 23:44:30 -0800800 for (size_t i = 0; i < arraysize(kSSLCertCertificateList); i++) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000801 const unsigned char* cert_buffer = kSSLCertCertificateList[i];
802 size_t cert_buffer_len = kSSLCertCertificateSizeList[i];
henrike@webrtc.orgd89b69a2014-11-06 17:23:09 +0000803 X509* cert = d2i_X509(NULL, &cert_buffer,
804 checked_cast<long>(cert_buffer_len));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000805 if (cert) {
806 int return_value = X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), cert);
807 if (return_value == 0) {
808 LOG(LS_WARNING) << "Unable to add certificate.";
809 } else {
810 count_of_added_certs++;
811 }
812 X509_free(cert);
813 }
814 }
815 return count_of_added_certs > 0;
816}
817
818SSL_CTX*
819OpenSSLAdapter::SetupSSLContext() {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000820 SSL_CTX* ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
821 DTLSv1_client_method() : TLSv1_client_method());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000822 if (ctx == NULL) {
823 unsigned long error = ERR_get_error(); // NOLINT: type used by OpenSSL.
824 LOG(LS_WARNING) << "SSL_CTX creation failed: "
825 << '"' << ERR_reason_error_string(error) << "\" "
826 << "(error=" << error << ')';
827 return NULL;
828 }
829 if (!ConfigureTrustedRootCertificates(ctx)) {
830 SSL_CTX_free(ctx);
831 return NULL;
832 }
833
tfarinaa41ab932015-10-30 16:08:48 -0700834#if !defined(NDEBUG)
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000835 SSL_CTX_set_info_callback(ctx, SSLInfoCallback);
836#endif
837
838 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, SSLVerifyCallback);
839 SSL_CTX_set_verify_depth(ctx, 4);
840 SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
841
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000842 if (ssl_mode_ == SSL_MODE_DTLS) {
843 SSL_CTX_set_read_ahead(ctx, 1);
844 }
845
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000846 return ctx;
847}
848
849} // namespace rtc
850
851#endif // HAVE_OPENSSL_SSL_H