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 void SSLStreamAdapterHelper::SetPeerCertificate(SSLCertificate* cert) { 84 ASSERT(peer_certificate_.get() == NULL); 85 ASSERT(peer_certificate_digest_algorithm_.empty()); 86 ASSERT(ssl_server_name_.empty()); 87 peer_certificate_.reset(cert); 88 } 89 90 bool SSLStreamAdapterHelper::SetPeerCertificateDigest( 91 const std::string &digest_alg, 92 const unsigned char* digest_val, 93 size_t digest_len) { 94 ASSERT(peer_certificate_.get() == NULL); 95 ASSERT(peer_certificate_digest_algorithm_.empty()); 96 ASSERT(ssl_server_name_.empty()); 97 size_t expected_len; 98 99 if (!GetDigestLength(digest_alg, &expected_len)) { 100 LOG(LS_WARNING) << "Unknown digest algorithm: " << digest_alg; 101 return false; 102 } 103 if (expected_len != digest_len) 104 return false; 105 106 peer_certificate_digest_value_.SetData(digest_val, digest_len); 107 peer_certificate_digest_algorithm_ = digest_alg; 108 109 return true; 110 } 111 112 void SSLStreamAdapterHelper::Error(const char* context, int err, bool signal) { 113 LOG(LS_WARNING) << "SSLStreamAdapterHelper::Error(" 114 << context << ", " << err << "," << signal << ")"; 115 state_ = SSL_ERROR; 116 ssl_error_code_ = err; 117 Cleanup(); 118 if (signal) 119 StreamAdapterInterface::OnEvent(stream(), SE_CLOSE, err); 120 } 121 122 void SSLStreamAdapterHelper::Close() { 123 Cleanup(); 124 ASSERT(state_ == SSL_CLOSED || state_ == SSL_ERROR); 125 StreamAdapterInterface::Close(); 126 } 127 128 int SSLStreamAdapterHelper::StartSSL() { 129 ASSERT(state_ == SSL_NONE); 130 131 if (StreamAdapterInterface::GetState() != SS_OPEN) { 132 state_ = SSL_WAIT; 133 return 0; 134 } 135 136 state_ = SSL_CONNECTING; 137 int err = BeginSSL(); 138 if (err) { 139 Error("BeginSSL", err, false); 140 return err; 141 } 142 143 return 0; 144 } 145 146 } // namespace talk_base 147 148