Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 
     12 #include <vector>
     13 
     14 #if HAVE_CONFIG_H
     15 #include "config.h"
     16 #endif  // HAVE_CONFIG_H
     17 
     18 #include "webrtc/base/sslstreamadapterhelper.h"
     19 
     20 #include "webrtc/base/common.h"
     21 #include "webrtc/base/logging.h"
     22 #include "webrtc/base/stream.h"
     23 
     24 namespace rtc {
     25 
     26 void SSLStreamAdapterHelper::SetIdentity(SSLIdentity* identity) {
     27   ASSERT(identity_.get() == NULL);
     28   identity_.reset(identity);
     29 }
     30 
     31 void SSLStreamAdapterHelper::SetServerRole(SSLRole role) {
     32   role_ = role;
     33 }
     34 
     35 int SSLStreamAdapterHelper::StartSSLWithServer(const char* server_name) {
     36   ASSERT(server_name != NULL && server_name[0] != '\0');
     37   ssl_server_name_ = server_name;
     38   return StartSSL();
     39 }
     40 
     41 int SSLStreamAdapterHelper::StartSSLWithPeer() {
     42   ASSERT(ssl_server_name_.empty());
     43   // It is permitted to specify peer_certificate_ only later.
     44   return StartSSL();
     45 }
     46 
     47 void SSLStreamAdapterHelper::SetMode(SSLMode mode) {
     48   ASSERT(state_ == SSL_NONE);
     49   ssl_mode_ = mode;
     50 }
     51 
     52 StreamState SSLStreamAdapterHelper::GetState() const {
     53   switch (state_) {
     54     case SSL_WAIT:
     55     case SSL_CONNECTING:
     56       return SS_OPENING;
     57     case SSL_CONNECTED:
     58       return SS_OPEN;
     59     default:
     60       return SS_CLOSED;
     61   };
     62   // not reached
     63 }
     64 
     65 bool SSLStreamAdapterHelper::GetPeerCertificate(SSLCertificate** cert) const {
     66   if (!peer_certificate_)
     67     return false;
     68 
     69   *cert = peer_certificate_->GetReference();
     70   return true;
     71 }
     72 
     73 bool SSLStreamAdapterHelper::SetPeerCertificateDigest(
     74     const std::string &digest_alg,
     75     const unsigned char* digest_val,
     76     size_t digest_len) {
     77   ASSERT(peer_certificate_.get() == NULL);
     78   ASSERT(peer_certificate_digest_algorithm_.empty());
     79   ASSERT(ssl_server_name_.empty());
     80   size_t expected_len;
     81 
     82   if (!GetDigestLength(digest_alg, &expected_len)) {
     83     LOG(LS_WARNING) << "Unknown digest algorithm: " << digest_alg;
     84     return false;
     85   }
     86   if (expected_len != digest_len)
     87     return false;
     88 
     89   peer_certificate_digest_value_.SetData(digest_val, digest_len);
     90   peer_certificate_digest_algorithm_ = digest_alg;
     91 
     92   return true;
     93 }
     94 
     95 void SSLStreamAdapterHelper::Error(const char* context, int err, bool signal) {
     96   LOG(LS_WARNING) << "SSLStreamAdapterHelper::Error("
     97                   << context << ", " << err << "," << signal << ")";
     98   state_ = SSL_ERROR;
     99   ssl_error_code_ = err;
    100   Cleanup();
    101   if (signal)
    102     StreamAdapterInterface::OnEvent(stream(), SE_CLOSE, err);
    103 }
    104 
    105 void SSLStreamAdapterHelper::Close() {
    106   Cleanup();
    107   ASSERT(state_ == SSL_CLOSED || state_ == SSL_ERROR);
    108   StreamAdapterInterface::Close();
    109 }
    110 
    111 int SSLStreamAdapterHelper::StartSSL() {
    112   ASSERT(state_ == SSL_NONE);
    113 
    114   if (StreamAdapterInterface::GetState() != SS_OPEN) {
    115     state_ = SSL_WAIT;
    116     return 0;
    117   }
    118 
    119   state_ = SSL_CONNECTING;
    120   int err = BeginSSL();
    121   if (err) {
    122     Error("BeginSSL", err, false);
    123     return err;
    124   }
    125 
    126   return 0;
    127 }
    128 
    129 }  // namespace rtc
    130 
    131