Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: remoting/protocol/v1_host_channel_authenticator.cc

Issue 8604001: Move SSL layer initialization into ChannelAuthenticator implementations. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Simple->V1 Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/protocol/v1_host_channel_authenticator.h ('k') | remoting/remoting.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "remoting/protocol/v1_host_channel_authenticator.h"
6
7 #include "crypto/rsa_private_key.h"
8 #include "crypto/secure_util.h"
9 #include "net/base/io_buffer.h"
10 #include "net/base/net_errors.h"
11 #include "net/base/ssl_config_service.h"
12 #include "net/base/x509_certificate.h"
13 #include "net/socket/ssl_server_socket.h"
14 #include "remoting/protocol/auth_util.h"
15
16 namespace remoting {
17 namespace protocol {
18
19 V1HostChannelAuthenticator::V1HostChannelAuthenticator(
20 const std::string& local_cert,
21 crypto::RSAPrivateKey* local_private_key,
22 const std::string& shared_secret)
23 : local_cert_(local_cert),
24 local_private_key_(local_private_key),
25 shared_secret_(shared_secret),
26 socket_(NULL),
27 ALLOW_THIS_IN_INITIALIZER_LIST(connect_callback_(
28 this, &V1HostChannelAuthenticator::OnConnected)),
29 ALLOW_THIS_IN_INITIALIZER_LIST(auth_read_callback_(
30 this, &V1HostChannelAuthenticator::OnAuthBytesRead)) {
31 }
32
33 V1HostChannelAuthenticator::~V1HostChannelAuthenticator() {
34 }
35
36 void V1HostChannelAuthenticator::SecureAndAuthenticate(
37 net::StreamSocket* socket, const DoneCallback& done_callback) {
38 DCHECK(CalledOnValidThread());
39
40 scoped_ptr<net::StreamSocket> channel_socket(socket);
41 done_callback_ = done_callback;
42
43 scoped_refptr<net::X509Certificate> cert =
44 net::X509Certificate::CreateFromBytes(
45 local_cert_.data(), local_cert_.length());
46 if (!cert) {
47 LOG(ERROR) << "Failed to parse X509Certificate";
48 done_callback.Run(net::ERR_FAILED, NULL);
49 return;
50 }
51
52 net::SSLConfig ssl_config;
53 socket_.reset(net::CreateSSLServerSocket(
54 channel_socket.release(), cert, local_private_key_, ssl_config));
55
56 int result = socket_->Handshake(&connect_callback_);
57 if (result == net::ERR_IO_PENDING) {
58 return;
59 }
60 OnConnected(result);
61 }
62
63 void V1HostChannelAuthenticator::OnConnected(int result) {
64 if (result != net::OK) {
65 LOG(ERROR) << "Failed to establish SSL connection";
66 done_callback_.Run(static_cast<net::Error>(result), NULL);
67 }
68
69 // Read an authentication digest.
70 auth_read_buf_ = new net::GrowableIOBuffer();
71 auth_read_buf_->SetCapacity(kAuthDigestLength);
72 DoAuthRead();
73 }
74
75 void V1HostChannelAuthenticator::DoAuthRead(){
76 while (true) {
77 int result = socket_->Read(auth_read_buf_,
78 auth_read_buf_->RemainingCapacity(),
79 &auth_read_callback_);
80 if (result == net::ERR_IO_PENDING)
81 break;
82 if (!HandleAuthBytesRead(result))
83 break;
84 }
85 }
86
87 void V1HostChannelAuthenticator::OnAuthBytesRead(int result) {
88 DCHECK(CalledOnValidThread());
89
90 if (HandleAuthBytesRead(result))
91 DoAuthRead();
92 }
93
94 bool V1HostChannelAuthenticator::HandleAuthBytesRead(int read_result) {
95 if (read_result <= 0) {
96 done_callback_.Run(static_cast<net::Error>(read_result), NULL);
97 return false;
98 }
99
100 auth_read_buf_->set_offset(auth_read_buf_->offset() + read_result);
101 if (auth_read_buf_->RemainingCapacity() > 0)
102 return true;
103
104 if (!VerifyAuthBytes(std::string(
105 auth_read_buf_->StartOfBuffer(),
106 auth_read_buf_->StartOfBuffer() + kAuthDigestLength))) {
107 LOG(WARNING) << "Mismatched authentication";
108 done_callback_.Run(net::ERR_FAILED, NULL);
109 return false;
110 }
111
112 done_callback_.Run(net::OK, socket_.release());
113 return false;
114 }
115
116 bool V1HostChannelAuthenticator::VerifyAuthBytes(
117 const std::string& received_auth_bytes) {
118 DCHECK(received_auth_bytes.length() == kAuthDigestLength);
119
120 unsigned char key_material[kAuthDigestLength];
121 int export_result = socket_->ExportKeyingMaterial(
122 kClientAuthSslExporterLabel, "", key_material, kAuthDigestLength);
123 if (export_result != net::OK) {
124 LOG(ERROR) << "Error fetching keying material: " << export_result;
125 done_callback_.Run(static_cast<net::Error>(export_result), NULL);
126 return false;
127 }
128
129 std::string auth_bytes;
130 if (!GetAuthBytes(shared_secret_,
131 std::string(key_material, key_material + kAuthDigestLength),
132 &auth_bytes)) {
133 done_callback_.Run(net::ERR_FAILED, NULL);
134 return false;
135 }
136
137 return crypto::SecureMemEqual(received_auth_bytes.data(),
138 &(auth_bytes[0]), kAuthDigestLength);
139 }
140
141 } // namespace protocol
142 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/protocol/v1_host_channel_authenticator.h ('k') | remoting/remoting.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698