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

Side by Side Diff: remoting/protocol/simple_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: - 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
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/simple_host_channel_authenticator.h"
6
7 #include "crypto/rsa_private_key.h"
8 #include "net/base/io_buffer.h"
9 #include "net/base/net_errors.h"
10 #include "net/base/ssl_config_service.h"
11 #include "net/socket/ssl_server_socket.h"
Wez 2011/11/22 22:29:48 Move this below x509_certificate.h
Sergey Ulanov 2011/11/23 01:23:42 Done.
12 #include "net/base/x509_certificate.h"
13 #include "remoting/protocol/auth_util.h"
14
15 namespace remoting {
16 namespace protocol {
17
18 SimpleHostChannelAuthenticator::SimpleHostChannelAuthenticator(
19 const std::string& local_cert,
20 crypto::RSAPrivateKey* local_private_key,
21 const std::string& shared_secret)
22 : local_cert_(local_cert),
23 local_private_key_(local_private_key),
24 shared_secret_(shared_secret),
25 socket_(NULL),
26 ALLOW_THIS_IN_INITIALIZER_LIST(connect_callback_(
27 this, &SimpleHostChannelAuthenticator::OnConnected)),
28 ALLOW_THIS_IN_INITIALIZER_LIST(auth_read_callback_(
29 this, &SimpleHostChannelAuthenticator::OnAuthBytesRead)) {
30 }
31
32 SimpleHostChannelAuthenticator::~SimpleHostChannelAuthenticator() {
33 }
34
35 void SimpleHostChannelAuthenticator::SecureAndAuthenticate(
36 net::StreamSocket* socket, const DoneCallback& done_callback) {
37 DCHECK(CalledOnValidThread());
38
39 scoped_ptr<net::StreamSocket> channel_socket(socket);
40 done_callback_ = done_callback;
41
42 scoped_refptr<net::X509Certificate> cert =
43 net::X509Certificate::CreateFromBytes(
44 local_cert_.data(), local_cert_.length());
45 if (!cert) {
46 LOG(ERROR) << "Failed to parse X509Certificate";
47 done_callback.Run(net::ERR_FAILED, NULL);
48 return;
49 }
50
51 // Create server SSL socket.
Wez 2011/11/22 22:29:48 nit: This comment's a bit redundant...
Sergey Ulanov 2011/11/23 01:23:42 Done.
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 SimpleHostChannelAuthenticator::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 unsigned char key_material[kAuthDigestLength];
70 int export_result = socket_->ExportKeyingMaterial(
71 kClientAuthSslExporterLabel, "", key_material, kAuthDigestLength);
72 if (export_result != net::OK) {
73 LOG(ERROR) << "Error fetching keying material: " << export_result;
74 done_callback_.Run(static_cast<net::Error>(export_result), NULL);
75 return;
76 }
77
78 if (!GetAuthBytes(shared_secret_,
79 std::string(key_material, key_material + kAuthDigestLength),
80 &auth_bytes_)) {
81 done_callback_.Run(net::ERR_FAILED, NULL);
82 return;
83 }
84
85 // Read an authentication digest.
86 auth_read_buf_ = new net::GrowableIOBuffer();
87 auth_read_buf_->SetCapacity(kAuthDigestLength);
88 DoAuthRead();
89 }
90
91 void SimpleHostChannelAuthenticator::DoAuthRead() {
92 while (true) {
93 int result = socket_->Read(auth_read_buf_,
94 auth_read_buf_->RemainingCapacity(),
95 &auth_read_callback_);
96 if (result == net::ERR_IO_PENDING)
97 break;
98 if (!HandleAuthBytesRead(result))
99 break;
100 }
101 }
102
103 void SimpleHostChannelAuthenticator::OnAuthBytesRead(int result) {
104 DCHECK(CalledOnValidThread());
105
106 if (HandleAuthBytesRead(result))
107 DoAuthRead();
108 }
109
110 bool SimpleHostChannelAuthenticator::HandleAuthBytesRead(int read_result) {
111 if (read_result <= 0) {
112 LOG(ERROR) << "Error reading authentication: " << read_result;
Wez 2011/11/22 22:29:48 nit: Don't really need this logging, or the preced
Sergey Ulanov 2011/11/23 01:23:42 Done.
113 done_callback_.Run(static_cast<net::Error>(read_result), NULL);
114 return false;
115 }
116
117 auth_read_buf_->set_offset(auth_read_buf_->offset() + read_result);
118 if (auth_read_buf_->RemainingCapacity() > 0)
119 return true;
120
121 if (!VerifyAuthBytes(std::string(
122 auth_read_buf_->StartOfBuffer(),
123 auth_read_buf_->StartOfBuffer() + kAuthDigestLength))) {
124 LOG(ERROR) << "Mismatched authentication";
Wez 2011/11/22 22:29:48 nit: Make this a warning, or remove it? Is there
Sergey Ulanov 2011/11/23 01:23:42 Done.
125 done_callback_.Run(net::ERR_FAILED, NULL);
126 return false;
127 }
128
129 done_callback_.Run(net::OK, socket_.release());
130 return false;
131 }
132
133 bool SimpleHostChannelAuthenticator::VerifyAuthBytes(
134 const std::string& received_auth_bytes) {
135 DCHECK(received_auth_bytes.length() == kAuthDigestLength);
136
137 // Compare the received and expected digests in fixed time, to limit the
138 // scope for timing attacks.
139 uint8 result = 0;
140 for (unsigned i = 0; i < auth_bytes_.length(); i++) {
141 result |= received_auth_bytes[i] ^ auth_bytes_[i];
Ryan Sleevi 2011/11/19 19:45:26 nit: See crypto/secure_util.h -> crypto::SecureMem
Sergey Ulanov 2011/11/22 02:49:18 Done.
142 }
143 return result == 0;
144 }
145
146 } // namespace protocol
147 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698