• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libjingle
3  * Copyright 2004--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_CONFIG_H
29 #include "config.h"
30 #endif  // HAVE_CONFIG_H
31 
32 #if HAVE_OPENSSL_SSL_H
33 
34 #include "talk/base/opensslstreamadapter.h"
35 
36 #include <openssl/bio.h>
37 #include <openssl/crypto.h>
38 #include <openssl/err.h>
39 #include <openssl/rand.h>
40 #include <openssl/ssl.h>
41 #include <openssl/x509v3.h>
42 
43 #include "talk/base/common.h"
44 #include "talk/base/logging.h"
45 #include "talk/base/stream.h"
46 #include "talk/base/openssladapter.h"
47 #include "talk/base/opensslidentity.h"
48 #include "talk/base/stringutils.h"
49 
50 namespace talk_base {
51 
52 //////////////////////////////////////////////////////////////////////
53 // StreamBIO
54 //////////////////////////////////////////////////////////////////////
55 
56 static int stream_write(BIO* h, const char* buf, int num);
57 static int stream_read(BIO* h, char* buf, int size);
58 static int stream_puts(BIO* h, const char* str);
59 static long stream_ctrl(BIO* h, int cmd, long arg1, void* arg2);
60 static int stream_new(BIO* h);
61 static int stream_free(BIO* data);
62 
63 static BIO_METHOD methods_stream = {
64   BIO_TYPE_BIO,
65   "stream",
66   stream_write,
67   stream_read,
68   stream_puts,
69   0,
70   stream_ctrl,
71   stream_new,
72   stream_free,
73   NULL,
74 };
75 
BIO_s_stream()76 static BIO_METHOD* BIO_s_stream() { return(&methods_stream); }
77 
BIO_new_stream(StreamInterface * stream)78 static BIO* BIO_new_stream(StreamInterface* stream) {
79   BIO* ret = BIO_new(BIO_s_stream());
80   if (ret == NULL)
81     return NULL;
82   ret->ptr = stream;
83   return ret;
84 }
85 
86 // bio methods return 1 (or at least non-zero) on success and 0 on failure.
87 
stream_new(BIO * b)88 static int stream_new(BIO* b) {
89   b->shutdown = 0;
90   b->init = 1;
91   b->num = 0;  // 1 means end-of-stream
92   b->ptr = 0;
93   return 1;
94 }
95 
stream_free(BIO * b)96 static int stream_free(BIO* b) {
97   if (b == NULL)
98     return 0;
99   return 1;
100 }
101 
stream_read(BIO * b,char * out,int outl)102 static int stream_read(BIO* b, char* out, int outl) {
103   if (!out)
104     return -1;
105   StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);
106   BIO_clear_retry_flags(b);
107   size_t read;
108   int error;
109   StreamResult result = stream->Read(out, outl, &read, &error);
110   if (result == SR_SUCCESS) {
111     return read;
112   } else if (result == SR_EOS) {
113     b->num = 1;
114   } else if (result == SR_BLOCK) {
115     BIO_set_retry_read(b);
116   }
117   return -1;
118 }
119 
stream_write(BIO * b,const char * in,int inl)120 static int stream_write(BIO* b, const char* in, int inl) {
121   if (!in)
122     return -1;
123   StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);
124   BIO_clear_retry_flags(b);
125   size_t written;
126   int error;
127   StreamResult result = stream->Write(in, inl, &written, &error);
128   if (result == SR_SUCCESS) {
129     return written;
130   } else if (result == SR_BLOCK) {
131     BIO_set_retry_write(b);
132   }
133   return -1;
134 }
135 
stream_puts(BIO * b,const char * str)136 static int stream_puts(BIO* b, const char* str) {
137   return stream_write(b, str, strlen(str));
138 }
139 
stream_ctrl(BIO * b,int cmd,long num,void * ptr)140 static long stream_ctrl(BIO* b, int cmd, long num, void* ptr) {
141   UNUSED(num);
142   UNUSED(ptr);
143 
144   switch (cmd) {
145     case BIO_CTRL_RESET:
146       return 0;
147     case BIO_CTRL_EOF:
148       return b->num;
149     case BIO_CTRL_WPENDING:
150     case BIO_CTRL_PENDING:
151       return 0;
152     case BIO_CTRL_FLUSH:
153       return 1;
154     default:
155       return 0;
156   }
157 }
158 
159 /////////////////////////////////////////////////////////////////////////////
160 // OpenSSLStreamAdapter
161 /////////////////////////////////////////////////////////////////////////////
162 
OpenSSLStreamAdapter(StreamInterface * stream)163 OpenSSLStreamAdapter::OpenSSLStreamAdapter(StreamInterface* stream)
164     : SSLStreamAdapter(stream),
165       state_(SSL_NONE),
166       role_(SSL_CLIENT),
167       ssl_read_needs_write_(false), ssl_write_needs_read_(false),
168       ssl_(NULL), ssl_ctx_(NULL),
169       custom_verification_succeeded_(false) {
170 }
171 
~OpenSSLStreamAdapter()172 OpenSSLStreamAdapter::~OpenSSLStreamAdapter() {
173   Cleanup();
174 }
175 
SetIdentity(SSLIdentity * identity)176 void OpenSSLStreamAdapter::SetIdentity(SSLIdentity* identity) {
177   ASSERT(identity_.get() == NULL);
178   identity_.reset(static_cast<OpenSSLIdentity*>(identity));
179 }
180 
SetServerRole()181 void OpenSSLStreamAdapter::SetServerRole() {
182   role_ = SSL_SERVER;
183 }
184 
SetPeerCertificate(SSLCertificate * cert)185 void OpenSSLStreamAdapter::SetPeerCertificate(SSLCertificate* cert) {
186   ASSERT(peer_certificate_.get() == NULL);
187   ASSERT(ssl_server_name_.empty());
188   peer_certificate_.reset(static_cast<OpenSSLCertificate*>(cert));
189 }
190 
StartSSLWithServer(const char * server_name)191 int OpenSSLStreamAdapter::StartSSLWithServer(const char* server_name) {
192   ASSERT(server_name != NULL && server_name[0] != '\0');
193   ssl_server_name_ = server_name;
194   return StartSSL();
195 }
196 
StartSSLWithPeer()197 int OpenSSLStreamAdapter::StartSSLWithPeer() {
198   ASSERT(ssl_server_name_.empty());
199   // It is permitted to specify peer_certificate_ only later.
200   return StartSSL();
201 }
202 
203 //
204 // StreamInterface Implementation
205 //
206 
Write(const void * data,size_t data_len,size_t * written,int * error)207 StreamResult OpenSSLStreamAdapter::Write(const void* data, size_t data_len,
208                                          size_t* written, int* error) {
209   LOG(LS_INFO) << "OpenSSLStreamAdapter::Write(" << data_len << ")";
210 
211   switch (state_) {
212   case SSL_NONE:
213     // pass-through in clear text
214     return StreamAdapterInterface::Write(data, data_len, written, error);
215 
216   case SSL_WAIT:
217   case SSL_CONNECTING:
218     return SR_BLOCK;
219 
220   case SSL_CONNECTED:
221     break;
222 
223   case SSL_ERROR:
224   case SSL_CLOSED:
225   default:
226     if (error)
227       *error = ssl_error_code_;
228     return SR_ERROR;
229   }
230 
231   // OpenSSL will return an error if we try to write zero bytes
232   if (data_len == 0) {
233     if (written)
234       *written = 0;
235     return SR_SUCCESS;
236   }
237 
238   ssl_write_needs_read_ = false;
239 
240   int code = SSL_write(ssl_, data, data_len);
241   switch (SSL_get_error(ssl_, code)) {
242   case SSL_ERROR_NONE:
243     LOG(LS_INFO) << " -- success";
244     ASSERT(0 < code && static_cast<unsigned>(code) <= data_len);
245     if (written)
246       *written = code;
247     return SR_SUCCESS;
248   case SSL_ERROR_WANT_READ:
249     LOG(LS_INFO) << " -- error want read";
250     ssl_write_needs_read_ = true;
251     return SR_BLOCK;
252   case SSL_ERROR_WANT_WRITE:
253     LOG(LS_INFO) << " -- error want write";
254     return SR_BLOCK;
255 
256   case SSL_ERROR_ZERO_RETURN:
257   default:
258     Error("SSL_write", (code ? code : -1), false);
259     if (error)
260       *error = ssl_error_code_;
261     return SR_ERROR;
262   }
263   // not reached
264 }
265 
Read(void * data,size_t data_len,size_t * read,int * error)266 StreamResult OpenSSLStreamAdapter::Read(void* data, size_t data_len,
267                                         size_t* read, int* error) {
268   LOG(LS_INFO) << "OpenSSLStreamAdapter::Read(" << data_len << ")";
269   switch (state_) {
270     case SSL_NONE:
271       // pass-through in clear text
272       return StreamAdapterInterface::Read(data, data_len, read, error);
273 
274     case SSL_WAIT:
275     case SSL_CONNECTING:
276       return SR_BLOCK;
277 
278     case SSL_CONNECTED:
279       break;
280 
281     case SSL_CLOSED:
282       return SR_EOS;
283 
284     case SSL_ERROR:
285     default:
286       if (error)
287         *error = ssl_error_code_;
288       return SR_ERROR;
289   }
290 
291   // Don't trust OpenSSL with zero byte reads
292   if (data_len == 0) {
293     if (read)
294       *read = 0;
295     return SR_SUCCESS;
296   }
297 
298   ssl_read_needs_write_ = false;
299 
300   int code = SSL_read(ssl_, data, data_len);
301   switch (SSL_get_error(ssl_, code)) {
302     case SSL_ERROR_NONE:
303       LOG(LS_INFO) << " -- success";
304       ASSERT(0 < code && static_cast<unsigned>(code) <= data_len);
305       if (read)
306         *read = code;
307       return SR_SUCCESS;
308     case SSL_ERROR_WANT_READ:
309       LOG(LS_INFO) << " -- error want read";
310       return SR_BLOCK;
311     case SSL_ERROR_WANT_WRITE:
312       LOG(LS_INFO) << " -- error want write";
313       ssl_read_needs_write_ = true;
314       return SR_BLOCK;
315     case SSL_ERROR_ZERO_RETURN:
316       LOG(LS_INFO) << " -- remote side closed";
317       return SR_EOS;
318       break;
319     default:
320       LOG(LS_INFO) << " -- error " << code;
321       Error("SSL_read", (code ? code : -1), false);
322       if (error)
323         *error = ssl_error_code_;
324       return SR_ERROR;
325   }
326   // not reached
327 }
328 
Close()329 void OpenSSLStreamAdapter::Close() {
330   Cleanup();
331   ASSERT(state_ == SSL_CLOSED || state_ == SSL_ERROR);
332   StreamAdapterInterface::Close();
333 }
334 
GetState() const335 StreamState OpenSSLStreamAdapter::GetState() const {
336   switch(state_) {
337     case SSL_WAIT:
338     case SSL_CONNECTING:
339       return SS_OPENING;
340     case SSL_CONNECTED:
341       return SS_OPEN;
342     default:
343       return SS_CLOSED;
344   };
345   // not reached
346 }
347 
OnEvent(StreamInterface * stream,int events,int err)348 void OpenSSLStreamAdapter::OnEvent(StreamInterface* stream, int events,
349                                    int err) {
350   int events_to_signal = 0;
351   int signal_error = 0;
352   ASSERT(stream == this->stream());
353   if ((events & SE_OPEN)) {
354     LOG(LS_INFO) << "OpenSSLStreamAdapter::OnEvent SE_OPEN";
355     if (state_ != SSL_WAIT) {
356       ASSERT(state_ == SSL_NONE);
357       events_to_signal |= SE_OPEN;
358     } else {
359       state_ = SSL_CONNECTING;
360       if (int err = BeginSSL()) {
361         Error("BeginSSL", err, true);
362         return;
363       }
364     }
365   }
366   if ((events & (SE_READ|SE_WRITE))) {
367     LOG(LS_INFO) << "OpenSSLStreamAdapter::OnEvent"
368                  << ((events & SE_READ) ? " SE_READ" : "")
369                  << ((events & SE_WRITE) ? " SE_WRITE" : "");
370     if (state_ == SSL_NONE) {
371       events_to_signal |= events & (SE_READ|SE_WRITE);
372     } else if (state_ == SSL_CONNECTING) {
373       if (int err = ContinueSSL()) {
374         Error("ContinueSSL", err, true);
375         return;
376       }
377     } else if (state_ == SSL_CONNECTED) {
378       if (((events & SE_READ) && ssl_write_needs_read_) ||
379           (events & SE_WRITE)) {
380         LOG(LS_INFO) << " -- onStreamWriteable";
381         events_to_signal |= SE_WRITE;
382       }
383       if (((events & SE_WRITE) && ssl_read_needs_write_) ||
384           (events & SE_READ)) {
385         LOG(LS_INFO) << " -- onStreamReadable";
386         events_to_signal |= SE_READ;
387       }
388     }
389   }
390   if ((events & SE_CLOSE)) {
391     LOG(LS_INFO) << "OpenSSLStreamAdapter::OnEvent(SE_CLOSE, " << err << ")";
392     Cleanup();
393     events_to_signal |= SE_CLOSE;
394     // SE_CLOSE is the only event that uses the final parameter to OnEvent().
395     ASSERT(signal_error == 0);
396     signal_error = err;
397   }
398   if(events_to_signal)
399     StreamAdapterInterface::OnEvent(stream, events_to_signal, signal_error);
400 }
401 
StartSSL()402 int OpenSSLStreamAdapter::StartSSL() {
403   ASSERT(state_ == SSL_NONE);
404 
405   if (StreamAdapterInterface::GetState() != SS_OPEN) {
406     state_ = SSL_WAIT;
407     return 0;
408   }
409 
410   state_ = SSL_CONNECTING;
411   if (int err = BeginSSL()) {
412     Error("BeginSSL", err, false);
413     return err;
414   }
415 
416   return 0;
417 }
418 
BeginSSL()419 int OpenSSLStreamAdapter::BeginSSL() {
420   ASSERT(state_ == SSL_CONNECTING);
421   // The underlying stream has open. If we are in peer-to-peer mode
422   // then a peer certificate must have been specified by now.
423   ASSERT(!ssl_server_name_.empty() || peer_certificate_.get() != NULL);
424   LOG(LS_INFO) << "BeginSSL: "
425                << (!ssl_server_name_.empty() ? ssl_server_name_ :
426                                                "with peer");
427 
428   BIO* bio = NULL;
429 
430   // First set up the context
431   ASSERT(ssl_ctx_ == NULL);
432   ssl_ctx_ = SetupSSLContext();
433   if (!ssl_ctx_)
434     return -1;
435 
436   bio = BIO_new_stream(static_cast<StreamInterface*>(stream()));
437   if (!bio)
438     return -1;
439 
440   ssl_ = SSL_new(ssl_ctx_);
441   if (!ssl_) {
442     BIO_free(bio);
443     return -1;
444   }
445 
446   SSL_set_app_data(ssl_, this);
447 
448   SSL_set_bio(ssl_, bio, bio);  // the SSL object owns the bio now.
449 
450   SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |
451                SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
452 
453   // Do the connect
454   return ContinueSSL();
455 }
456 
ContinueSSL()457 int OpenSSLStreamAdapter::ContinueSSL() {
458   LOG(LS_INFO) << "ContinueSSL";
459   ASSERT(state_ == SSL_CONNECTING);
460 
461   int code = (role_ == SSL_CLIENT) ? SSL_connect(ssl_) : SSL_accept(ssl_);
462   switch (SSL_get_error(ssl_, code)) {
463     case SSL_ERROR_NONE:
464       LOG(LS_INFO) << " -- success";
465 
466       if (!SSLPostConnectionCheck(ssl_, ssl_server_name_.c_str(),
467                                   peer_certificate_.get() != NULL
468                                   ? peer_certificate_->x509() : NULL)) {
469         LOG(LS_ERROR) << "TLS post connection check failed";
470         return -1;
471       }
472 
473       state_ = SSL_CONNECTED;
474       StreamAdapterInterface::OnEvent(stream(), SE_OPEN|SE_READ|SE_WRITE, 0);
475       break;
476 
477     case SSL_ERROR_WANT_READ:
478       LOG(LS_INFO) << " -- error want read";
479       break;
480 
481     case SSL_ERROR_WANT_WRITE:
482       LOG(LS_INFO) << " -- error want write";
483       break;
484 
485     case SSL_ERROR_ZERO_RETURN:
486     default:
487       LOG(LS_INFO) << " -- error " << code;
488       return (code != 0) ? code : -1;
489   }
490 
491   return 0;
492 }
493 
Error(const char * context,int err,bool signal)494 void OpenSSLStreamAdapter::Error(const char* context, int err, bool signal) {
495   LOG(LS_WARNING) << "OpenSSLStreamAdapter::Error("
496                   << context << ", " << err << ")";
497   state_ = SSL_ERROR;
498   ssl_error_code_ = err;
499   Cleanup();
500   if (signal)
501     StreamAdapterInterface::OnEvent(stream(), SE_CLOSE, err);
502 }
503 
Cleanup()504 void OpenSSLStreamAdapter::Cleanup() {
505   LOG(LS_INFO) << "Cleanup";
506 
507   if (state_ != SSL_ERROR) {
508     state_ = SSL_CLOSED;
509     ssl_error_code_ = 0;
510   }
511 
512   if (ssl_) {
513     SSL_free(ssl_);
514     ssl_ = NULL;
515   }
516   if (ssl_ctx_) {
517     SSL_CTX_free(ssl_ctx_);
518     ssl_ctx_ = NULL;
519   }
520   identity_.reset();
521   peer_certificate_.reset();
522 }
523 
SetupSSLContext()524 SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() {
525   SSL_CTX* ctx = SSL_CTX_new(role_ == SSL_CLIENT ? TLSv1_client_method()
526                              : TLSv1_server_method());
527   if (ctx == NULL)
528     return NULL;
529 
530   if (identity_.get() && !identity_->ConfigureIdentity(ctx)) {
531     SSL_CTX_free(ctx);
532     return NULL;
533   }
534 
535   if (peer_certificate_.get() == NULL) {  // traditional mode
536     // Add the root cert to the SSL context
537     if(!OpenSSLAdapter::ConfigureTrustedRootCertificates(ctx)) {
538       SSL_CTX_free(ctx);
539       return NULL;
540     }
541   }
542 
543   if (peer_certificate_.get() != NULL && role_ == SSL_SERVER)
544     // we must specify which client cert to ask for
545     SSL_CTX_add_client_CA(ctx, peer_certificate_->x509());
546 
547 #ifdef _DEBUG
548   SSL_CTX_set_info_callback(ctx, OpenSSLAdapter::SSLInfoCallback);
549 #endif
550 
551   SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
552                      SSLVerifyCallback);
553   SSL_CTX_set_verify_depth(ctx, 4);
554   SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
555 
556   return ctx;
557 }
558 
SSLVerifyCallback(int ok,X509_STORE_CTX * store)559 int OpenSSLStreamAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) {
560 #if _DEBUG
561   if (!ok) {
562     char data[256];
563     X509* cert = X509_STORE_CTX_get_current_cert(store);
564     int depth = X509_STORE_CTX_get_error_depth(store);
565     int err = X509_STORE_CTX_get_error(store);
566 
567     LOG(LS_INFO) << "Error with certificate at depth: " << depth;
568     X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data));
569     LOG(LS_INFO) << "  issuer  = " << data;
570     X509_NAME_oneline(X509_get_subject_name(cert), data, sizeof(data));
571     LOG(LS_INFO) << "  subject = " << data;
572     LOG(LS_INFO) << "  err     = " << err
573       << ":" << X509_verify_cert_error_string(err);
574   }
575 #endif
576 
577   // Get our SSL structure from the store
578   SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(
579                                         store,
580                                         SSL_get_ex_data_X509_STORE_CTX_idx()));
581 
582   OpenSSLStreamAdapter* stream =
583     reinterpret_cast<OpenSSLStreamAdapter*>(SSL_get_app_data(ssl));
584 
585   // In peer-to-peer mode, no root cert / certificate authority was
586   // specified, so the libraries knows of no certificate to accept,
587   // and therefore it will necessarily call here on the first cert it
588   // tries to verify.
589   if (!ok && stream->peer_certificate_.get() != NULL) {
590     X509* cert = X509_STORE_CTX_get_current_cert(store);
591     int err = X509_STORE_CTX_get_error(store);
592     // peer-to-peer mode: allow the certificate to be self-signed,
593     // assuming it matches the cert that was specified.
594     if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT &&
595         X509_cmp(cert, stream->peer_certificate_->x509()) == 0) {
596       LOG(LS_INFO) << "Accepted self-signed peer certificate authority";
597       ok = 1;
598     }
599   } else if (!ok && OpenSSLAdapter::custom_verify_callback_) {
600     // this applies only in traditional mode
601     void* cert =
602         reinterpret_cast<void*>(X509_STORE_CTX_get_current_cert(store));
603     if (OpenSSLAdapter::custom_verify_callback_(cert)) {
604       stream->custom_verification_succeeded_ = true;
605       LOG(LS_INFO) << "validated certificate using custom callback";
606       ok = 1;
607     }
608   }
609 
610   if (!ok && stream->ignore_bad_cert()) {
611     LOG(LS_WARNING) << "Ignoring cert error while verifying cert chain";
612     ok = 1;
613   }
614 
615   return ok;
616 }
617 
618 // This code is taken from the "Network Security with OpenSSL"
619 // sample in chapter 5
SSLPostConnectionCheck(SSL * ssl,const char * server_name,const X509 * peer_cert)620 bool OpenSSLStreamAdapter::SSLPostConnectionCheck(SSL* ssl,
621                                                   const char* server_name,
622                                                   const X509* peer_cert) {
623   ASSERT(server_name != NULL);
624   bool ok;
625   if(server_name[0] != '\0') {  // traditional mode
626     ok = OpenSSLAdapter::VerifyServerName(ssl, server_name, ignore_bad_cert());
627 
628     if (ok) {
629       ok = (SSL_get_verify_result(ssl) == X509_V_OK ||
630             custom_verification_succeeded_);
631     }
632   } else {  // peer-to-peer mode
633     ASSERT(peer_cert != NULL);
634     // no server name validation
635     ok = true;
636   }
637 
638   if (!ok && ignore_bad_cert()) {
639     LOG(LS_ERROR) << "SSL_get_verify_result(ssl) = "
640                   << SSL_get_verify_result(ssl);
641     LOG(LS_INFO) << "Other TLS post connection checks failed.";
642     ok = true;
643   }
644 
645   return ok;
646 }
647 
648 }  // namespace talk_base
649 
650 #endif  // HAVE_OPENSSL_SSL_H
651