blob: c3be4ea6845456b46fdbc1ea111affd49f2a2eef [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
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
24namespace rtc {
25
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +000026SSLStreamAdapterHelper::SSLStreamAdapterHelper(StreamInterface* stream)
27 : SSLStreamAdapter(stream),
28 state_(SSL_NONE),
29 role_(SSL_CLIENT),
30 ssl_error_code_(0), // Not meaningful yet
Joachim Bauch831c5582015-05-20 12:48:41 +020031 ssl_mode_(SSL_MODE_TLS),
32 ssl_max_version_(SSL_PROTOCOL_TLS_11) {
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +000033}
34
35SSLStreamAdapterHelper::~SSLStreamAdapterHelper() = default;
36
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000037void SSLStreamAdapterHelper::SetIdentity(SSLIdentity* identity) {
38 ASSERT(identity_.get() == NULL);
39 identity_.reset(identity);
40}
41
42void SSLStreamAdapterHelper::SetServerRole(SSLRole role) {
43 role_ = role;
44}
45
46int SSLStreamAdapterHelper::StartSSLWithServer(const char* server_name) {
47 ASSERT(server_name != NULL && server_name[0] != '\0');
48 ssl_server_name_ = server_name;
49 return StartSSL();
50}
51
52int SSLStreamAdapterHelper::StartSSLWithPeer() {
53 ASSERT(ssl_server_name_.empty());
54 // It is permitted to specify peer_certificate_ only later.
55 return StartSSL();
56}
57
58void SSLStreamAdapterHelper::SetMode(SSLMode mode) {
59 ASSERT(state_ == SSL_NONE);
60 ssl_mode_ = mode;
61}
62
Joachim Bauch831c5582015-05-20 12:48:41 +020063void SSLStreamAdapterHelper::SetMaxProtocolVersion(SSLProtocolVersion version) {
64 ssl_max_version_ = version;
65}
66
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000067StreamState SSLStreamAdapterHelper::GetState() const {
68 switch (state_) {
69 case SSL_WAIT:
70 case SSL_CONNECTING:
71 return SS_OPENING;
72 case SSL_CONNECTED:
73 return SS_OPEN;
74 default:
75 return SS_CLOSED;
76 };
77 // not reached
78}
79
80bool SSLStreamAdapterHelper::GetPeerCertificate(SSLCertificate** cert) const {
81 if (!peer_certificate_)
82 return false;
83
84 *cert = peer_certificate_->GetReference();
85 return true;
86}
87
88bool SSLStreamAdapterHelper::SetPeerCertificateDigest(
89 const std::string &digest_alg,
90 const unsigned char* digest_val,
91 size_t digest_len) {
92 ASSERT(peer_certificate_.get() == NULL);
93 ASSERT(peer_certificate_digest_algorithm_.empty());
94 ASSERT(ssl_server_name_.empty());
95 size_t expected_len;
96
97 if (!GetDigestLength(digest_alg, &expected_len)) {
98 LOG(LS_WARNING) << "Unknown digest algorithm: " << digest_alg;
99 return false;
100 }
101 if (expected_len != digest_len)
102 return false;
103
104 peer_certificate_digest_value_.SetData(digest_val, digest_len);
105 peer_certificate_digest_algorithm_ = digest_alg;
106
107 return true;
108}
109
110void SSLStreamAdapterHelper::Error(const char* context, int err, bool signal) {
111 LOG(LS_WARNING) << "SSLStreamAdapterHelper::Error("
112 << context << ", " << err << "," << signal << ")";
113 state_ = SSL_ERROR;
114 ssl_error_code_ = err;
115 Cleanup();
116 if (signal)
117 StreamAdapterInterface::OnEvent(stream(), SE_CLOSE, err);
118}
119
120void SSLStreamAdapterHelper::Close() {
121 Cleanup();
122 ASSERT(state_ == SSL_CLOSED || state_ == SSL_ERROR);
123 StreamAdapterInterface::Close();
124}
125
126int SSLStreamAdapterHelper::StartSSL() {
127 ASSERT(state_ == SSL_NONE);
128
129 if (StreamAdapterInterface::GetState() != SS_OPEN) {
130 state_ = SSL_WAIT;
131 return 0;
132 }
133
134 state_ = SSL_CONNECTING;
135 int err = BeginSSL();
136 if (err) {
137 Error("BeginSSL", err, false);
138 return err;
139 }
140
141 return 0;
142}
143
144} // namespace rtc
145