1 /* 2 * libjingle 3 * Copyright 2004--2008, Google Inc. 4 * Copyright 2012, RTFM, Inc. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 20 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 30 #include <vector> 31 32 #if HAVE_CONFIG_H 33 #include "config.h" 34 #endif // HAVE_CONFIG_H 35 36 #include "talk/base/sslstreamadapterhelper.h" 37 38 #include "talk/base/common.h" 39 #include "talk/base/logging.h" 40 #include "talk/base/stream.h" 41 42 namespace talk_base { 43 44 void SSLStreamAdapterHelper::SetIdentity(SSLIdentity* identity) { 45 ASSERT(identity_.get() == NULL); 46 identity_.reset(identity); 47 } 48 49 void SSLStreamAdapterHelper::SetServerRole(SSLRole role) { 50 role_ = role; 51 } 52 53 int SSLStreamAdapterHelper::StartSSLWithServer(const char* server_name) { 54 ASSERT(server_name != NULL && server_name[0] != '\0'); 55 ssl_server_name_ = server_name; 56 return StartSSL(); 57 } 58 59 int SSLStreamAdapterHelper::StartSSLWithPeer() { 60 ASSERT(ssl_server_name_.empty()); 61 // It is permitted to specify peer_certificate_ only later. 62 return StartSSL(); 63 } 64 65 void SSLStreamAdapterHelper::SetMode(SSLMode mode) { 66 ASSERT(state_ == SSL_NONE); 67 ssl_mode_ = mode; 68 } 69 70 StreamState SSLStreamAdapterHelper::GetState() const { 71 switch (state_) { 72 case SSL_WAIT: 73 case SSL_CONNECTING: 74 return SS_OPENING; 75 case SSL_CONNECTED: 76 return SS_OPEN; 77 default: 78 return SS_CLOSED; 79 }; 80 // not reached 81 } 82 83 bool SSLStreamAdapterHelper::GetPeerCertificate(SSLCertificate** cert) const { 84 if (!peer_certificate_) 85 return false; 86 87 *cert = peer_certificate_->GetReference(); 88 return true; 89 } 90 91 bool SSLStreamAdapterHelper::SetPeerCertificateDigest( 92 const std::string &digest_alg, 93 const unsigned char* digest_val, 94 size_t digest_len) { 95 ASSERT(peer_certificate_.get() == NULL); 96 ASSERT(peer_certificate_digest_algorithm_.empty()); 97 ASSERT(ssl_server_name_.empty()); 98 size_t expected_len; 99 100 if (!GetDigestLength(digest_alg, &expected_len)) { 101 LOG(LS_WARNING) << "Unknown digest algorithm: " << digest_alg; 102 return false; 103 } 104 if (expected_len != digest_len) 105 return false; 106 107 peer_certificate_digest_value_.SetData(digest_val, digest_len); 108 peer_certificate_digest_algorithm_ = digest_alg; 109 110 return true; 111 } 112 113 void SSLStreamAdapterHelper::Error(const char* context, int err, bool signal) { 114 LOG(LS_WARNING) << "SSLStreamAdapterHelper::Error(" 115 << context << ", " << err << "," << signal << ")"; 116 state_ = SSL_ERROR; 117 ssl_error_code_ = err; 118 Cleanup(); 119 if (signal) 120 StreamAdapterInterface::OnEvent(stream(), SE_CLOSE, err); 121 } 122 123 void SSLStreamAdapterHelper::Close() { 124 Cleanup(); 125 ASSERT(state_ == SSL_CLOSED || state_ == SSL_ERROR); 126 StreamAdapterInterface::Close(); 127 } 128 129 int SSLStreamAdapterHelper::StartSSL() { 130 ASSERT(state_ == SSL_NONE); 131 132 if (StreamAdapterInterface::GetState() != SS_OPEN) { 133 state_ = SSL_WAIT; 134 return 0; 135 } 136 137 state_ = SSL_CONNECTING; 138 int err = BeginSSL(); 139 if (err) { 140 Error("BeginSSL", err, false); 141 return err; 142 } 143 144 return 0; 145 } 146 147 } // namespace talk_base 148 149