|  | /* | 
|  | *  Copyright 2004 The WebRTC Project Authors. All rights reserved. | 
|  | * | 
|  | *  Use of this source code is governed by a BSD-style license | 
|  | *  that can be found in the LICENSE file in the root of the source | 
|  | *  tree. An additional intellectual property rights grant can be found | 
|  | *  in the file PATENTS.  All contributing project authors may | 
|  | *  be found in the AUTHORS file in the root of the source tree. | 
|  | */ | 
|  |  | 
|  |  | 
|  | #include <vector> | 
|  |  | 
|  | #if HAVE_CONFIG_H | 
|  | #include "config.h" | 
|  | #endif  // HAVE_CONFIG_H | 
|  |  | 
|  | #include "webrtc/base/sslstreamadapterhelper.h" | 
|  |  | 
|  | #include "webrtc/base/common.h" | 
|  | #include "webrtc/base/logging.h" | 
|  | #include "webrtc/base/stream.h" | 
|  |  | 
|  | namespace rtc { | 
|  |  | 
|  | SSLStreamAdapterHelper::SSLStreamAdapterHelper(StreamInterface* stream) | 
|  | : SSLStreamAdapter(stream), | 
|  | state_(SSL_NONE), | 
|  | role_(SSL_CLIENT), | 
|  | ssl_error_code_(0),  // Not meaningful yet | 
|  | ssl_mode_(SSL_MODE_TLS), | 
|  | ssl_max_version_(SSL_PROTOCOL_TLS_12) {} | 
|  |  | 
|  | SSLStreamAdapterHelper::~SSLStreamAdapterHelper() = default; | 
|  |  | 
|  | void SSLStreamAdapterHelper::SetIdentity(SSLIdentity* identity) { | 
|  | ASSERT(identity_.get() == NULL); | 
|  | identity_.reset(identity); | 
|  | } | 
|  |  | 
|  | void SSLStreamAdapterHelper::SetServerRole(SSLRole role) { | 
|  | role_ = role; | 
|  | } | 
|  |  | 
|  | int SSLStreamAdapterHelper::StartSSLWithServer(const char* server_name) { | 
|  | ASSERT(server_name != NULL && server_name[0] != '\0'); | 
|  | ssl_server_name_ = server_name; | 
|  | return StartSSL(); | 
|  | } | 
|  |  | 
|  | int SSLStreamAdapterHelper::StartSSLWithPeer() { | 
|  | ASSERT(ssl_server_name_.empty()); | 
|  | // It is permitted to specify peer_certificate_ only later. | 
|  | return StartSSL(); | 
|  | } | 
|  |  | 
|  | void SSLStreamAdapterHelper::SetMode(SSLMode mode) { | 
|  | ASSERT(state_ == SSL_NONE); | 
|  | ssl_mode_ = mode; | 
|  | } | 
|  |  | 
|  | void SSLStreamAdapterHelper::SetMaxProtocolVersion(SSLProtocolVersion version) { | 
|  | ssl_max_version_ = version; | 
|  | } | 
|  |  | 
|  | StreamState SSLStreamAdapterHelper::GetState() const { | 
|  | switch (state_) { | 
|  | case SSL_WAIT: | 
|  | case SSL_CONNECTING: | 
|  | return SS_OPENING; | 
|  | case SSL_CONNECTED: | 
|  | return SS_OPEN; | 
|  | default: | 
|  | return SS_CLOSED; | 
|  | }; | 
|  | // not reached | 
|  | } | 
|  |  | 
|  | bool SSLStreamAdapterHelper::GetPeerCertificate(SSLCertificate** cert) const { | 
|  | if (!peer_certificate_) | 
|  | return false; | 
|  |  | 
|  | *cert = peer_certificate_->GetReference(); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | bool SSLStreamAdapterHelper::SetPeerCertificateDigest( | 
|  | const std::string &digest_alg, | 
|  | const unsigned char* digest_val, | 
|  | size_t digest_len) { | 
|  | ASSERT(peer_certificate_.get() == NULL); | 
|  | ASSERT(peer_certificate_digest_algorithm_.empty()); | 
|  | ASSERT(ssl_server_name_.empty()); | 
|  | size_t expected_len; | 
|  |  | 
|  | if (!GetDigestLength(digest_alg, &expected_len)) { | 
|  | LOG(LS_WARNING) << "Unknown digest algorithm: " << digest_alg; | 
|  | return false; | 
|  | } | 
|  | if (expected_len != digest_len) | 
|  | return false; | 
|  |  | 
|  | peer_certificate_digest_value_.SetData(digest_val, digest_len); | 
|  | peer_certificate_digest_algorithm_ = digest_alg; | 
|  |  | 
|  | return true; | 
|  | } | 
|  |  | 
|  | void SSLStreamAdapterHelper::Error(const char* context, int err, bool signal) { | 
|  | LOG(LS_WARNING) << "SSLStreamAdapterHelper::Error(" | 
|  | << context << ", " << err << "," << signal << ")"; | 
|  | state_ = SSL_ERROR; | 
|  | ssl_error_code_ = err; | 
|  | Cleanup(); | 
|  | if (signal) | 
|  | StreamAdapterInterface::OnEvent(stream(), SE_CLOSE, err); | 
|  | } | 
|  |  | 
|  | void SSLStreamAdapterHelper::Close() { | 
|  | Cleanup(); | 
|  | ASSERT(state_ == SSL_CLOSED || state_ == SSL_ERROR); | 
|  | StreamAdapterInterface::Close(); | 
|  | } | 
|  |  | 
|  | int SSLStreamAdapterHelper::StartSSL() { | 
|  | ASSERT(state_ == SSL_NONE); | 
|  |  | 
|  | if (StreamAdapterInterface::GetState() != SS_OPEN) { | 
|  | state_ = SSL_WAIT; | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | state_ = SSL_CONNECTING; | 
|  | int err = BeginSSL(); | 
|  | if (err) { | 
|  | Error("BeginSSL", err, false); | 
|  | return err; | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | }  // namespace rtc | 
|  |  |