Index: remoting/protocol/channel_authenticator.cc |
diff --git a/remoting/protocol/channel_authenticator.cc b/remoting/protocol/channel_authenticator.cc |
deleted file mode 100644 |
index fcce9b135dd483f39937a21eee3f6638d25df4a9..0000000000000000000000000000000000000000 |
--- a/remoting/protocol/channel_authenticator.cc |
+++ /dev/null |
@@ -1,220 +0,0 @@ |
-// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "remoting/protocol/channel_authenticator.h" |
- |
-#include "base/compiler_specific.h" |
-#include "base/string_piece.h" |
-#include "crypto/hmac.h" |
-#include "net/base/io_buffer.h" |
-#include "net/base/net_errors.h" |
-#include "net/socket/ssl_socket.h" |
-#include "net/socket/stream_socket.h" |
- |
-namespace remoting { |
-namespace protocol { |
- |
-namespace { |
- |
-// Labels for use when exporting the SSL master keys. |
-const char kClientSslExporterLabel[] = "EXPORTER-remoting-channel-auth-client"; |
- |
-// Size of the HMAC-SHA-256 authentication digest. |
-const size_t kAuthDigestLength = 32; |
- |
-// static |
-bool GetAuthBytes(const std::string& shared_secret, |
- const std::string& key_material, |
- std::string* auth_bytes) { |
- // Generate auth digest based on the keying material and shared secret. |
- crypto::HMAC response(crypto::HMAC::SHA256); |
- if (!response.Init(key_material)) { |
- NOTREACHED() << "HMAC::Init failed"; |
- return false; |
- } |
- unsigned char out_bytes[kAuthDigestLength]; |
- if (!response.Sign(shared_secret, out_bytes, kAuthDigestLength)) { |
- NOTREACHED() << "HMAC::Sign failed"; |
- return false; |
- } |
- |
- auth_bytes->assign(out_bytes, out_bytes + kAuthDigestLength); |
- return true; |
-} |
- |
-} // namespace |
- |
-HostChannelAuthenticator::HostChannelAuthenticator( |
- const std::string& shared_secret) |
- : shared_secret_(shared_secret), |
- socket_(NULL), |
- ALLOW_THIS_IN_INITIALIZER_LIST(auth_read_callback_( |
- this, &HostChannelAuthenticator::OnAuthBytesRead)) { |
-} |
- |
-HostChannelAuthenticator::~HostChannelAuthenticator() { |
-} |
- |
-void HostChannelAuthenticator::Authenticate(net::SSLSocket* socket, |
- const DoneCallback& done_callback) { |
- DCHECK(CalledOnValidThread()); |
- |
- socket_ = socket; |
- done_callback_ = done_callback; |
- |
- unsigned char key_material[kAuthDigestLength]; |
- int result = socket_->ExportKeyingMaterial( |
- kClientSslExporterLabel, "", key_material, kAuthDigestLength); |
- if (result != net::OK) { |
- LOG(ERROR) << "Error fetching keying material: " << result; |
- done_callback.Run(FAILURE); |
- return; |
- } |
- |
- if (!GetAuthBytes(shared_secret_, |
- std::string(key_material, key_material + kAuthDigestLength), |
- &auth_bytes_)) { |
- done_callback.Run(FAILURE); |
- return; |
- } |
- |
- // Read an authentication digest. |
- auth_read_buf_ = new net::GrowableIOBuffer(); |
- auth_read_buf_->SetCapacity(kAuthDigestLength); |
- DoAuthRead(); |
-} |
- |
-void HostChannelAuthenticator::DoAuthRead() { |
- while (true) { |
- int result = socket_->Read(auth_read_buf_, |
- auth_read_buf_->RemainingCapacity(), |
- &auth_read_callback_); |
- if (result == net::ERR_IO_PENDING) |
- break; |
- if (!HandleAuthBytesRead(result)) |
- break; |
- } |
-} |
- |
-void HostChannelAuthenticator::OnAuthBytesRead(int result) { |
- DCHECK(CalledOnValidThread()); |
- |
- if (HandleAuthBytesRead(result)) |
- DoAuthRead(); |
-} |
- |
-bool HostChannelAuthenticator::HandleAuthBytesRead(int read_result) { |
- if (read_result <= 0) { |
- LOG(ERROR) << "Error reading authentication: " << read_result; |
- done_callback_.Run(FAILURE); |
- return false; |
- } |
- |
- auth_read_buf_->set_offset(auth_read_buf_->offset() + read_result); |
- if (auth_read_buf_->RemainingCapacity() > 0) |
- return true; |
- |
- if (!VerifyAuthBytes(std::string( |
- auth_read_buf_->StartOfBuffer(), |
- auth_read_buf_->StartOfBuffer() + kAuthDigestLength))) { |
- LOG(ERROR) << "Mismatched authentication"; |
- done_callback_.Run(FAILURE); |
- return false; |
- } |
- |
- done_callback_.Run(SUCCESS); |
- return false; |
-} |
- |
-bool HostChannelAuthenticator::VerifyAuthBytes( |
- const std::string& received_auth_bytes) { |
- DCHECK(received_auth_bytes.length() == kAuthDigestLength); |
- |
- // Compare the received and expected digests in fixed time, to limit the |
- // scope for timing attacks. |
- uint8 result = 0; |
- for (unsigned i = 0; i < auth_bytes_.length(); i++) { |
- result |= received_auth_bytes[i] ^ auth_bytes_[i]; |
- } |
- return result == 0; |
-} |
- |
-ClientChannelAuthenticator::ClientChannelAuthenticator( |
- const std::string& shared_secret) |
- : shared_secret_(shared_secret), |
-socket_(NULL), |
- ALLOW_THIS_IN_INITIALIZER_LIST(auth_write_callback_( |
- this, &ClientChannelAuthenticator::OnAuthBytesWritten)) { |
-} |
- |
-ClientChannelAuthenticator::~ClientChannelAuthenticator() { |
-} |
- |
-void ClientChannelAuthenticator::Authenticate( |
- net::SSLSocket* socket, |
- const DoneCallback& done_callback) { |
- DCHECK(CalledOnValidThread()); |
- |
- socket_ = socket; |
- done_callback_ = done_callback; |
- |
- unsigned char key_material[kAuthDigestLength]; |
- int result = socket_->ExportKeyingMaterial( |
- kClientSslExporterLabel, "", key_material, kAuthDigestLength); |
- if (result != net::OK) { |
- LOG(ERROR) << "Error fetching keying material: " << result; |
- done_callback.Run(FAILURE); |
- return; |
- } |
- |
- std::string auth_bytes; |
- if (!GetAuthBytes(shared_secret_, |
- std::string(key_material, key_material + kAuthDigestLength), |
- &auth_bytes)) { |
- done_callback.Run(FAILURE); |
- return; |
- } |
- |
- // Allocate a buffer to write the authentication digest. |
- auth_write_buf_ = new net::DrainableIOBuffer( |
- new net::StringIOBuffer(auth_bytes), auth_bytes.size()); |
- DoAuthWrite(); |
-} |
- |
-void ClientChannelAuthenticator::DoAuthWrite() { |
- while (true) { |
- int result = socket_->Write(auth_write_buf_, |
- auth_write_buf_->BytesRemaining(), |
- &auth_write_callback_); |
- if (result == net::ERR_IO_PENDING) |
- break; |
- if (!HandleAuthBytesWritten(result)) |
- break; |
- } |
-} |
- |
-void ClientChannelAuthenticator::OnAuthBytesWritten(int result) { |
- DCHECK(CalledOnValidThread()); |
- |
- if (HandleAuthBytesWritten(result)) |
- DoAuthWrite(); |
-} |
- |
-bool ClientChannelAuthenticator::HandleAuthBytesWritten(int result) { |
- if (result <= 0) { |
- LOG(ERROR) << "Error writing authentication: " << result; |
- done_callback_.Run(FAILURE); |
- return false; |
- } |
- |
- auth_write_buf_->DidConsume(result); |
- if (auth_write_buf_->BytesRemaining() > 0) |
- return true; |
- |
- done_callback_.Run(SUCCESS); |
- return false; |
-} |
- |
-} // namespace protocol |
-} // namespace remoting |