OLD | NEW |
---|---|
(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_client_channel_authenticator.h" | |
6 | |
7 #include "net/base/cert_verifier.h" | |
8 #include "net/base/host_port_pair.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/socket/client_socket_factory.h" | |
13 #include "net/socket/ssl_client_socket.h" | |
14 #include "remoting/protocol/auth_util.h" | |
15 | |
16 namespace remoting { | |
17 namespace protocol { | |
18 | |
19 namespace { | |
20 | |
21 // Helper method to create a SSL client socket. | |
22 net::SSLClientSocket* CreateSSLClientSocket( | |
Wez
2011/11/22 22:29:48
Is it really worth having this a separate method f
Sergey Ulanov
2011/11/23 01:23:42
Done.
| |
23 net::StreamSocket* socket, const std::string& der_cert, | |
24 net::CertVerifier* cert_verifier) { | |
25 net::SSLConfig ssl_config; | |
26 | |
27 // Certificate provided by the host doesn't need authority. | |
Wez
2011/11/22 22:29:48
Isn't this also to do with being self-signed, as b
Sergey Ulanov
2011/11/23 01:23:42
Done.
| |
28 net::SSLConfig::CertAndStatus cert_and_status; | |
29 cert_and_status.cert_status = net::CERT_STATUS_AUTHORITY_INVALID; | |
30 cert_and_status.der_cert = der_cert; | |
31 ssl_config.allowed_bad_certs.push_back(cert_and_status); | |
32 | |
33 // Revocation checking is not needed because we use self-signed | |
34 // certs. Disable it so that SSL layer doesn't try to initialize | |
Wez
2011/11/22 22:29:48
nit: that _the_ SSL layer
Sergey Ulanov
2011/11/23 01:23:42
Done.
| |
35 // OCSP (OCSP works only on IO thread). | |
Wez
2011/11/22 22:29:48
nit: on _the_ IO thread
Sergey Ulanov
2011/11/23 01:23:42
Done.
| |
36 ssl_config.rev_checking_enabled = false; | |
37 | |
38 // SSLClientSocket takes ownership of the adapter. | |
Wez
2011/11/22 22:29:48
nit: What adapter?
Sergey Ulanov
2011/11/23 01:23:42
Done.
| |
39 net::HostPortPair host_and_port(kSslFakeHostName, 0); | |
40 net::SSLClientSocketContext context; | |
41 context.cert_verifier = cert_verifier; | |
42 net::SSLClientSocket* ssl_socket = | |
43 net::ClientSocketFactory::GetDefaultFactory()->CreateSSLClientSocket( | |
44 socket, host_and_port, ssl_config, NULL, context); | |
45 return ssl_socket; | |
46 } | |
47 | |
48 } // namespace | |
49 | |
50 SimpleClientChannelAuthenticator::SimpleClientChannelAuthenticator( | |
51 const std::string& remote_cert, | |
Wez
2011/11/22 22:29:48
nit: |remote_cert| -> |peer_cert|?
Sergey Ulanov
2011/11/23 01:23:42
Changed it to host_cert as it is more specific.
| |
52 const std::string& shared_secret) | |
53 : remote_cert_(remote_cert), | |
54 shared_secret_(shared_secret), | |
55 socket_(NULL), | |
56 ALLOW_THIS_IN_INITIALIZER_LIST(connect_callback_( | |
57 this, &SimpleClientChannelAuthenticator::OnConnected)), | |
58 ALLOW_THIS_IN_INITIALIZER_LIST(auth_write_callback_( | |
59 this, &SimpleClientChannelAuthenticator::OnAuthBytesWritten)) { | |
60 } | |
61 | |
62 SimpleClientChannelAuthenticator::~SimpleClientChannelAuthenticator() { | |
63 } | |
64 | |
65 void SimpleClientChannelAuthenticator::SecureAndAuthenticate( | |
66 net::StreamSocket* socket, const DoneCallback& done_callback) { | |
67 DCHECK(CalledOnValidThread()); | |
68 | |
69 done_callback_ = done_callback; | |
70 | |
71 cert_verifier_.reset(new net::CertVerifier()); | |
Wez
2011/11/22 22:29:48
Why do we pass in a standard CertVerifier if we ne
Sergey Ulanov
2011/11/23 01:23:42
This is because SSLClientSocket still expects to g
| |
72 socket_.reset(CreateSSLClientSocket( | |
73 socket, remote_cert_, cert_verifier_.get())); | |
74 | |
75 int result = socket_->Connect(&connect_callback_); | |
Wez
2011/11/22 22:29:48
It seems strange for connecting the SteramSocket t
Sergey Ulanov
2011/11/23 01:23:42
This connects SSL layer, not the socket itself. Th
| |
76 if (result == net::ERR_IO_PENDING) { | |
77 return; | |
78 } | |
79 OnConnected(result); | |
80 } | |
81 | |
82 void SimpleClientChannelAuthenticator::OnConnected(int result) { | |
83 if (result != net::OK) { | |
84 LOG(ERROR) << "Failed to establish SSL connection"; | |
Wez
2011/11/22 22:29:48
nit: I don't think this needs logging here; callin
Sergey Ulanov
2011/11/23 01:23:42
This log message should be very rare, and I think
| |
85 done_callback_.Run(static_cast<net::Error>(result), NULL); | |
86 } | |
87 | |
88 unsigned char key_material[kAuthDigestLength]; | |
89 int export_result = socket_->ExportKeyingMaterial( | |
90 kClientAuthSslExporterLabel, "", key_material, kAuthDigestLength); | |
91 if (export_result != net::OK) { | |
92 LOG(ERROR) << "Error fetching keying material: " << export_result; | |
Wez
2011/11/22 22:29:48
nit: See above.
Sergey Ulanov
2011/11/23 01:23:42
same here
| |
93 done_callback_.Run(static_cast<net::Error>(export_result), NULL); | |
94 return; | |
95 } | |
96 | |
97 std::string auth_bytes; | |
98 if (!GetAuthBytes(shared_secret_, | |
99 std::string(key_material, key_material + kAuthDigestLength), | |
Wez
2011/11/22 22:29:48
Why not just std::string(key_material, kAuthDigest
Sergey Ulanov
2011/11/23 01:23:42
key_material is unsigned int, so std::string(key_m
| |
100 &auth_bytes)) { | |
101 done_callback_.Run(net::ERR_FAILED, NULL); | |
102 return; | |
103 } | |
104 | |
105 // Allocate a buffer to write the authentication digest. | |
Wez
2011/11/22 22:29:48
nit: This function doesn't have comments on earlie
Sergey Ulanov
2011/11/23 01:23:42
Done.
| |
106 auth_write_buf_ = new net::DrainableIOBuffer( | |
107 new net::StringIOBuffer(auth_bytes), auth_bytes.size()); | |
108 DoAuthWrite(); | |
109 } | |
110 | |
111 void SimpleClientChannelAuthenticator::DoAuthWrite() { | |
Wez
2011/11/22 22:29:48
nit: DoAuthWrite -> WriteAuthenticationBytes() or
Sergey Ulanov
2011/11/23 01:23:42
Done.
| |
112 while (true) { | |
113 int result = socket_->Write(auth_write_buf_, | |
114 auth_write_buf_->BytesRemaining(), | |
115 &auth_write_callback_); | |
116 if (result == net::ERR_IO_PENDING) | |
117 break; | |
118 if (!HandleAuthBytesWritten(result)) | |
119 break; | |
120 } | |
121 } | |
122 | |
123 void SimpleClientChannelAuthenticator::OnAuthBytesWritten(int result) { | |
124 DCHECK(CalledOnValidThread()); | |
125 | |
126 if (HandleAuthBytesWritten(result)) | |
127 DoAuthWrite(); | |
128 } | |
129 | |
130 bool SimpleClientChannelAuthenticator::HandleAuthBytesWritten(int result) { | |
131 if (result <= 0) { | |
132 LOG(ERROR) << "Error writing authentication: " << result; | |
133 done_callback_.Run(static_cast<net::Error>(result), NULL); | |
134 return false; | |
135 } | |
136 | |
137 auth_write_buf_->DidConsume(result); | |
138 if (auth_write_buf_->BytesRemaining() > 0) | |
139 return true; | |
140 | |
141 done_callback_.Run(net::OK, socket_.release()); | |
142 return false; | |
143 } | |
144 | |
145 } // namespace protocol | |
146 } // namespace remoting | |
OLD | NEW |