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