Chromium Code Reviews| 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 |