blob: 9e6fe72c244157ba3306bd638e3a257464294fb7 [file] [log] [blame]
henrike@webrtc.org0e118e72013-07-10 00:45:36 +00001/*
2 * libjingle
3 * Copyright 2008, Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#if HAVE_OPENSSL_SSL_H
29
30#include "talk/base/openssladapter.h"
31
32#if defined(POSIX)
33#include <unistd.h>
34#endif
35
36// Must be included first before openssl headers.
37#include "talk/base/win32.h" // NOLINT
38
39#include <openssl/bio.h>
40#include <openssl/crypto.h>
41#include <openssl/err.h>
42#include <openssl/opensslv.h>
43#include <openssl/rand.h>
henrike@webrtc.org0e118e72013-07-10 00:45:36 +000044#include <openssl/x509v3.h>
45
46#if HAVE_CONFIG_H
47#include "config.h"
48#endif // HAVE_CONFIG_H
49
50#include "talk/base/common.h"
51#include "talk/base/logging.h"
wu@webrtc.org8a77f5b2014-02-13 23:18:49 +000052#include "talk/base/openssl.h"
henrike@webrtc.org0e118e72013-07-10 00:45:36 +000053#include "talk/base/sslroots.h"
54#include "talk/base/stringutils.h"
55
56// TODO: Use a nicer abstraction for mutex.
57
58#if defined(WIN32)
59 #define MUTEX_TYPE HANDLE
60 #define MUTEX_SETUP(x) (x) = CreateMutex(NULL, FALSE, NULL)
61 #define MUTEX_CLEANUP(x) CloseHandle(x)
62 #define MUTEX_LOCK(x) WaitForSingleObject((x), INFINITE)
63 #define MUTEX_UNLOCK(x) ReleaseMutex(x)
64 #define THREAD_ID GetCurrentThreadId()
wu@webrtc.org2a81a382014-01-03 22:08:47 +000065#elif defined(POSIX)
henrike@webrtc.org0e118e72013-07-10 00:45:36 +000066 #define MUTEX_TYPE pthread_mutex_t
67 #define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
68 #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
69 #define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
70 #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
71 #define THREAD_ID pthread_self()
72#else
73 #error You must define mutex operations appropriate for your platform!
74#endif
75
76struct CRYPTO_dynlock_value {
77 MUTEX_TYPE mutex;
78};
79
80//////////////////////////////////////////////////////////////////////
81// SocketBIO
82//////////////////////////////////////////////////////////////////////
83
84static int socket_write(BIO* h, const char* buf, int num);
85static int socket_read(BIO* h, char* buf, int size);
86static int socket_puts(BIO* h, const char* str);
87static long socket_ctrl(BIO* h, int cmd, long arg1, void* arg2);
88static int socket_new(BIO* h);
89static int socket_free(BIO* data);
90
91static BIO_METHOD methods_socket = {
92 BIO_TYPE_BIO,
93 "socket",
94 socket_write,
95 socket_read,
96 socket_puts,
97 0,
98 socket_ctrl,
99 socket_new,
100 socket_free,
101 NULL,
102};
103
104BIO_METHOD* BIO_s_socket2() { return(&methods_socket); }
105
106BIO* BIO_new_socket(talk_base::AsyncSocket* socket) {
107 BIO* ret = BIO_new(BIO_s_socket2());
108 if (ret == NULL) {
109 return NULL;
110 }
111 ret->ptr = socket;
112 return ret;
113}
114
115static int socket_new(BIO* b) {
116 b->shutdown = 0;
117 b->init = 1;
118 b->num = 0; // 1 means socket closed
119 b->ptr = 0;
120 return 1;
121}
122
123static int socket_free(BIO* b) {
124 if (b == NULL)
125 return 0;
126 return 1;
127}
128
129static int socket_read(BIO* b, char* out, int outl) {
130 if (!out)
131 return -1;
132 talk_base::AsyncSocket* socket = static_cast<talk_base::AsyncSocket*>(b->ptr);
133 BIO_clear_retry_flags(b);
134 int result = socket->Recv(out, outl);
135 if (result > 0) {
136 return result;
137 } else if (result == 0) {
138 b->num = 1;
139 } else if (socket->IsBlocking()) {
140 BIO_set_retry_read(b);
141 }
142 return -1;
143}
144
145static int socket_write(BIO* b, const char* in, int inl) {
146 if (!in)
147 return -1;
148 talk_base::AsyncSocket* socket = static_cast<talk_base::AsyncSocket*>(b->ptr);
149 BIO_clear_retry_flags(b);
150 int result = socket->Send(in, inl);
151 if (result > 0) {
152 return result;
153 } else if (socket->IsBlocking()) {
154 BIO_set_retry_write(b);
155 }
156 return -1;
157}
158
159static int socket_puts(BIO* b, const char* str) {
160 return socket_write(b, str, strlen(str));
161}
162
163static long socket_ctrl(BIO* b, int cmd, long num, void* ptr) {
164 UNUSED(num);
165 UNUSED(ptr);
166
167 switch (cmd) {
168 case BIO_CTRL_RESET:
169 return 0;
170 case BIO_CTRL_EOF:
171 return b->num;
172 case BIO_CTRL_WPENDING:
173 case BIO_CTRL_PENDING:
174 return 0;
175 case BIO_CTRL_FLUSH:
176 return 1;
177 default:
178 return 0;
179 }
180}
181
182/////////////////////////////////////////////////////////////////////////////
183// OpenSSLAdapter
184/////////////////////////////////////////////////////////////////////////////
185
186namespace talk_base {
187
188// This array will store all of the mutexes available to OpenSSL.
189static MUTEX_TYPE* mutex_buf = NULL;
190
191static void locking_function(int mode, int n, const char * file, int line) {
192 if (mode & CRYPTO_LOCK) {
193 MUTEX_LOCK(mutex_buf[n]);
194 } else {
195 MUTEX_UNLOCK(mutex_buf[n]);
196 }
197}
198
199static unsigned long id_function() { // NOLINT
200 // Use old-style C cast because THREAD_ID's type varies with the platform,
201 // in some cases requiring static_cast, and in others requiring
202 // reinterpret_cast.
203 return (unsigned long)THREAD_ID; // NOLINT
204}
205
206static CRYPTO_dynlock_value* dyn_create_function(const char* file, int line) {
207 CRYPTO_dynlock_value* value = new CRYPTO_dynlock_value;
208 if (!value)
209 return NULL;
210 MUTEX_SETUP(value->mutex);
211 return value;
212}
213
214static void dyn_lock_function(int mode, CRYPTO_dynlock_value* l,
215 const char* file, int line) {
216 if (mode & CRYPTO_LOCK) {
217 MUTEX_LOCK(l->mutex);
218 } else {
219 MUTEX_UNLOCK(l->mutex);
220 }
221}
222
223static void dyn_destroy_function(CRYPTO_dynlock_value* l,
224 const char* file, int line) {
225 MUTEX_CLEANUP(l->mutex);
226 delete l;
227}
228
229VerificationCallback OpenSSLAdapter::custom_verify_callback_ = NULL;
230
231bool OpenSSLAdapter::InitializeSSL(VerificationCallback callback) {
232 if (!InitializeSSLThread() || !SSL_library_init())
233 return false;
mallinath@webrtc.orgb60e69e2013-09-28 07:24:39 +0000234#if !defined(ADDRESS_SANITIZER) || !defined(OSX)
wu@webrtc.org861d0732013-10-07 23:32:02 +0000235 // Loading the error strings crashes mac_asan. Omit this debugging aid there.
henrike@webrtc.org0e118e72013-07-10 00:45:36 +0000236 SSL_load_error_strings();
mallinath@webrtc.orgb60e69e2013-09-28 07:24:39 +0000237#endif
henrike@webrtc.org0e118e72013-07-10 00:45:36 +0000238 ERR_load_BIO_strings();
239 OpenSSL_add_all_algorithms();
240 RAND_poll();
241 custom_verify_callback_ = callback;
242 return true;
243}
244
245bool OpenSSLAdapter::InitializeSSLThread() {
246 mutex_buf = new MUTEX_TYPE[CRYPTO_num_locks()];
247 if (!mutex_buf)
248 return false;
249 for (int i = 0; i < CRYPTO_num_locks(); ++i)
250 MUTEX_SETUP(mutex_buf[i]);
251
252 // we need to cast our id_function to return an unsigned long -- pthread_t is
253 // a pointer
254 CRYPTO_set_id_callback(id_function);
255 CRYPTO_set_locking_callback(locking_function);
256 CRYPTO_set_dynlock_create_callback(dyn_create_function);
257 CRYPTO_set_dynlock_lock_callback(dyn_lock_function);
258 CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function);
259 return true;
260}
261
262bool OpenSSLAdapter::CleanupSSL() {
263 if (!mutex_buf)
264 return false;
265 CRYPTO_set_id_callback(NULL);
266 CRYPTO_set_locking_callback(NULL);
267 CRYPTO_set_dynlock_create_callback(NULL);
268 CRYPTO_set_dynlock_lock_callback(NULL);
269 CRYPTO_set_dynlock_destroy_callback(NULL);
270 for (int i = 0; i < CRYPTO_num_locks(); ++i)
271 MUTEX_CLEANUP(mutex_buf[i]);
272 delete [] mutex_buf;
273 mutex_buf = NULL;
274 return true;
275}
276
277OpenSSLAdapter::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_(NULL), ssl_ctx_(NULL),
284 custom_verification_succeeded_(false) {
285}
286
287OpenSSLAdapter::~OpenSSLAdapter() {
288 Cleanup();
289}
290
291int
292OpenSSLAdapter::StartSSL(const char* hostname, bool restartable) {
293 if (state_ != SSL_NONE)
294 return -1;
295
296 ssl_host_name_ = hostname;
297 restartable_ = restartable;
298
299 if (socket_->GetState() != Socket::CS_CONNECTED) {
300 state_ = SSL_WAIT;
301 return 0;
302 }
303
304 state_ = SSL_CONNECTING;
305 if (int err = BeginSSL()) {
306 Error("BeginSSL", err, false);
307 return err;
308 }
309
310 return 0;
311}
312
313int
314OpenSSLAdapter::BeginSSL() {
315 LOG(LS_INFO) << "BeginSSL: " << ssl_host_name_;
316 ASSERT(state_ == SSL_CONNECTING);
317
318 int err = 0;
319 BIO* bio = NULL;
320
321 // First set up the context
322 if (!ssl_ctx_)
323 ssl_ctx_ = SetupSSLContext();
324
325 if (!ssl_ctx_) {
326 err = -1;
327 goto ssl_error;
328 }
329
330 bio = BIO_new_socket(static_cast<AsyncSocketAdapter*>(socket_));
331 if (!bio) {
332 err = -1;
333 goto ssl_error;
334 }
335
336 ssl_ = SSL_new(ssl_ctx_);
337 if (!ssl_) {
338 err = -1;
339 goto ssl_error;
340 }
341
342 SSL_set_app_data(ssl_, this);
343
344 SSL_set_bio(ssl_, bio, bio);
345 SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |
346 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
347
348 // the SSL object owns the bio now
349 bio = NULL;
350
351 // Do the connect
352 err = ContinueSSL();
353 if (err != 0)
354 goto ssl_error;
355
356 return err;
357
358ssl_error:
359 Cleanup();
360 if (bio)
361 BIO_free(bio);
362
363 return err;
364}
365
366int
367OpenSSLAdapter::ContinueSSL() {
368 ASSERT(state_ == SSL_CONNECTING);
369
370 int code = SSL_connect(ssl_);
371 switch (SSL_get_error(ssl_, code)) {
372 case SSL_ERROR_NONE:
373 if (!SSLPostConnectionCheck(ssl_, ssl_host_name_.c_str())) {
374 LOG(LS_ERROR) << "TLS post connection check failed";
375 // make sure we close the socket
376 Cleanup();
377 // The connect failed so return -1 to shut down the socket
378 return -1;
379 }
380
381 state_ = SSL_CONNECTED;
382 AsyncSocketAdapter::OnConnectEvent(this);
383#if 0 // TODO: worry about this
384 // Don't let ourselves go away during the callbacks
385 PRefPtr<OpenSSLAdapter> lock(this);
386 LOG(LS_INFO) << " -- onStreamReadable";
387 AsyncSocketAdapter::OnReadEvent(this);
388 LOG(LS_INFO) << " -- onStreamWriteable";
389 AsyncSocketAdapter::OnWriteEvent(this);
390#endif
391 break;
392
393 case SSL_ERROR_WANT_READ:
394 case SSL_ERROR_WANT_WRITE:
395 break;
396
397 case SSL_ERROR_ZERO_RETURN:
398 default:
399 LOG(LS_WARNING) << "ContinueSSL -- error " << code;
400 return (code != 0) ? code : -1;
401 }
402
403 return 0;
404}
405
406void
407OpenSSLAdapter::Error(const char* context, int err, bool signal) {
408 LOG(LS_WARNING) << "OpenSSLAdapter::Error("
409 << context << ", " << err << ")";
410 state_ = SSL_ERROR;
411 SetError(err);
412 if (signal)
413 AsyncSocketAdapter::OnCloseEvent(this, err);
414}
415
416void
417OpenSSLAdapter::Cleanup() {
418 LOG(LS_INFO) << "Cleanup";
419
420 state_ = SSL_NONE;
421 ssl_read_needs_write_ = false;
422 ssl_write_needs_read_ = false;
423 custom_verification_succeeded_ = false;
424
425 if (ssl_) {
426 SSL_free(ssl_);
427 ssl_ = NULL;
428 }
429
430 if (ssl_ctx_) {
431 SSL_CTX_free(ssl_ctx_);
432 ssl_ctx_ = NULL;
433 }
434}
435
436//
437// AsyncSocket Implementation
438//
439
440int
441OpenSSLAdapter::Send(const void* pv, size_t cb) {
442 //LOG(LS_INFO) << "OpenSSLAdapter::Send(" << cb << ")";
443
444 switch (state_) {
445 case SSL_NONE:
446 return AsyncSocketAdapter::Send(pv, cb);
447
448 case SSL_WAIT:
449 case SSL_CONNECTING:
450 SetError(EWOULDBLOCK);
451 return SOCKET_ERROR;
452
453 case SSL_CONNECTED:
454 break;
455
456 case SSL_ERROR:
457 default:
458 return SOCKET_ERROR;
459 }
460
461 // OpenSSL will return an error if we try to write zero bytes
462 if (cb == 0)
463 return 0;
464
465 ssl_write_needs_read_ = false;
466
467 int code = SSL_write(ssl_, pv, cb);
468 switch (SSL_get_error(ssl_, code)) {
469 case SSL_ERROR_NONE:
470 //LOG(LS_INFO) << " -- success";
471 return code;
472 case SSL_ERROR_WANT_READ:
473 //LOG(LS_INFO) << " -- error want read";
474 ssl_write_needs_read_ = true;
475 SetError(EWOULDBLOCK);
476 break;
477 case SSL_ERROR_WANT_WRITE:
478 //LOG(LS_INFO) << " -- error want write";
479 SetError(EWOULDBLOCK);
480 break;
481 case SSL_ERROR_ZERO_RETURN:
482 //LOG(LS_INFO) << " -- remote side closed";
483 SetError(EWOULDBLOCK);
484 // do we need to signal closure?
485 break;
486 default:
487 //LOG(LS_INFO) << " -- error " << code;
488 Error("SSL_write", (code ? code : -1), false);
489 break;
490 }
491
492 return SOCKET_ERROR;
493}
494
495int
496OpenSSLAdapter::Recv(void* pv, size_t cb) {
497 //LOG(LS_INFO) << "OpenSSLAdapter::Recv(" << cb << ")";
498 switch (state_) {
499
500 case SSL_NONE:
501 return AsyncSocketAdapter::Recv(pv, cb);
502
503 case SSL_WAIT:
504 case SSL_CONNECTING:
505 SetError(EWOULDBLOCK);
506 return SOCKET_ERROR;
507
508 case SSL_CONNECTED:
509 break;
510
511 case SSL_ERROR:
512 default:
513 return SOCKET_ERROR;
514 }
515
516 // Don't trust OpenSSL with zero byte reads
517 if (cb == 0)
518 return 0;
519
520 ssl_read_needs_write_ = false;
521
522 int code = SSL_read(ssl_, pv, cb);
523 switch (SSL_get_error(ssl_, code)) {
524 case SSL_ERROR_NONE:
525 //LOG(LS_INFO) << " -- success";
526 return code;
527 case SSL_ERROR_WANT_READ:
528 //LOG(LS_INFO) << " -- error want read";
529 SetError(EWOULDBLOCK);
530 break;
531 case SSL_ERROR_WANT_WRITE:
532 //LOG(LS_INFO) << " -- error want write";
533 ssl_read_needs_write_ = true;
534 SetError(EWOULDBLOCK);
535 break;
536 case SSL_ERROR_ZERO_RETURN:
537 //LOG(LS_INFO) << " -- remote side closed";
538 SetError(EWOULDBLOCK);
539 // do we need to signal closure?
540 break;
541 default:
542 //LOG(LS_INFO) << " -- error " << code;
543 Error("SSL_read", (code ? code : -1), false);
544 break;
545 }
546
547 return SOCKET_ERROR;
548}
549
550int
551OpenSSLAdapter::Close() {
552 Cleanup();
553 state_ = restartable_ ? SSL_WAIT : SSL_NONE;
554 return AsyncSocketAdapter::Close();
555}
556
557Socket::ConnState
558OpenSSLAdapter::GetState() const {
559 //if (signal_close_)
560 // return CS_CONNECTED;
561 ConnState state = socket_->GetState();
562 if ((state == CS_CONNECTED)
563 && ((state_ == SSL_WAIT) || (state_ == SSL_CONNECTING)))
564 state = CS_CONNECTING;
565 return state;
566}
567
568void
569OpenSSLAdapter::OnConnectEvent(AsyncSocket* socket) {
570 LOG(LS_INFO) << "OpenSSLAdapter::OnConnectEvent";
571 if (state_ != SSL_WAIT) {
572 ASSERT(state_ == SSL_NONE);
573 AsyncSocketAdapter::OnConnectEvent(socket);
574 return;
575 }
576
577 state_ = SSL_CONNECTING;
578 if (int err = BeginSSL()) {
579 AsyncSocketAdapter::OnCloseEvent(socket, err);
580 }
581}
582
583void
584OpenSSLAdapter::OnReadEvent(AsyncSocket* socket) {
585 //LOG(LS_INFO) << "OpenSSLAdapter::OnReadEvent";
586
587 if (state_ == SSL_NONE) {
588 AsyncSocketAdapter::OnReadEvent(socket);
589 return;
590 }
591
592 if (state_ == SSL_CONNECTING) {
593 if (int err = ContinueSSL()) {
594 Error("ContinueSSL", err);
595 }
596 return;
597 }
598
599 if (state_ != SSL_CONNECTED)
600 return;
601
602 // Don't let ourselves go away during the callbacks
603 //PRefPtr<OpenSSLAdapter> lock(this); // TODO: fix this
604 if (ssl_write_needs_read_) {
605 //LOG(LS_INFO) << " -- onStreamWriteable";
606 AsyncSocketAdapter::OnWriteEvent(socket);
607 }
608
609 //LOG(LS_INFO) << " -- onStreamReadable";
610 AsyncSocketAdapter::OnReadEvent(socket);
611}
612
613void
614OpenSSLAdapter::OnWriteEvent(AsyncSocket* socket) {
615 //LOG(LS_INFO) << "OpenSSLAdapter::OnWriteEvent";
616
617 if (state_ == SSL_NONE) {
618 AsyncSocketAdapter::OnWriteEvent(socket);
619 return;
620 }
621
622 if (state_ == SSL_CONNECTING) {
623 if (int err = ContinueSSL()) {
624 Error("ContinueSSL", err);
625 }
626 return;
627 }
628
629 if (state_ != SSL_CONNECTED)
630 return;
631
632 // Don't let ourselves go away during the callbacks
633 //PRefPtr<OpenSSLAdapter> lock(this); // TODO: fix this
634
635 if (ssl_read_needs_write_) {
636 //LOG(LS_INFO) << " -- onStreamReadable";
637 AsyncSocketAdapter::OnReadEvent(socket);
638 }
639
640 //LOG(LS_INFO) << " -- onStreamWriteable";
641 AsyncSocketAdapter::OnWriteEvent(socket);
642}
643
644void
645OpenSSLAdapter::OnCloseEvent(AsyncSocket* socket, int err) {
646 LOG(LS_INFO) << "OpenSSLAdapter::OnCloseEvent(" << err << ")";
647 AsyncSocketAdapter::OnCloseEvent(socket, err);
648}
649
650// This code is taken from the "Network Security with OpenSSL"
651// sample in chapter 5
652
653bool OpenSSLAdapter::VerifyServerName(SSL* ssl, const char* host,
654 bool ignore_bad_cert) {
655 if (!host)
656 return false;
657
658 // Checking the return from SSL_get_peer_certificate here is not strictly
659 // necessary. With our setup, it is not possible for it to return
660 // NULL. However, it is good form to check the return.
661 X509* certificate = SSL_get_peer_certificate(ssl);
662 if (!certificate)
663 return false;
664
665 // Logging certificates is extremely verbose. So it is disabled by default.
666#ifdef LOG_CERTIFICATES
667 {
668 LOG(LS_INFO) << "Certificate from server:";
669 BIO* mem = BIO_new(BIO_s_mem());
670 X509_print_ex(mem, certificate, XN_FLAG_SEP_CPLUS_SPC, X509_FLAG_NO_HEADER);
671 BIO_write(mem, "\0", 1);
672 char* buffer;
673 BIO_get_mem_data(mem, &buffer);
674 LOG(LS_INFO) << buffer;
675 BIO_free(mem);
676
677 char* cipher_description =
678 SSL_CIPHER_description(SSL_get_current_cipher(ssl), NULL, 128);
679 LOG(LS_INFO) << "Cipher: " << cipher_description;
680 OPENSSL_free(cipher_description);
681 }
682#endif
683
684 bool ok = false;
685 int extension_count = X509_get_ext_count(certificate);
686 for (int i = 0; i < extension_count; ++i) {
687 X509_EXTENSION* extension = X509_get_ext(certificate, i);
688 int extension_nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension));
689
690 if (extension_nid == NID_subject_alt_name) {
henrike@webrtc.org0e118e72013-07-10 00:45:36 +0000691 const X509V3_EXT_METHOD* meth = X509V3_EXT_get(extension);
henrike@webrtc.org0e118e72013-07-10 00:45:36 +0000692 if (!meth)
693 break;
694
695 void* ext_str = NULL;
696
697 // We assign this to a local variable, instead of passing the address
698 // directly to ASN1_item_d2i.
699 // See http://readlist.com/lists/openssl.org/openssl-users/0/4761.html.
700 unsigned char* ext_value_data = extension->value->data;
701
henrike@webrtc.org0e118e72013-07-10 00:45:36 +0000702 const unsigned char **ext_value_data_ptr =
703 (const_cast<const unsigned char **>(&ext_value_data));
henrike@webrtc.org0e118e72013-07-10 00:45:36 +0000704
705 if (meth->it) {
706 ext_str = ASN1_item_d2i(NULL, ext_value_data_ptr,
707 extension->value->length,
708 ASN1_ITEM_ptr(meth->it));
709 } else {
710 ext_str = meth->d2i(NULL, ext_value_data_ptr, extension->value->length);
711 }
712
713 STACK_OF(CONF_VALUE)* value = meth->i2v(meth, ext_str, NULL);
714 for (int j = 0; j < sk_CONF_VALUE_num(value); ++j) {
715 CONF_VALUE* nval = sk_CONF_VALUE_value(value, j);
716 // The value for nval can contain wildcards
717 if (!strcmp(nval->name, "DNS") && string_match(host, nval->value)) {
718 ok = true;
719 break;
720 }
721 }
722 sk_CONF_VALUE_pop_free(value, X509V3_conf_free);
723 value = NULL;
724
725 if (meth->it) {
726 ASN1_item_free(reinterpret_cast<ASN1_VALUE*>(ext_str),
727 ASN1_ITEM_ptr(meth->it));
728 } else {
729 meth->ext_free(ext_str);
730 }
731 ext_str = NULL;
732 }
733 if (ok)
734 break;
735 }
736
737 char data[256];
738 X509_name_st* subject;
739 if (!ok
740 && ((subject = X509_get_subject_name(certificate)) != NULL)
741 && (X509_NAME_get_text_by_NID(subject, NID_commonName,
742 data, sizeof(data)) > 0)) {
743 data[sizeof(data)-1] = 0;
744 if (_stricmp(data, host) == 0)
745 ok = true;
746 }
747
748 X509_free(certificate);
749
750 // This should only ever be turned on for debugging and development.
751 if (!ok && ignore_bad_cert) {
752 LOG(LS_WARNING) << "TLS certificate check FAILED. "
753 << "Allowing connection anyway.";
754 ok = true;
755 }
756
757 return ok;
758}
759
760bool OpenSSLAdapter::SSLPostConnectionCheck(SSL* ssl, const char* host) {
761 bool ok = VerifyServerName(ssl, host, ignore_bad_cert());
762
763 if (ok) {
764 ok = (SSL_get_verify_result(ssl) == X509_V_OK ||
765 custom_verification_succeeded_);
766 }
767
768 if (!ok && ignore_bad_cert()) {
769 LOG(LS_INFO) << "Other TLS post connection checks failed.";
770 ok = true;
771 }
772
773 return ok;
774}
775
776#if _DEBUG
777
778// We only use this for tracing and so it is only needed in debug mode
779
780void
781OpenSSLAdapter::SSLInfoCallback(const SSL* s, int where, int ret) {
782 const char* str = "undefined";
783 int w = where & ~SSL_ST_MASK;
784 if (w & SSL_ST_CONNECT) {
785 str = "SSL_connect";
786 } else if (w & SSL_ST_ACCEPT) {
787 str = "SSL_accept";
788 }
789 if (where & SSL_CB_LOOP) {
790 LOG(LS_INFO) << str << ":" << SSL_state_string_long(s);
791 } else if (where & SSL_CB_ALERT) {
792 str = (where & SSL_CB_READ) ? "read" : "write";
793 LOG(LS_INFO) << "SSL3 alert " << str
794 << ":" << SSL_alert_type_string_long(ret)
795 << ":" << SSL_alert_desc_string_long(ret);
796 } else if (where & SSL_CB_EXIT) {
797 if (ret == 0) {
798 LOG(LS_INFO) << str << ":failed in " << SSL_state_string_long(s);
799 } else if (ret < 0) {
800 LOG(LS_INFO) << str << ":error in " << SSL_state_string_long(s);
801 }
802 }
803}
804
805#endif // _DEBUG
806
807int
808OpenSSLAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) {
809#if _DEBUG
810 if (!ok) {
811 char data[256];
812 X509* cert = X509_STORE_CTX_get_current_cert(store);
813 int depth = X509_STORE_CTX_get_error_depth(store);
814 int err = X509_STORE_CTX_get_error(store);
815
816 LOG(LS_INFO) << "Error with certificate at depth: " << depth;
817 X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data));
818 LOG(LS_INFO) << " issuer = " << data;
819 X509_NAME_oneline(X509_get_subject_name(cert), data, sizeof(data));
820 LOG(LS_INFO) << " subject = " << data;
821 LOG(LS_INFO) << " err = " << err
822 << ":" << X509_verify_cert_error_string(err);
823 }
824#endif
825
826 // Get our stream pointer from the store
827 SSL* ssl = reinterpret_cast<SSL*>(
828 X509_STORE_CTX_get_ex_data(store,
829 SSL_get_ex_data_X509_STORE_CTX_idx()));
830
831 OpenSSLAdapter* stream =
832 reinterpret_cast<OpenSSLAdapter*>(SSL_get_app_data(ssl));
833
834 if (!ok && custom_verify_callback_) {
835 void* cert =
836 reinterpret_cast<void*>(X509_STORE_CTX_get_current_cert(store));
837 if (custom_verify_callback_(cert)) {
838 stream->custom_verification_succeeded_ = true;
839 LOG(LS_INFO) << "validated certificate using custom callback";
840 ok = true;
841 }
842 }
843
844 // Should only be used for debugging and development.
845 if (!ok && stream->ignore_bad_cert()) {
846 LOG(LS_WARNING) << "Ignoring cert error while verifying cert chain";
847 ok = 1;
848 }
849
850 return ok;
851}
852
853bool OpenSSLAdapter::ConfigureTrustedRootCertificates(SSL_CTX* ctx) {
854 // Add the root cert that we care about to the SSL context
855 int count_of_added_certs = 0;
856 for (int i = 0; i < ARRAY_SIZE(kSSLCertCertificateList); i++) {
857 const unsigned char* cert_buffer = kSSLCertCertificateList[i];
858 size_t cert_buffer_len = kSSLCertCertificateSizeList[i];
859 X509* cert = d2i_X509(NULL, &cert_buffer, cert_buffer_len);
860 if (cert) {
861 int return_value = X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), cert);
862 if (return_value == 0) {
863 LOG(LS_WARNING) << "Unable to add certificate.";
864 } else {
865 count_of_added_certs++;
866 }
867 X509_free(cert);
868 }
869 }
870 return count_of_added_certs > 0;
871}
872
873SSL_CTX*
874OpenSSLAdapter::SetupSSLContext() {
875 SSL_CTX* ctx = SSL_CTX_new(TLSv1_client_method());
876 if (ctx == NULL) {
877 unsigned long error = ERR_get_error(); // NOLINT: type used by OpenSSL.
878 LOG(LS_WARNING) << "SSL_CTX creation failed: "
879 << '"' << ERR_reason_error_string(error) << "\" "
880 << "(error=" << error << ')';
881 return NULL;
882 }
883 if (!ConfigureTrustedRootCertificates(ctx)) {
884 SSL_CTX_free(ctx);
885 return NULL;
886 }
887
888#ifdef _DEBUG
889 SSL_CTX_set_info_callback(ctx, SSLInfoCallback);
890#endif
891
892 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, SSLVerifyCallback);
893 SSL_CTX_set_verify_depth(ctx, 4);
894 SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
895
896 return ctx;
897}
898
899} // namespace talk_base
900
901#endif // HAVE_OPENSSL_SSL_H