Home | History | Annotate | Download | only in base
      1 /*
      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>
     44 #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"
     52 #include "talk/base/openssl.h"
     53 #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()
     65 #elif defined(POSIX)
     66   #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 
     76 struct CRYPTO_dynlock_value {
     77   MUTEX_TYPE mutex;
     78 };
     79 
     80 //////////////////////////////////////////////////////////////////////
     81 // SocketBIO
     82 //////////////////////////////////////////////////////////////////////
     83 
     84 static int socket_write(BIO* h, const char* buf, int num);
     85 static int socket_read(BIO* h, char* buf, int size);
     86 static int socket_puts(BIO* h, const char* str);
     87 static long socket_ctrl(BIO* h, int cmd, long arg1, void* arg2);
     88 static int socket_new(BIO* h);
     89 static int socket_free(BIO* data);
     90 
     91 static 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 
    104 BIO_METHOD* BIO_s_socket2() { return(&methods_socket); }
    105 
    106 BIO* 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 
    115 static 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 
    123 static int socket_free(BIO* b) {
    124   if (b == NULL)
    125     return 0;
    126   return 1;
    127 }
    128 
    129 static 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 
    145 static 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 
    159 static int socket_puts(BIO* b, const char* str) {
    160   return socket_write(b, str, strlen(str));
    161 }
    162 
    163 static 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 
    186 namespace talk_base {
    187 
    188 // This array will store all of the mutexes available to OpenSSL.
    189 static MUTEX_TYPE* mutex_buf = NULL;
    190 
    191 static 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 
    199 static 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 
    206 static 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 
    214 static 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 
    223 static void dyn_destroy_function(CRYPTO_dynlock_value* l,
    224                                  const char* file, int line) {
    225   MUTEX_CLEANUP(l->mutex);
    226   delete l;
    227 }
    228 
    229 VerificationCallback OpenSSLAdapter::custom_verify_callback_ = NULL;
    230 
    231 bool OpenSSLAdapter::InitializeSSL(VerificationCallback callback) {
    232   if (!InitializeSSLThread() || !SSL_library_init())
    233       return false;
    234 #if !defined(ADDRESS_SANITIZER) || !defined(OSX)
    235   // Loading the error strings crashes mac_asan.  Omit this debugging aid there.
    236   SSL_load_error_strings();
    237 #endif
    238   ERR_load_BIO_strings();
    239   OpenSSL_add_all_algorithms();
    240   RAND_poll();
    241   custom_verify_callback_ = callback;
    242   return true;
    243 }
    244 
    245 bool 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 
    262 bool 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 
    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_(NULL), ssl_ctx_(NULL),
    284     custom_verification_succeeded_(false) {
    285 }
    286 
    287 OpenSSLAdapter::~OpenSSLAdapter() {
    288   Cleanup();
    289 }
    290 
    291 int
    292 OpenSSLAdapter::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 
    313 int
    314 OpenSSLAdapter::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 
    358 ssl_error:
    359   Cleanup();
    360   if (bio)
    361     BIO_free(bio);
    362 
    363   return err;
    364 }
    365 
    366 int
    367 OpenSSLAdapter::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 
    406 void
    407 OpenSSLAdapter::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 
    416 void
    417 OpenSSLAdapter::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 
    440 int
    441 OpenSSLAdapter::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 
    495 int
    496 OpenSSLAdapter::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 
    550 int
    551 OpenSSLAdapter::Close() {
    552   Cleanup();
    553   state_ = restartable_ ? SSL_WAIT : SSL_NONE;
    554   return AsyncSocketAdapter::Close();
    555 }
    556 
    557 Socket::ConnState
    558 OpenSSLAdapter::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 
    568 void
    569 OpenSSLAdapter::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 
    583 void
    584 OpenSSLAdapter::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 
    613 void
    614 OpenSSLAdapter::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 
    644 void
    645 OpenSSLAdapter::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 
    653 bool 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) {
    691       const X509V3_EXT_METHOD* meth = X509V3_EXT_get(extension);
    692       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 
    702       const unsigned char **ext_value_data_ptr =
    703           (const_cast<const unsigned char **>(&ext_value_data));
    704 
    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 
    760 bool 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 
    780 void
    781 OpenSSLAdapter::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 
    807 int
    808 OpenSSLAdapter::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 
    853 bool 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 
    873 SSL_CTX*
    874 OpenSSLAdapter::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
    902