Note: We no longer publish the latest version of our code here. We primarily use a kumc-bmi github organization. The heron ETL repository, in particular, is not public. Peers in the informatics community should see MultiSiteDev for details on requesting access.

source: webrtc/talk/base/opensslstreamadapter.cc @ 0:4bda6873e34c

pub_scrub_3792 tip
Last change on this file since 0:4bda6873e34c was 0:4bda6873e34c, checked in by Michael Prittie <mprittie@…>, 6 years ago

Scrubbed password for publication.

File size: 25.9 KB
Line 
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 <vector>
44
45#include "talk/base/common.h"
46#include "talk/base/logging.h"
47#include "talk/base/stream.h"
48#include "talk/base/openssladapter.h"
49#include "talk/base/openssldigest.h"
50#include "talk/base/opensslidentity.h"
51#include "talk/base/stringutils.h"
52#include "talk/base/thread.h"
53
54namespace talk_base {
55
56#if (OPENSSL_VERSION_NUMBER >= 0x10001000L)
57#define HAVE_DTLS_SRTP
58#endif
59
60#if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
61#define HAVE_DTLS
62#endif
63
64#ifdef HAVE_DTLS_SRTP
65// SRTP cipher suite table
66struct SrtpCipherMapEntry {
67  const char* external_name;
68  const char* internal_name;
69};
70
71// This isn't elegant, but it's better than an external reference
72static SrtpCipherMapEntry SrtpCipherMap[] = {
73  {"AES_CM_128_HMAC_SHA1_80", "SRTP_AES128_CM_SHA1_80"},
74  {"AES_CM_128_HMAC_SHA1_32", "SRTP_AES128_CM_SHA1_32"},
75  {NULL, NULL}
76};
77#endif
78
79//////////////////////////////////////////////////////////////////////
80// StreamBIO
81//////////////////////////////////////////////////////////////////////
82
83static int stream_write(BIO* h, const char* buf, int num);
84static int stream_read(BIO* h, char* buf, int size);
85static int stream_puts(BIO* h, const char* str);
86static long stream_ctrl(BIO* h, int cmd, long arg1, void* arg2);
87static int stream_new(BIO* h);
88static int stream_free(BIO* data);
89
90static BIO_METHOD methods_stream = {
91  BIO_TYPE_BIO,
92  "stream",
93  stream_write,
94  stream_read,
95  stream_puts,
96  0,
97  stream_ctrl,
98  stream_new,
99  stream_free,
100  NULL,
101};
102
103static BIO_METHOD* BIO_s_stream() { return(&methods_stream); }
104
105static BIO* BIO_new_stream(StreamInterface* stream) {
106  BIO* ret = BIO_new(BIO_s_stream());
107  if (ret == NULL)
108    return NULL;
109  ret->ptr = stream;
110  return ret;
111}
112
113// bio methods return 1 (or at least non-zero) on success and 0 on failure.
114
115static int stream_new(BIO* b) {
116  b->shutdown = 0;
117  b->init = 1;
118  b->num = 0;  // 1 means end-of-stream
119  b->ptr = 0;
120  return 1;
121}
122
123static int stream_free(BIO* b) {
124  if (b == NULL)
125    return 0;
126  return 1;
127}
128
129static int stream_read(BIO* b, char* out, int outl) {
130  if (!out)
131    return -1;
132  StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);
133  BIO_clear_retry_flags(b);
134  size_t read;
135  int error;
136  StreamResult result = stream->Read(out, outl, &read, &error);
137  if (result == SR_SUCCESS) {
138    return read;
139  } else if (result == SR_EOS) {
140    b->num = 1;
141  } else if (result == SR_BLOCK) {
142    BIO_set_retry_read(b);
143  }
144  return -1;
145}
146
147static int stream_write(BIO* b, const char* in, int inl) {
148  if (!in)
149    return -1;
150  StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);
151  BIO_clear_retry_flags(b);
152  size_t written;
153  int error;
154  StreamResult result = stream->Write(in, inl, &written, &error);
155  if (result == SR_SUCCESS) {
156    return written;
157  } else if (result == SR_BLOCK) {
158    BIO_set_retry_write(b);
159  }
160  return -1;
161}
162
163static int stream_puts(BIO* b, const char* str) {
164  return stream_write(b, str, strlen(str));
165}
166
167static long stream_ctrl(BIO* b, int cmd, long num, void* ptr) {
168  UNUSED(num);
169  UNUSED(ptr);
170
171  switch (cmd) {
172    case BIO_CTRL_RESET:
173      return 0;
174    case BIO_CTRL_EOF:
175      return b->num;
176    case BIO_CTRL_WPENDING:
177    case BIO_CTRL_PENDING:
178      return 0;
179    case BIO_CTRL_FLUSH:
180      return 1;
181    default:
182      return 0;
183  }
184}
185
186/////////////////////////////////////////////////////////////////////////////
187// OpenSSLStreamAdapter
188/////////////////////////////////////////////////////////////////////////////
189
190OpenSSLStreamAdapter::OpenSSLStreamAdapter(StreamInterface* stream)
191    : SSLStreamAdapter(stream),
192      state_(SSL_NONE),
193      role_(SSL_CLIENT),
194      ssl_read_needs_write_(false), ssl_write_needs_read_(false),
195      ssl_(NULL), ssl_ctx_(NULL),
196      custom_verification_succeeded_(false),
197      ssl_mode_(SSL_MODE_TLS) {
198}
199
200OpenSSLStreamAdapter::~OpenSSLStreamAdapter() {
201  Cleanup();
202}
203
204void OpenSSLStreamAdapter::SetIdentity(SSLIdentity* identity) {
205  ASSERT(!identity_);
206  identity_.reset(static_cast<OpenSSLIdentity*>(identity));
207}
208
209void OpenSSLStreamAdapter::SetServerRole(SSLRole role) {
210  role_ = role;
211}
212
213void OpenSSLStreamAdapter::SetPeerCertificate(SSLCertificate* cert) {
214  ASSERT(!peer_certificate_);
215  ASSERT(peer_certificate_digest_algorithm_.empty());
216  ASSERT(ssl_server_name_.empty());
217  peer_certificate_.reset(static_cast<OpenSSLCertificate*>(cert));
218}
219
220bool OpenSSLStreamAdapter::GetPeerCertificate(SSLCertificate** cert) const {
221  if (!peer_certificate_)
222    return false;
223
224  *cert = peer_certificate_->GetReference();
225  return true;
226}
227
228bool OpenSSLStreamAdapter::SetPeerCertificateDigest(const std::string
229                                                    &digest_alg,
230                                                    const unsigned char*
231                                                    digest_val,
232                                                    size_t digest_len) {
233  ASSERT(!peer_certificate_);
234  ASSERT(peer_certificate_digest_algorithm_.size() == 0);
235  ASSERT(ssl_server_name_.empty());
236  size_t expected_len;
237
238  if (!OpenSSLDigest::GetDigestSize(digest_alg, &expected_len)) {
239    LOG(LS_WARNING) << "Unknown digest algorithm: " << digest_alg;
240    return false;
241  }
242  if (expected_len != digest_len)
243    return false;
244
245  peer_certificate_digest_value_.SetData(digest_val, digest_len);
246  peer_certificate_digest_algorithm_ = digest_alg;
247
248  return true;
249}
250
251// Key Extractor interface
252bool OpenSSLStreamAdapter::ExportKeyingMaterial(const std::string& label,
253                                                const uint8* context,
254                                                size_t context_len,
255                                                bool use_context,
256                                                uint8* result,
257                                                size_t result_len) {
258#ifdef HAVE_DTLS_SRTP
259  int i;
260
261  i = SSL_export_keying_material(ssl_, result, result_len,
262                                 label.c_str(), label.length(),
263                                 const_cast<uint8 *>(context),
264                                 context_len, use_context);
265
266  if (i != 1)
267    return false;
268
269  return true;
270#else
271  return false;
272#endif
273}
274
275bool OpenSSLStreamAdapter::SetDtlsSrtpCiphers(
276    const std::vector<std::string>& ciphers) {
277  std::string internal_ciphers;
278
279  if (state_ != SSL_NONE)
280    return false;
281
282#ifdef HAVE_DTLS_SRTP
283  for (std::vector<std::string>::const_iterator cipher = ciphers.begin();
284       cipher != ciphers.end(); ++cipher) {
285    bool found = false;
286    for (SrtpCipherMapEntry *entry = SrtpCipherMap; entry->internal_name;
287         ++entry) {
288      if (*cipher == entry->external_name) {
289        found = true;
290        if (!internal_ciphers.empty())
291          internal_ciphers += ":";
292        internal_ciphers += entry->internal_name;
293        break;
294      }
295    }
296
297    if (!found) {
298      LOG(LS_ERROR) << "Could not find cipher: " << *cipher;
299      return false;
300    }
301  }
302
303  if (internal_ciphers.empty())
304    return false;
305
306  srtp_ciphers_ = internal_ciphers;
307  return true;
308#else
309  return false;
310#endif
311}
312
313bool OpenSSLStreamAdapter::GetDtlsSrtpCipher(std::string* cipher) {
314#ifdef HAVE_DTLS_SRTP
315  ASSERT(state_ == SSL_CONNECTED);
316  if (state_ != SSL_CONNECTED)
317    return false;
318
319  SRTP_PROTECTION_PROFILE *srtp_profile =
320      SSL_get_selected_srtp_profile(ssl_);
321
322  if (!srtp_profile)
323    return false;
324
325  for (SrtpCipherMapEntry *entry = SrtpCipherMap;
326       entry->internal_name; ++entry) {
327    if (!strcmp(entry->internal_name, srtp_profile->name)) {
328      *cipher = entry->external_name;
329      return true;
330    }
331  }
332
333  ASSERT(false);  // This should never happen
334
335  return false;
336#else
337  return false;
338#endif
339}
340
341int OpenSSLStreamAdapter::StartSSLWithServer(const char* server_name) {
342  ASSERT(server_name != NULL && server_name[0] != '\0');
343  ssl_server_name_ = server_name;
344  return StartSSL();
345}
346
347int OpenSSLStreamAdapter::StartSSLWithPeer() {
348  ASSERT(ssl_server_name_.empty());
349  // It is permitted to specify peer_certificate_ only later.
350  return StartSSL();
351}
352
353void OpenSSLStreamAdapter::SetMode(SSLMode mode) {
354  ASSERT(state_ == SSL_NONE);
355  ssl_mode_ = mode;
356}
357
358//
359// StreamInterface Implementation
360//
361
362StreamResult OpenSSLStreamAdapter::Write(const void* data, size_t data_len,
363                                         size_t* written, int* error) {
364  LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Write(" << data_len << ")";
365
366  switch (state_) {
367  case SSL_NONE:
368    // pass-through in clear text
369    return StreamAdapterInterface::Write(data, data_len, written, error);
370
371  case SSL_WAIT:
372  case SSL_CONNECTING:
373    return SR_BLOCK;
374
375  case SSL_CONNECTED:
376    break;
377
378  case SSL_ERROR:
379  case SSL_CLOSED:
380  default:
381    if (error)
382      *error = ssl_error_code_;
383    return SR_ERROR;
384  }
385
386  // OpenSSL will return an error if we try to write zero bytes
387  if (data_len == 0) {
388    if (written)
389      *written = 0;
390    return SR_SUCCESS;
391  }
392
393  ssl_write_needs_read_ = false;
394
395  int code = SSL_write(ssl_, data, data_len);
396  int ssl_error = SSL_get_error(ssl_, code);
397  switch (ssl_error) {
398  case SSL_ERROR_NONE:
399    LOG(LS_VERBOSE) << " -- success";
400    ASSERT(0 < code && static_cast<unsigned>(code) <= data_len);
401    if (written)
402      *written = code;
403    return SR_SUCCESS;
404  case SSL_ERROR_WANT_READ:
405    LOG(LS_VERBOSE) << " -- error want read";
406    ssl_write_needs_read_ = true;
407    return SR_BLOCK;
408  case SSL_ERROR_WANT_WRITE:
409    LOG(LS_VERBOSE) << " -- error want write";
410    return SR_BLOCK;
411
412  case SSL_ERROR_ZERO_RETURN:
413  default:
414    Error("SSL_write", (ssl_error ? ssl_error : -1), false);
415    if (error)
416      *error = ssl_error_code_;
417    return SR_ERROR;
418  }
419  // not reached
420}
421
422StreamResult OpenSSLStreamAdapter::Read(void* data, size_t data_len,
423                                        size_t* read, int* error) {
424  LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Read(" << data_len << ")";
425  switch (state_) {
426    case SSL_NONE:
427      // pass-through in clear text
428      return StreamAdapterInterface::Read(data, data_len, read, error);
429
430    case SSL_WAIT:
431    case SSL_CONNECTING:
432      return SR_BLOCK;
433
434    case SSL_CONNECTED:
435      break;
436
437    case SSL_CLOSED:
438      return SR_EOS;
439
440    case SSL_ERROR:
441    default:
442      if (error)
443        *error = ssl_error_code_;
444      return SR_ERROR;
445  }
446
447  // Don't trust OpenSSL with zero byte reads
448  if (data_len == 0) {
449    if (read)
450      *read = 0;
451    return SR_SUCCESS;
452  }
453
454  ssl_read_needs_write_ = false;
455
456  int code = SSL_read(ssl_, data, data_len);
457  int ssl_error = SSL_get_error(ssl_, code);
458  switch (ssl_error) {
459    case SSL_ERROR_NONE:
460      LOG(LS_VERBOSE) << " -- success";
461      ASSERT(0 < code && static_cast<unsigned>(code) <= data_len);
462      if (read)
463        *read = code;
464
465      if (ssl_mode_ == SSL_MODE_DTLS) {
466        // Enforce atomic reads -- this is a short read
467        unsigned int pending = SSL_pending(ssl_);
468
469        if (pending) {
470          LOG(LS_INFO) << " -- short DTLS read. flushing";
471          FlushInput(pending);
472          if (error)
473            *error = SSE_MSG_TRUNC;
474          return SR_ERROR;
475        }
476      }
477      return SR_SUCCESS;
478    case SSL_ERROR_WANT_READ:
479      LOG(LS_VERBOSE) << " -- error want read";
480      return SR_BLOCK;
481    case SSL_ERROR_WANT_WRITE:
482      LOG(LS_VERBOSE) << " -- error want write";
483      ssl_read_needs_write_ = true;
484      return SR_BLOCK;
485    case SSL_ERROR_ZERO_RETURN:
486      LOG(LS_VERBOSE) << " -- remote side closed";
487      return SR_EOS;
488      break;
489    default:
490      LOG(LS_VERBOSE) << " -- error " << code;
491      Error("SSL_read", (ssl_error ? ssl_error : -1), false);
492      if (error)
493        *error = ssl_error_code_;
494      return SR_ERROR;
495  }
496  // not reached
497}
498
499void OpenSSLStreamAdapter::FlushInput(unsigned int left) {
500  unsigned char buf[2048];
501
502  while (left) {
503    // This should always succeed
504    int toread = (sizeof(buf) < left) ? sizeof(buf) : left;
505    int code = SSL_read(ssl_, buf, toread);
506
507    int ssl_error = SSL_get_error(ssl_, code);
508    ASSERT(ssl_error == SSL_ERROR_NONE);
509
510    if (ssl_error != SSL_ERROR_NONE) {
511      LOG(LS_VERBOSE) << " -- error " << code;
512      Error("SSL_read", (ssl_error ? ssl_error : -1), false);
513      return;
514    }
515
516    LOG(LS_VERBOSE) << " -- flushed " << code << " bytes";
517    left -= code;
518  }
519}
520
521void OpenSSLStreamAdapter::Close() {
522  Cleanup();
523  ASSERT(state_ == SSL_CLOSED || state_ == SSL_ERROR);
524  StreamAdapterInterface::Close();
525}
526
527StreamState OpenSSLStreamAdapter::GetState() const {
528  switch (state_) {
529    case SSL_WAIT:
530    case SSL_CONNECTING:
531      return SS_OPENING;
532    case SSL_CONNECTED:
533      return SS_OPEN;
534    default:
535      return SS_CLOSED;
536  };
537  // not reached
538}
539
540void OpenSSLStreamAdapter::OnEvent(StreamInterface* stream, int events,
541                                   int err) {
542  int events_to_signal = 0;
543  int signal_error = 0;
544  ASSERT(stream == this->stream());
545  if ((events & SE_OPEN)) {
546    LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent SE_OPEN";
547    if (state_ != SSL_WAIT) {
548      ASSERT(state_ == SSL_NONE);
549      events_to_signal |= SE_OPEN;
550    } else {
551      state_ = SSL_CONNECTING;
552      if (int err = BeginSSL()) {
553        Error("BeginSSL", err, true);
554        return;
555      }
556    }
557  }
558  if ((events & (SE_READ|SE_WRITE))) {
559    LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent"
560                 << ((events & SE_READ) ? " SE_READ" : "")
561                 << ((events & SE_WRITE) ? " SE_WRITE" : "");
562    if (state_ == SSL_NONE) {
563      events_to_signal |= events & (SE_READ|SE_WRITE);
564    } else if (state_ == SSL_CONNECTING) {
565      if (int err = ContinueSSL()) {
566        Error("ContinueSSL", err, true);
567        return;
568      }
569    } else if (state_ == SSL_CONNECTED) {
570      if (((events & SE_READ) && ssl_write_needs_read_) ||
571          (events & SE_WRITE)) {
572        LOG(LS_VERBOSE) << " -- onStreamWriteable";
573        events_to_signal |= SE_WRITE;
574      }
575      if (((events & SE_WRITE) && ssl_read_needs_write_) ||
576          (events & SE_READ)) {
577        LOG(LS_VERBOSE) << " -- onStreamReadable";
578        events_to_signal |= SE_READ;
579      }
580    }
581  }
582  if ((events & SE_CLOSE)) {
583    LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent(SE_CLOSE, " << err << ")";
584    Cleanup();
585    events_to_signal |= SE_CLOSE;
586    // SE_CLOSE is the only event that uses the final parameter to OnEvent().
587    ASSERT(signal_error == 0);
588    signal_error = err;
589  }
590  if (events_to_signal)
591    StreamAdapterInterface::OnEvent(stream, events_to_signal, signal_error);
592}
593
594int OpenSSLStreamAdapter::StartSSL() {
595  ASSERT(state_ == SSL_NONE);
596
597  if (StreamAdapterInterface::GetState() != SS_OPEN) {
598    state_ = SSL_WAIT;
599    return 0;
600  }
601
602  state_ = SSL_CONNECTING;
603  if (int err = BeginSSL()) {
604    Error("BeginSSL", err, false);
605    return err;
606  }
607
608  return 0;
609}
610
611int OpenSSLStreamAdapter::BeginSSL() {
612  ASSERT(state_ == SSL_CONNECTING);
613  // The underlying stream has open. If we are in peer-to-peer mode
614  // then a peer certificate must have been specified by now.
615  ASSERT(!ssl_server_name_.empty() ||
616         peer_certificate_ ||
617         !peer_certificate_digest_algorithm_.empty());
618  LOG(LS_INFO) << "BeginSSL: "
619               << (!ssl_server_name_.empty() ? ssl_server_name_ :
620                                               "with peer");
621
622  BIO* bio = NULL;
623
624  // First set up the context
625  ASSERT(ssl_ctx_ == NULL);
626  ssl_ctx_ = SetupSSLContext();
627  if (!ssl_ctx_)
628    return -1;
629
630  bio = BIO_new_stream(static_cast<StreamInterface*>(stream()));
631  if (!bio)
632    return -1;
633
634  ssl_ = SSL_new(ssl_ctx_);
635  if (!ssl_) {
636    BIO_free(bio);
637    return -1;
638  }
639
640  SSL_set_app_data(ssl_, this);
641
642  SSL_set_bio(ssl_, bio, bio);  // the SSL object owns the bio now.
643
644  SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |
645               SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
646
647  // Do the connect
648  return ContinueSSL();
649}
650
651int OpenSSLStreamAdapter::ContinueSSL() {
652  LOG(LS_VERBOSE) << "ContinueSSL";
653  ASSERT(state_ == SSL_CONNECTING);
654
655  // Clear the DTLS timer
656  Thread::Current()->Clear(this, MSG_TIMEOUT);
657
658  int code = (role_ == SSL_CLIENT) ? SSL_connect(ssl_) : SSL_accept(ssl_);
659  int ssl_error;
660  switch (ssl_error = SSL_get_error(ssl_, code)) {
661    case SSL_ERROR_NONE:
662      LOG(LS_VERBOSE) << " -- success";
663
664      if (!SSLPostConnectionCheck(ssl_, ssl_server_name_.c_str(),
665                                  peer_certificate_ ?
666                                      peer_certificate_->x509() : NULL,
667                                  peer_certificate_digest_algorithm_)) {
668        LOG(LS_ERROR) << "TLS post connection check failed";
669        return -1;
670      }
671
672      state_ = SSL_CONNECTED;
673      StreamAdapterInterface::OnEvent(stream(), SE_OPEN|SE_READ|SE_WRITE, 0);
674      break;
675
676    case SSL_ERROR_WANT_READ: {
677        LOG(LS_VERBOSE) << " -- error want read";
678#ifdef HAVE_DTLS
679        struct timeval timeout;
680        if (DTLSv1_get_timeout(ssl_, &timeout)) {
681          int delay = timeout.tv_sec * 1000 + timeout.tv_usec/1000;
682
683          Thread::Current()->PostDelayed(delay, this, MSG_TIMEOUT, 0);
684        }
685#endif
686      }
687      break;
688
689    case SSL_ERROR_WANT_WRITE:
690      LOG(LS_VERBOSE) << " -- error want write";
691      break;
692
693    case SSL_ERROR_ZERO_RETURN:
694    default:
695      LOG(LS_VERBOSE) << " -- error " << code;
696      return (ssl_error != 0) ? ssl_error : -1;
697  }
698
699  return 0;
700}
701
702void OpenSSLStreamAdapter::Error(const char* context, int err, bool signal) {
703  LOG(LS_WARNING) << "OpenSSLStreamAdapter::Error("
704                  << context << ", " << err << ")";
705  state_ = SSL_ERROR;
706  ssl_error_code_ = err;
707  Cleanup();
708  if (signal)
709    StreamAdapterInterface::OnEvent(stream(), SE_CLOSE, err);
710}
711
712void OpenSSLStreamAdapter::Cleanup() {
713  LOG(LS_INFO) << "Cleanup";
714
715  if (state_ != SSL_ERROR) {
716    state_ = SSL_CLOSED;
717    ssl_error_code_ = 0;
718  }
719
720  if (ssl_) {
721    SSL_free(ssl_);
722    ssl_ = NULL;
723  }
724  if (ssl_ctx_) {
725    SSL_CTX_free(ssl_ctx_);
726    ssl_ctx_ = NULL;
727  }
728  identity_.reset();
729  peer_certificate_.reset();
730
731  // Clear the DTLS timer
732  Thread::Current()->Clear(this, MSG_TIMEOUT);
733}
734
735
736void OpenSSLStreamAdapter::OnMessage(Message* msg) {
737  // Process our own messages and then pass others to the superclass
738  if (MSG_TIMEOUT == msg->message_id) {
739    LOG(LS_INFO) << "DTLS timeout expired";
740#ifdef HAVE_DTLS
741    DTLSv1_handle_timeout(ssl_);
742#endif
743    ContinueSSL();
744  } else {
745    StreamInterface::OnMessage(msg);
746  }
747}
748
749SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() {
750  SSL_CTX *ctx = NULL;
751
752  if (role_ == SSL_CLIENT) {
753#ifdef HAVE_DTLS
754    ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
755        DTLSv1_client_method() : TLSv1_client_method());
756#else
757    ctx = SSL_CTX_new(TLSv1_client_method());
758#endif
759  } else {
760#ifdef HAVE_DTLS
761    ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
762        DTLSv1_server_method() : TLSv1_server_method());
763#else
764    ctx = SSL_CTX_new(TLSv1_server_method());
765#endif
766  }
767  if (ctx == NULL)
768    return NULL;
769
770  if (identity_ && !identity_->ConfigureIdentity(ctx)) {
771    SSL_CTX_free(ctx);
772    return NULL;
773  }
774
775  if (!peer_certificate_) {  // traditional mode
776    // Add the root cert to the SSL context
777    if (!OpenSSLAdapter::ConfigureTrustedRootCertificates(ctx)) {
778      SSL_CTX_free(ctx);
779      return NULL;
780    }
781  }
782
783  if (peer_certificate_ && role_ == SSL_SERVER)
784    // we must specify which client cert to ask for
785    SSL_CTX_add_client_CA(ctx, peer_certificate_->x509());
786
787#ifdef _DEBUG
788  SSL_CTX_set_info_callback(ctx, OpenSSLAdapter::SSLInfoCallback);
789#endif
790
791  SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
792                     SSLVerifyCallback);
793  SSL_CTX_set_verify_depth(ctx, 4);
794  SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
795
796#ifdef HAVE_DTLS_SRTP
797  if (!srtp_ciphers_.empty()) {
798    if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_ciphers_.c_str())) {
799      SSL_CTX_free(ctx);
800      return NULL;
801    }
802  }
803#endif
804
805  return ctx;
806}
807
808int OpenSSLStreamAdapter::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 SSL structure from the store
827  SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(
828                                        store,
829                                        SSL_get_ex_data_X509_STORE_CTX_idx()));
830
831  OpenSSLStreamAdapter* stream =
832    reinterpret_cast<OpenSSLStreamAdapter*>(SSL_get_app_data(ssl));
833
834  // In peer-to-peer mode, no root cert / certificate authority was
835  // specified, so the libraries knows of no certificate to accept,
836  // and therefore it will necessarily call here on the first cert it
837  // tries to verify.
838  if (!ok && stream->peer_certificate_) {
839    X509* cert = X509_STORE_CTX_get_current_cert(store);
840    int err = X509_STORE_CTX_get_error(store);
841    // peer-to-peer mode: allow the certificate to be self-signed,
842    // assuming it matches the cert that was specified.
843    if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT &&
844        X509_cmp(cert, stream->peer_certificate_->x509()) == 0) {
845      LOG(LS_INFO) << "Accepted self-signed peer certificate authority";
846      ok = 1;
847    }
848  } else if (!ok && !stream->peer_certificate_digest_algorithm_.empty()) {
849    X509* cert = X509_STORE_CTX_get_current_cert(store);
850    int err = X509_STORE_CTX_get_error(store);
851
852    // peer-to-peer mode: allow the certificate to be self-signed,
853    // assuming it matches the digest that was specified.
854    if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) {
855      unsigned char digest[EVP_MAX_MD_SIZE];
856      std::size_t digest_length;
857
858      if (OpenSSLCertificate::
859         ComputeDigest(cert,
860                       stream->peer_certificate_digest_algorithm_,
861                       digest, sizeof(digest),
862                       &digest_length)) {
863        Buffer computed_digest(digest, digest_length);
864        if (computed_digest == stream->peer_certificate_digest_value_) {
865          LOG(LS_INFO) <<
866              "Accepted self-signed peer certificate authority";
867          ok = 1;
868
869          // Record the peer's certificate.
870          stream->peer_certificate_.reset(new OpenSSLCertificate(cert));
871        }
872      }
873    }
874  } else if (!ok && OpenSSLAdapter::custom_verify_callback_) {
875    // this applies only in traditional mode
876    void* cert =
877        reinterpret_cast<void*>(X509_STORE_CTX_get_current_cert(store));
878    if (OpenSSLAdapter::custom_verify_callback_(cert)) {
879      stream->custom_verification_succeeded_ = true;
880      LOG(LS_INFO) << "validated certificate using custom callback";
881      ok = 1;
882    }
883  }
884
885  if (!ok && stream->ignore_bad_cert()) {
886    LOG(LS_WARNING) << "Ignoring cert error while verifying cert chain";
887    ok = 1;
888  }
889
890  return ok;
891}
892
893// This code is taken from the "Network Security with OpenSSL"
894// sample in chapter 5
895bool OpenSSLStreamAdapter::SSLPostConnectionCheck(SSL* ssl,
896                                                  const char* server_name,
897                                                  const X509* peer_cert,
898                                                  const std::string
899                                                  &peer_digest) {
900  ASSERT(server_name != NULL);
901  bool ok;
902  if (server_name[0] != '\0') {  // traditional mode
903    ok = OpenSSLAdapter::VerifyServerName(ssl, server_name, ignore_bad_cert());
904
905    if (ok) {
906      ok = (SSL_get_verify_result(ssl) == X509_V_OK ||
907            custom_verification_succeeded_);
908    }
909  } else {  // peer-to-peer mode
910    ASSERT((peer_cert != NULL) || (!peer_digest.empty()));
911    // no server name validation
912    ok = true;
913  }
914
915  if (!ok && ignore_bad_cert()) {
916    LOG(LS_ERROR) << "SSL_get_verify_result(ssl) = "
917                  << SSL_get_verify_result(ssl);
918    LOG(LS_INFO) << "Other TLS post connection checks failed.";
919    ok = true;
920  }
921
922  return ok;
923}
924
925bool OpenSSLStreamAdapter::HaveDtls() {
926#ifdef HAVE_DTLS
927  return true;
928#else
929  return false;
930#endif
931}
932
933bool OpenSSLStreamAdapter::HaveDtlsSrtp() {
934#ifdef HAVE_DTLS_SRTP
935  return true;
936#else
937  return false;
938#endif
939}
940
941bool OpenSSLStreamAdapter::HaveExporter() {
942#ifdef HAVE_DTLS_SRTP
943  return true;
944#else
945  return false;
946#endif
947}
948
949}  // namespace talk_base
950
951#endif  // HAVE_OPENSSL_SSL_H
Note: See TracBrowser for help on using the repository browser.