diff options
author | rmsousa@chromium.org <rmsousa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-07 13:43:10 +0000 |
---|---|---|
committer | rmsousa@chromium.org <rmsousa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-07 13:43:10 +0000 |
commit | 8f1504bf1badb27cff0f1a71886f89de09d7fd7e (patch) | |
tree | 01ecd48a698dfc1fd77189fc6ca12454ad36b27c | |
parent | 558b2e4ba581c3c20b22520aeaf5705adaa442ee (diff) | |
download | chromium_src-8f1504bf1badb27cff0f1a71886f89de09d7fd7e.zip chromium_src-8f1504bf1badb27cff0f1a71886f89de09d7fd7e.tar.gz chromium_src-8f1504bf1badb27cff0f1a71886f89de09d7fd7e.tar.bz2 |
Move HostKeyPair into protocol::KeyPair.
This makes the RSAPrivateKey dependency encapsulated inside KeyPair, and makes it a refcounted object, rather than copying the private key on every authenticator constructor. It also allows authenticators to use the KeyPair methods (such as GetSignature() or GetPublicKey()).
BUG=115899
Review URL: https://chromiumcodereview.appspot.com/12316083
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@186709 0039d316-1c4b-4281-b951-d872f2087c98
34 files changed, 330 insertions, 299 deletions
diff --git a/remoting/host/host_key_pair.cc b/remoting/base/rsa_key_pair.cc index ff0f2cf..566bf01 100644 --- a/remoting/host/host_key_pair.cc +++ b/remoting/base/rsa_key_pair.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "remoting/host/host_key_pair.h" +#include "remoting/base/rsa_key_pair.h" #include <limits> #include <string> @@ -15,54 +15,52 @@ #include "crypto/rsa_private_key.h" #include "crypto/signature_creator.h" #include "net/base/x509_certificate.h" -#include "remoting/host/host_config.h" namespace remoting { -HostKeyPair::HostKeyPair() { } +RsaKeyPair::RsaKeyPair(scoped_ptr<crypto::RSAPrivateKey> key) + : key_(key.Pass()){ + DCHECK(key_); +} -HostKeyPair::~HostKeyPair() { } +RsaKeyPair::~RsaKeyPair() {} -void HostKeyPair::Generate() { - key_.reset(crypto::RSAPrivateKey::Create(2048)); +//static +scoped_refptr<RsaKeyPair> RsaKeyPair::Generate() { + scoped_ptr<crypto::RSAPrivateKey> key(crypto::RSAPrivateKey::Create(2048)); + if (!key) { + LOG(ERROR) << "Cannot generate private key."; + return NULL; + } + return new RsaKeyPair(key.Pass()); } -bool HostKeyPair::LoadFromString(const std::string& key_base64) { +//static +scoped_refptr<RsaKeyPair> RsaKeyPair::FromString( + const std::string& key_base64) { std::string key_str; if (!base::Base64Decode(key_base64, &key_str)) { LOG(ERROR) << "Failed to decode private key."; - return false; + return NULL; } std::vector<uint8> key_buf(key_str.begin(), key_str.end()); - key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_buf)); - if (key_.get() == NULL) { + scoped_ptr<crypto::RSAPrivateKey> key( + crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_buf)); + if (!key) { LOG(ERROR) << "Invalid private key."; - return false; - } - - return true; -} - -bool HostKeyPair::Load(const HostConfig& host_config) { - std::string key_base64; - if (!host_config.GetString(kPrivateKeyConfigPath, &key_base64)) { - LOG(ERROR) << "Private key wasn't found in the config file."; - return false; + return NULL; } - return LoadFromString(key_base64); -} -void HostKeyPair::Save(MutableHostConfig* host_config) { - host_config->SetString(kPrivateKeyConfigPath, GetAsString()); + return new RsaKeyPair(key.Pass()); } -std::string HostKeyPair::GetAsString() const { +std::string RsaKeyPair::ToString() const { // Check that the key initialized. DCHECK(key_.get() != NULL); std::vector<uint8> key_buf; - key_->ExportPrivateKey(&key_buf); + CHECK(key_->ExportPrivateKey(&key_buf)); std::string key_str(key_buf.begin(), key_buf.end()); std::string key_base64; if (!base::Base64Encode(key_str, &key_base64)) { @@ -71,16 +69,16 @@ std::string HostKeyPair::GetAsString() const { return key_base64; } -std::string HostKeyPair::GetPublicKey() const { +std::string RsaKeyPair::GetPublicKey() const { std::vector<uint8> public_key; - key_->ExportPublicKey(&public_key); + CHECK(key_->ExportPublicKey(&public_key)); std::string public_key_str(public_key.begin(), public_key.end()); std::string public_key_base64; base::Base64Encode(public_key_str, &public_key_base64); return public_key_base64; } -std::string HostKeyPair::GetSignature(const std::string& message) const { +std::string RsaKeyPair::SignMessage(const std::string& message) const { scoped_ptr<crypto::SignatureCreator> signature_creator( crypto::SignatureCreator::Create(key_.get())); signature_creator->Update(reinterpret_cast<const uint8*>(message.c_str()), @@ -93,13 +91,7 @@ std::string HostKeyPair::GetSignature(const std::string& message) const { return signature_base64; } -crypto::RSAPrivateKey* HostKeyPair::CopyPrivateKey() const { - std::vector<uint8> key_bytes; - CHECK(key_->ExportPrivateKey(&key_bytes)); - return crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes); -} - -std::string HostKeyPair::GenerateCertificate() const { +std::string RsaKeyPair::GenerateCertificate() const { scoped_refptr<net::X509Certificate> cert = net::X509Certificate::CreateSelfSigned( key_.get(), "CN=chromoting", diff --git a/remoting/base/rsa_key_pair.h b/remoting/base/rsa_key_pair.h new file mode 100644 index 0000000..f5009b2 --- /dev/null +++ b/remoting/base/rsa_key_pair.h @@ -0,0 +1,55 @@ +// Copyright (c) 2012 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. + +#ifndef REMOTING_BASE_RSA_KEY_PAIR_H_ +#define REMOTING_BASE_RSA_KEY_PAIR_H_ + +#include <string> + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" + +namespace crypto { +class RSAPrivateKey; +} // namespace crypto + +namespace remoting { + +class RsaKeyPair : public base::RefCountedThreadSafe<RsaKeyPair> { + public: + // Generates a new (random) private key. + static scoped_refptr<RsaKeyPair> Generate(); + + // Loads a private key from a base64-encoded string. Returns true on success. + static scoped_refptr<RsaKeyPair> FromString(const std::string& key_base64); + + // Returns a base64 encoded string representing the private key. + std::string ToString() const; + + // Generates a DER-encoded self-signed certificate using the key pair. Returns + // empty string if cert generation fails (e.g. it may happen when the system + // clock is off). + std::string GenerateCertificate() const; + + // Returns a base64-encoded string representing the public key. + std::string GetPublicKey() const; + + // Returns a base64-encoded signature for the message. + std::string SignMessage(const std::string& message) const; + + crypto::RSAPrivateKey* private_key() { return key_.get(); } + + private: + friend class base::RefCountedThreadSafe<RsaKeyPair>; + RsaKeyPair(scoped_ptr<crypto::RSAPrivateKey> key); + virtual ~RsaKeyPair(); + + scoped_ptr<crypto::RSAPrivateKey> key_; + + DISALLOW_COPY_AND_ASSIGN(RsaKeyPair); +}; + +} // namespace remoting + +#endif // REMOTING_BASE_RSA_KEY_PAIR_H_ diff --git a/remoting/base/rsa_key_pair_unittest.cc b/remoting/base/rsa_key_pair_unittest.cc new file mode 100644 index 0000000..4b38659 --- /dev/null +++ b/remoting/base/rsa_key_pair_unittest.cc @@ -0,0 +1,98 @@ +// Copyright (c) 2012 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 <string> + +#include "remoting/base/rsa_key_pair.h" +#include "remoting/base/test_rsa_key_pair.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace remoting { + +namespace { +const char kTestMessage[] = "Test Message"; + +// |kTestMessage| signed with the key from |kTestRsaKeyPair|. +const char kExpectedSignature[] = +"LfUyXU2AiKM4rpWivUR3bLiQiRt1W3iIenNfJEB8RWyoEfnvSBoD52x8q9yFvtLFDEMPWyIrwM+N2" +"LuaWBKG1c0R7h+twBgvpExzZneJl+lbGMRx9ba8m/KAFrUWA/NRzOen2NHCuPybOEasgrPgGWBrmf" +"gDcvyW8QiGuKLopGj/4c5CQT4yE8JjsyU3Qqo2ZPK4neJYQhOmAlg+Q5dAPLpzWMj5HQyOVHJaSXZ" +"Y8vl/LiKvbdofYLeYNVKAE4q5mfpQMrsysPYpbxBV60AhFyrvtC040MFGcflKQRZNiZwMXVb7DclC" +"BPgvK7rI5Y0ERtVm+yNmH7vCivfyAnDUYA=="; + +// Another RSA key pair, different from |kTestRsaKeyPair| +const char kTestRsaKeyPair2[] = +"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDLNd9bNNBFxXSasqWHv8ydItmoi" +"NhiWV/1Z6JI6TpKTnTm9yQSxIoCLHT8fB8QA0wzzgYEuZpDHIZDv1WxSdC3kgx84JrWe43+SPDZ2b" +"7ekuhXinPK+f3Nw5GjGaAUevyeWNoDD3GFka5q4zw8W1OE8E/z50FfPqOUejg+qyrgovEWQIZWvI0" +"CHdy8HTtxT7G0YbPJYZ8ycRkUrsXtY2RQX4IaCMEcdAmCm2Q2hYldulbZX6Bvv5GX8FOWYOerbYVK" +"ZsmH5II+KEP4We75ONVR2jdCCJ5L3YMXtbYtZZy1yZXcOf2fpBo6+p81M7rG9com/C75QoMVMVJJC" +"ahCli7/AgMBAAECggEAZNzThUC8k7UDQHmlgbCojeIraOSrin1UDMmomknxHcq9aZqHtC0LVzLbyi" +"qNfHQ2kYwUHqpFMERrPBsvHHVH/KWoPx94mzbubqWjrm3OuEjwu+rDuJ7G5CfLFMp2U1QMKUhuxZA" +"Xx7Vcfj9VuZuW4+gntyc0omLD7MGRQ0HQYXh7ZDGWrMPEs6Cjzcx9/G9AD7ysWIqk14iwJqKhztiD" +"NirMr64eDZFzzDvXTl3j5l+yiAHiV5LPUUKyCe+jEdZMceSKy5wSZXSkiW4zhgEzwdMN2zmxlcC59" +"17dw2c6xD+tKxTMwzx77sauBFNzebNU1m5hIKH+jCPiA8aQv3/l8QKBgQD8J4ilT/CV6hhw0/q99e" +"+54s+SIz8nYo8fvyeEBCiA4lf/OZuxl/sYWK+PthP+xzsjKTq7yoFkliXrtOioW34E0WdLv+6jEXQ" +"hxaXZyk0TMwxm228xMG66evXDJ8OGWCi6uiAnVWNUu6VXacQwKHf9hv6DNRNcmkQGojfcx3ZNZwKB" +"gQDOT0ApweRr0zA28l8C6qtNfY/NIeWTWPDTspt8zDoX1ILXc2HZHYW0QtUQ6tXNQnUW/ymavla7E" +"upa8AoZoqMvaUIg1BjMYIzc4yQMVf1BRCfvT8GsoymX+8Gt/DB34L7KMPOhQysMmZMNjKtozQsbZY" +"wcnN19pWnDv78trFZ6qQKBgHy1nMqN7+JlRjM/VCrxYOAhwiF31ztGbpz38LZFTDb6OyVau5spHKH" +"c8u9z0Q3YQXJRaOAJ9tblv9mEvvDNV1VQr/Lx+TejYTl2xGEjwdz2CXMxohvE5W7Lc5NSrkxae8Jm" +"XZK2k4sLx2mlQMfErBuy0VvZOzs4fN5/CnviFquPAoGBAI8NAI5ztPDW1L2kvSCGmxT2FTnFYSwUJ" +"ZiEZa/Y5AcWAUtm49fp0oW1OYuraWgTxqCVeMGlbPn2Ga3IdxhjXwdG0uV0a2V7JPEcRiiPjzUsDw" +"yunroXwIVzuU3saacVnPURkDynGDh6XC6u9UOLuUHb3ZURZ7rxcS6by/HdZ3FRAoGBAOhjtjyfFEn" +"bZtjcQd+bNtoTPV/L71+K8AYPwV0td5Qy5VbBrTIlv7pNFxE4bYNuEe6cI2cxTua4i5IoKYXyUm5u" +"SvUVkkz7CpoiFwMnnLsNrZmazVS2zq0Y2a2ai8C3mPgLOdroS2fBBAcuFApeq1PvISmT6ZnJJ8Yah" +"HQCfClh"; + +} // namespace + +class RsaKeyPairTest : public testing::Test { +}; + +TEST_F(RsaKeyPairTest, ImportExportImport) { + // Load a key from a string, export to a string, load again, and verify that + // we generate the same signature with both keys. + scoped_refptr<RsaKeyPair> exported_key = RsaKeyPair::FromString( + kTestRsaKeyPair); + scoped_refptr<RsaKeyPair> imported_key = RsaKeyPair::FromString( + exported_key->ToString()); + + ASSERT_EQ(exported_key->SignMessage(kTestMessage), + imported_key->SignMessage(kTestMessage)); +} + +TEST_F(RsaKeyPairTest, Signatures) { + // Sign a message and check that we get the expected signature. + scoped_refptr<RsaKeyPair> key_pair = RsaKeyPair::FromString(kTestRsaKeyPair); + + std::string signature_base64 = key_pair->SignMessage(kTestMessage); + ASSERT_EQ(signature_base64, std::string(kExpectedSignature)); +} + +TEST_F(RsaKeyPairTest, GenerateKey) { + // Test that we can generate a valid key. + scoped_refptr<RsaKeyPair> key_pair = RsaKeyPair::Generate(); + ASSERT_TRUE(key_pair); + ASSERT_NE(key_pair->ToString(), ""); + ASSERT_NE(key_pair->GetPublicKey(), ""); + ASSERT_NE(key_pair->SignMessage(kTestMessage), ""); +} + +TEST_F(RsaKeyPairTest, SignaturesDiffer) { + // Sign using different keys/messages and check that signatures are different. + scoped_refptr<RsaKeyPair> key_pair1 = RsaKeyPair::FromString(kTestRsaKeyPair); + scoped_refptr<RsaKeyPair> key_pair2 = RsaKeyPair::FromString( + kTestRsaKeyPair2); + + std::string signature_kp1_msg1_base64 = key_pair1->SignMessage(kTestMessage); + std::string signature_kp2_msg1_base64 = key_pair2->SignMessage(kTestMessage); + std::string signature_kp1_msg2_base64 = key_pair1->SignMessage("Different"); + ASSERT_NE(signature_kp1_msg1_base64, signature_kp2_msg1_base64); + ASSERT_NE(signature_kp1_msg1_base64, signature_kp1_msg2_base64); + ASSERT_NE(key_pair1->GetPublicKey(), key_pair2->GetPublicKey()); +} + +} // namespace remoting diff --git a/remoting/host/test_key_pair.h b/remoting/base/test_rsa_key_pair.h index cb46e4c..1578003 100644 --- a/remoting/host/test_key_pair.h +++ b/remoting/base/test_rsa_key_pair.h @@ -3,8 +3,9 @@ // found in the LICENSE file. namespace remoting { + // An RSA keypair used in unittests. -const char kTestHostKeyPair[] = +const char kTestRsaKeyPair[] = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDeeT/wgtzQkGoeA5LRQI4iXibQZ" "R3YUiJn/oVz0P+KLJSCWL4Uhjl3CytKg0nzuxgaJ9UOHxrl91k1XnLnwJytqkjl8kgWle+JJbiDx3" "+3WBxmSjPWmmaPNuBebpyTD1N3TJEPRwe7vfYiOz56jzBPSm3gqIeRvJGIC+Ou+Q0OV+ISTu2Jjtj" @@ -27,4 +28,5 @@ const char kTestHostKeyPair[] = "Et5ho7YqrrBWTwnvMLw4G7qftiMco15JcMAXhfGhmlDI8OUq7MlXVCUWwdZtRYcAyWJcqhWQ3yrXv" "8cWi9hxwNGPuof5PchDDuR+cwe8gZvpzwfFDFTgJHIBe64CkFd9Oeb5CvEffbrP04mpWvjVeMcjjz" "ZA6a+IB"; + } // namespace remoting diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h index d755744..5d9d236 100644 --- a/remoting/host/chromoting_host.h +++ b/remoting/host/chromoting_host.h @@ -15,7 +15,6 @@ #include "base/threading/thread.h" #include "net/base/backoff_entry.h" #include "remoting/host/client_session.h" -#include "remoting/host/host_key_pair.h" #include "remoting/host/host_status_monitor.h" #include "remoting/host/host_status_observer.h" #include "remoting/host/mouse_move_observer.h" diff --git a/remoting/host/heartbeat_sender.cc b/remoting/host/heartbeat_sender.cc index ebad71d..82506ce 100644 --- a/remoting/host/heartbeat_sender.cc +++ b/remoting/host/heartbeat_sender.cc @@ -51,7 +51,7 @@ HeartbeatSender::HeartbeatSender( Listener* listener, const std::string& host_id, SignalStrategy* signal_strategy, - HostKeyPair* key_pair, + scoped_refptr<RsaKeyPair> key_pair, const std::string& directory_bot_jid) : listener_(listener), host_id_(host_id), @@ -264,7 +264,7 @@ scoped_ptr<XmlElement> HeartbeatSender::CreateSignature() { std::string message = signal_strategy_->GetLocalJid() + ' ' + base::IntToString(sequence_id_); - std::string signature(key_pair_->GetSignature(message)); + std::string signature(key_pair_->SignMessage(message)); signature_tag->AddText(signature); return signature_tag.Pass(); diff --git a/remoting/host/heartbeat_sender.h b/remoting/host/heartbeat_sender.h index 2d0986d..c79c863 100644 --- a/remoting/host/heartbeat_sender.h +++ b/remoting/host/heartbeat_sender.h @@ -12,7 +12,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/timer.h" -#include "remoting/host/host_key_pair.h" +#include "remoting/base/rsa_key_pair.h" #include "remoting/jingle_glue/signal_strategy.h" namespace base { @@ -25,7 +25,7 @@ class XmlElement; namespace remoting { -class HostKeyPair; +class RsaKeyPair; class IqRequest; class IqSender; @@ -86,13 +86,13 @@ class HeartbeatSender : public SignalStrategy::Listener { virtual void OnUnknownHostIdError() = 0; }; - // |signal_strategy|, |key_pair| and |delegate| must outlive this + // |signal_strategy| and |delegate| must outlive this // object. Heartbeats will start when the supplied SignalStrategy // enters the CONNECTED state. HeartbeatSender(Listener* listener, const std::string& host_id, SignalStrategy* signal_strategy, - HostKeyPair* key_pair, + scoped_refptr<RsaKeyPair> key_pair, const std::string& directory_bot_jid); virtual ~HeartbeatSender(); @@ -125,7 +125,7 @@ class HeartbeatSender : public SignalStrategy::Listener { Listener* listener_; std::string host_id_; SignalStrategy* signal_strategy_; - HostKeyPair* key_pair_; + scoped_refptr<RsaKeyPair> key_pair_; std::string directory_bot_jid_; scoped_ptr<IqSender> iq_sender_; scoped_ptr<IqRequest> request_; diff --git a/remoting/host/heartbeat_sender_unittest.cc b/remoting/host/heartbeat_sender_unittest.cc index 0947937..99880b4 100644 --- a/remoting/host/heartbeat_sender_unittest.cc +++ b/remoting/host/heartbeat_sender_unittest.cc @@ -11,8 +11,8 @@ #include "base/message_loop_proxy.h" #include "base/string_number_conversions.h" #include "remoting/base/constants.h" -#include "remoting/host/host_key_pair.h" -#include "remoting/host/test_key_pair.h" +#include "remoting/base/rsa_key_pair.h" +#include "remoting/base/test_rsa_key_pair.h" #include "remoting/jingle_glue/iq_sender.h" #include "remoting/jingle_glue/mock_objects.h" #include "testing/gmock/include/gmock/gmock.h" @@ -58,7 +58,8 @@ class HeartbeatSenderTest } virtual void SetUp() OVERRIDE { - ASSERT_TRUE(key_pair_.LoadFromString(kTestHostKeyPair)); + key_pair_ = RsaKeyPair::FromString(kTestRsaKeyPair); + ASSERT_TRUE(key_pair_); EXPECT_CALL(signal_strategy_, GetState()) .WillOnce(Return(SignalStrategy::DISCONNECTED)); @@ -70,7 +71,7 @@ class HeartbeatSenderTest .WillRepeatedly(Return(kTestJid)); heartbeat_sender_.reset(new HeartbeatSender( - this, kHostId, &signal_strategy_, &key_pair_, kTestBotJid)); + this, kHostId, &signal_strategy_, key_pair_, kTestBotJid)); } virtual void TearDown() OVERRIDE { @@ -84,7 +85,7 @@ class HeartbeatSenderTest MessageLoop message_loop_; MockSignalStrategy signal_strategy_; std::set<SignalStrategy::Listener*> signal_strategy_listeners_; - HostKeyPair key_pair_; + scoped_refptr<RsaKeyPair> key_pair_; scoped_ptr<HeartbeatSender> heartbeat_sender_; }; @@ -236,10 +237,10 @@ void HeartbeatSenderTest::ValidateHeartbeatStanza( ASSERT_TRUE(signature != NULL); EXPECT_TRUE(heartbeat_stanza->NextNamed(signature_tag) == NULL); - HostKeyPair key_pair; - key_pair.LoadFromString(kTestHostKeyPair); + scoped_refptr<RsaKeyPair> key_pair = RsaKeyPair::FromString(kTestRsaKeyPair); + ASSERT_TRUE(key_pair); std::string expected_signature = - key_pair.GetSignature(std::string(kTestJid) + ' ' + expectedSequenceId); + key_pair->SignMessage(std::string(kTestJid) + ' ' + expectedSequenceId); EXPECT_EQ(expected_signature, signature->BodyText()); } diff --git a/remoting/host/host_key_pair.h b/remoting/host/host_key_pair.h deleted file mode 100644 index f7aa651..0000000 --- a/remoting/host/host_key_pair.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef REMOTING_HOST_HOST_KEY_PAIR_H_ -#define REMOTING_HOST_HOST_KEY_PAIR_H_ - -#include <string> - -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" - -namespace crypto { -class RSAPrivateKey; -} // namespace base - -namespace remoting { - -class HostConfig; -class MutableHostConfig; - -class HostKeyPair { - public: - HostKeyPair(); - ~HostKeyPair(); - - void Generate(); - bool LoadFromString(const std::string& key_base64); - bool Load(const HostConfig& host_config); - void Save(MutableHostConfig* host_config); - - crypto::RSAPrivateKey* private_key() { return key_.get(); } - - std::string GetAsString() const; - std::string GetPublicKey() const; - std::string GetSignature(const std::string& message) const; - - // Make a new copy of private key. Caller will own the generated private key. - crypto::RSAPrivateKey* CopyPrivateKey() const; - - // Generates self-signed certificate using the key pair. Returns empty string - // if cert generation fails (e.g. it may happen when the system clock is off). - std::string GenerateCertificate() const; - - private: - scoped_ptr<crypto::RSAPrivateKey> key_; -}; - -} // namespace remoting - -#endif // REMOTING_HOST_HOST_KEY_PAIR_H_ diff --git a/remoting/host/host_key_pair_unittest.cc b/remoting/host/host_key_pair_unittest.cc deleted file mode 100644 index 2aa921c..0000000 --- a/remoting/host/host_key_pair_unittest.cc +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2012 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 <string> - -#include "base/files/scoped_temp_dir.h" -#include "base/memory/ref_counted.h" -#include "base/message_loop.h" -#include "base/message_loop_proxy.h" -#include "base/string_util.h" -#include "remoting/host/host_key_pair.h" -#include "remoting/host/json_host_config.h" -#include "remoting/host/test_key_pair.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace remoting { - -namespace { -const char kTestMessage[] = "Test Message"; - -// |kTestMessage| signed with the key from |kTestHostKeyPair|. -const char kExpectedSignature[] = -"LfUyXU2AiKM4rpWivUR3bLiQiRt1W3iIenNfJEB8RWyoEfnvSBoD52x8q9yFvtLFDEMPWyIrwM+N2" -"LuaWBKG1c0R7h+twBgvpExzZneJl+lbGMRx9ba8m/KAFrUWA/NRzOen2NHCuPybOEasgrPgGWBrmf" -"gDcvyW8QiGuKLopGj/4c5CQT4yE8JjsyU3Qqo2ZPK4neJYQhOmAlg+Q5dAPLpzWMj5HQyOVHJaSXZ" -"Y8vl/LiKvbdofYLeYNVKAE4q5mfpQMrsysPYpbxBV60AhFyrvtC040MFGcflKQRZNiZwMXVb7DclC" -"BPgvK7rI5Y0ERtVm+yNmH7vCivfyAnDUYA=="; -} // namespace - -class HostKeyPairTest : public testing::Test { - protected: - virtual void SetUp() { - ASSERT_TRUE(test_dir_.CreateUniqueTempDir()); - base::FilePath config_path = test_dir_.path().AppendASCII("test_config.json"); - config_.reset(new JsonHostConfig(config_path)); - } - - MessageLoop message_loop_; - base::ScopedTempDir test_dir_; - scoped_ptr<JsonHostConfig> config_; -}; - -TEST_F(HostKeyPairTest, SaveLoad) { - // Save a key to a config, then load it back, and verify that we - // generate the same signature with both keys. - HostKeyPair exported_key; - exported_key.LoadFromString(kTestHostKeyPair); - exported_key.Save(config_.get()); - - message_loop_.RunUntilIdle(); - - HostKeyPair imported_key; - imported_key.Load(*config_); - - ASSERT_EQ(exported_key.GetSignature(kTestMessage), - imported_key.GetSignature(kTestMessage)); -} - -TEST_F(HostKeyPairTest, Signatures) { - // Sign a message and check that we get expected signature. - HostKeyPair key_pair; - key_pair.LoadFromString(kTestHostKeyPair); - - std::string signature_base64 = key_pair.GetSignature(kTestMessage); - ASSERT_EQ(signature_base64, std::string(kExpectedSignature)); -} - -} // namespace remoting diff --git a/remoting/host/plugin/host_script_object.cc b/remoting/host/plugin/host_script_object.cc index 1346bce..63b8513 100644 --- a/remoting/host/plugin/host_script_object.cc +++ b/remoting/host/plugin/host_script_object.cc @@ -18,12 +18,12 @@ #include "net/base/net_util.h" #include "remoting/base/auth_token_util.h" #include "remoting/base/auto_thread.h" +#include "remoting/base/rsa_key_pair.h" #include "remoting/host/basic_desktop_environment.h" #include "remoting/host/chromoting_host.h" #include "remoting/host/chromoting_host_context.h" #include "remoting/host/host_config.h" #include "remoting/host/host_event_logger.h" -#include "remoting/host/host_key_pair.h" #include "remoting/host/host_secret.h" #include "remoting/host/host_status_observer.h" #include "remoting/host/it2me_host_user_interface.h" @@ -162,7 +162,7 @@ class HostNPScriptObject::It2MeImpl State state_; - HostKeyPair host_key_pair_; + scoped_refptr<RsaKeyPair> host_key_pair_; scoped_ptr<SignalStrategy> signal_strategy_; scoped_ptr<RegisterSupportHostRequest> register_request_; scoped_ptr<LogToServer> log_to_server_; @@ -344,7 +344,7 @@ void HostNPScriptObject::It2MeImpl::FinishConnect( // Generate a key pair for the Host to use. // TODO(wez): Move this to the worker thread. - host_key_pair_.Generate(); + host_key_pair_ = RsaKeyPair::Generate(); // Create XMPP connection. scoped_ptr<SignalStrategy> signal_strategy( @@ -355,7 +355,7 @@ void HostNPScriptObject::It2MeImpl::FinishConnect( // Request registration of the host for support. scoped_ptr<RegisterSupportHostRequest> register_request( new RegisterSupportHostRequest( - signal_strategy.get(), &host_key_pair_, directory_bot_jid_, + signal_strategy.get(), host_key_pair_, directory_bot_jid_, base::Bind(&It2MeImpl::OnReceivedSupportID, base::Unretained(this)))); @@ -642,7 +642,7 @@ void HostNPScriptObject::It2MeImpl::OnReceivedSupportID( std::string host_secret = GenerateSupportHostSecret(); std::string access_code = support_id + host_secret; - std::string local_certificate = host_key_pair_.GenerateCertificate(); + std::string local_certificate = host_key_pair_->GenerateCertificate(); if (local_certificate.empty()) { LOG(ERROR) << "Failed to generate host certificate."; SetState(kError); @@ -652,7 +652,7 @@ void HostNPScriptObject::It2MeImpl::OnReceivedSupportID( scoped_ptr<protocol::AuthenticatorFactory> factory( new protocol::It2MeHostAuthenticatorFactory( - local_certificate, *host_key_pair_.private_key(), access_code)); + local_certificate, host_key_pair_, access_code)); host_->SetAuthenticatorFactory(factory.Pass()); // Pass the Access Code to the script object before changing state. @@ -1448,10 +1448,9 @@ bool HostNPScriptObject::LocalizeStringWithSubstitution( } void HostNPScriptObject::DoGenerateKeyPair(const ScopedRefNPObject& callback) { - HostKeyPair key_pair; - key_pair.Generate(); - InvokeGenerateKeyPairCallback(callback, key_pair.GetAsString(), - key_pair.GetPublicKey()); + scoped_refptr<RsaKeyPair> key_pair = RsaKeyPair::Generate(); + InvokeGenerateKeyPairCallback(callback, key_pair->ToString(), + key_pair->GetPublicKey()); } void HostNPScriptObject::InvokeGenerateKeyPairCallback( diff --git a/remoting/host/plugin/host_script_object.h b/remoting/host/plugin/host_script_object.h index a8ec631..d8fd2c7 100644 --- a/remoting/host/plugin/host_script_object.h +++ b/remoting/host/plugin/host_script_object.h @@ -21,7 +21,6 @@ #include "base/time.h" #include "remoting/base/auto_thread_task_runner.h" #include "remoting/host/chromoting_host_context.h" -#include "remoting/host/host_key_pair.h" #include "remoting/host/log_to_server.h" #include "remoting/host/plugin/host_plugin_utils.h" #include "remoting/host/setup/daemon_controller.h" diff --git a/remoting/host/register_support_host_request.cc b/remoting/host/register_support_host_request.cc index b149851..388291d 100644 --- a/remoting/host/register_support_host_request.cc +++ b/remoting/host/register_support_host_request.cc @@ -36,7 +36,7 @@ const char kSupportIdLifetimeTag[] = "support-id-lifetime"; RegisterSupportHostRequest::RegisterSupportHostRequest( SignalStrategy* signal_strategy, - HostKeyPair* key_pair, + scoped_refptr<RsaKeyPair> key_pair, const std::string& directory_bot_jid, const RegisterCallback& callback) : signal_strategy_(signal_strategy), @@ -98,7 +98,7 @@ scoped_ptr<XmlElement> RegisterSupportHostRequest::CreateSignature( QName(kChromotingXmlNamespace, kSignatureTimeAttr), time_str); std::string message = jid + ' ' + time_str; - std::string signature(key_pair_->GetSignature(message)); + std::string signature(key_pair_->SignMessage(message)); signature_tag->AddText(signature); return signature_tag.Pass(); diff --git a/remoting/host/register_support_host_request.h b/remoting/host/register_support_host_request.h index fd9758c85..ab4d649 100644 --- a/remoting/host/register_support_host_request.h +++ b/remoting/host/register_support_host_request.h @@ -10,8 +10,8 @@ #include "base/callback.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "remoting/base/rsa_key_pair.h" #include "remoting/jingle_glue/signal_strategy.h" -#include "remoting/host/host_key_pair.h" #include "testing/gtest/include/gtest/gtest_prod.h" class MessageLoop; @@ -49,7 +49,7 @@ class RegisterSupportHostRequest : public SignalStrategy::Listener { // TODO(sergeyu): This class should have timeout for the bot // response. RegisterSupportHostRequest(SignalStrategy* signal_strategy, - HostKeyPair* key_pair, + scoped_refptr<RsaKeyPair> key_pair, const std::string& directory_bot_jid, const RegisterCallback& callback); virtual ~RegisterSupportHostRequest(); @@ -75,7 +75,7 @@ class RegisterSupportHostRequest : public SignalStrategy::Listener { bool success, const std::string& support_id, base::TimeDelta lifetime); SignalStrategy* signal_strategy_; - HostKeyPair* key_pair_; + scoped_refptr<RsaKeyPair> key_pair_; std::string directory_bot_jid_; RegisterCallback callback_; diff --git a/remoting/host/register_support_host_request_unittest.cc b/remoting/host/register_support_host_request_unittest.cc index 81b5c42..cd5da6e 100644 --- a/remoting/host/register_support_host_request_unittest.cc +++ b/remoting/host/register_support_host_request_unittest.cc @@ -10,9 +10,9 @@ #include "base/observer_list.h" #include "base/string_number_conversions.h" #include "remoting/base/constants.h" -#include "remoting/host/host_key_pair.h" +#include "remoting/base/rsa_key_pair.h" +#include "remoting/base/test_rsa_key_pair.h" #include "remoting/host/in_memory_host_config.h" -#include "remoting/host/test_key_pair.h" #include "remoting/jingle_glue/iq_sender.h" #include "remoting/jingle_glue/mock_objects.h" #include "testing/gmock/include/gmock/gmock.h" @@ -58,7 +58,8 @@ class RegisterSupportHostRequestTest : public testing::Test { public: protected: virtual void SetUp() { - ASSERT_TRUE(key_pair_.LoadFromString(kTestHostKeyPair)); + key_pair_ = RsaKeyPair::FromString(kTestRsaKeyPair); + ASSERT_TRUE(key_pair_); EXPECT_CALL(signal_strategy_, AddListener(NotNull())) .WillRepeatedly(AddListener(&signal_strategy_listeners_)); @@ -71,7 +72,7 @@ class RegisterSupportHostRequestTest : public testing::Test { MessageLoop message_loop_; MockSignalStrategy signal_strategy_; ObserverList<SignalStrategy::Listener, true> signal_strategy_listeners_; - HostKeyPair key_pair_; + scoped_refptr<RsaKeyPair> key_pair_; MockCallback callback_; }; @@ -80,7 +81,7 @@ TEST_F(RegisterSupportHostRequestTest, Send) { int64 start_time = static_cast<int64>(base::Time::Now().ToDoubleT()); scoped_ptr<RegisterSupportHostRequest> request( - new RegisterSupportHostRequest(&signal_strategy_, &key_pair_, + new RegisterSupportHostRequest(&signal_strategy_, key_pair_, kTestBotJid, base::Bind(&MockCallback::OnResponse, base::Unretained(&callback_)))); @@ -118,10 +119,11 @@ TEST_F(RegisterSupportHostRequestTest, Send) { EXPECT_LE(start_time, time); EXPECT_GE(now, time); - HostKeyPair key_pair; - key_pair.LoadFromString(kTestHostKeyPair); + scoped_refptr<RsaKeyPair> key_pair = RsaKeyPair::FromString(kTestRsaKeyPair); + ASSERT_TRUE(key_pair); + std::string expected_signature = - key_pair.GetSignature(std::string(kTestJid) + ' ' + time_str); + key_pair->SignMessage(std::string(kTestJid) + ' ' + time_str); EXPECT_EQ(expected_signature, signature->BodyText()); // Generate response and verify that callback is called. diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc index f5089b2..35289fa 100644 --- a/remoting/host/remoting_me2me_host.cc +++ b/remoting/host/remoting_me2me_host.cc @@ -285,7 +285,7 @@ class HostProcess std::string host_id_; protocol::SharedSecretHash host_secret_hash_; - HostKeyPair key_pair_; + scoped_refptr<RsaKeyPair> key_pair_; std::string oauth_refresh_token_; std::string serialized_config_; std::string xmpp_login_; @@ -511,7 +511,7 @@ void HostProcess::CreateAuthenticatorFactory() { if (state_ != HOST_STARTED) return; - std::string local_certificate = key_pair_.GenerateCertificate(); + std::string local_certificate = key_pair_->GenerateCertificate(); if (local_certificate.empty()) { LOG(ERROR) << "Failed to generate host certificate."; ShutdownHost(kInitializationFailed); @@ -520,7 +520,7 @@ void HostProcess::CreateAuthenticatorFactory() { scoped_ptr<protocol::AuthenticatorFactory> factory( new protocol::Me2MeHostAuthenticatorFactory( - local_certificate, *key_pair_.private_key(), host_secret_hash_)); + local_certificate, key_pair_, host_secret_hash_)); #if defined(OS_POSIX) // On Linux and Mac, perform a PAM authorization step after authentication. factory.reset(new PamAuthorizationFactory(factory.Pass())); @@ -688,7 +688,15 @@ bool HostProcess::ApplyConfig(scoped_ptr<JsonHostConfig> config) { return false; } - if (!key_pair_.Load(*config)) { + std::string key_base64; + if (!config->GetString(kPrivateKeyConfigPath, &key_base64)) { + LOG(ERROR) << "Private key couldn't be read from the config file."; + return false; + } + + key_pair_ = RsaKeyPair::FromString(key_base64); + if (!key_pair_) { + LOG(ERROR) << "Invalid private key in the config file."; return false; } @@ -942,7 +950,8 @@ void HostProcess::StartHost() { #endif heartbeat_sender_.reset(new HeartbeatSender( - this, host_id_, signal_strategy_.get(), &key_pair_, directory_bot_jid_)); + this, host_id_, signal_strategy_.get(), key_pair_, + directory_bot_jid_)); host_change_notification_listener_.reset(new HostChangeNotificationListener( this, host_id_, signal_strategy_.get(), directory_bot_jid_)); diff --git a/remoting/host/setup/host_starter.cc b/remoting/host/setup/host_starter.cc index 13cb685..90c4924 100644 --- a/remoting/host/setup/host_starter.cc +++ b/remoting/host/setup/host_starter.cc @@ -106,9 +106,9 @@ void HostStarter::OnGetUserInfoResponse(const std::string& user_email) { user_email_ = user_email; // Register the host. host_id_ = base::GenerateGUID(); - key_pair_.Generate(); + key_pair_ = RsaKeyPair::Generate(); service_client_->RegisterHost( - host_id_, host_name_, key_pair_.GetPublicKey(), access_token_, this); + host_id_, host_name_, key_pair_->GetPublicKey(), access_token_, this); } void HostStarter::OnHostRegistered() { @@ -124,7 +124,7 @@ void HostStarter::OnHostRegistered() { config->SetString("oauth_refresh_token", refresh_token_); config->SetString("host_id", host_id_); config->SetString("host_name", host_name_); - config->SetString("private_key", key_pair_.GetAsString()); + config->SetString("private_key", key_pair_->ToString()); config->SetString("host_secret_hash", host_secret_hash); daemon_controller_->SetConfigAndStart( config.Pass(), consent_to_data_collection_, diff --git a/remoting/host/setup/host_starter.h b/remoting/host/setup/host_starter.h index 9d83e4c..e743a75 100644 --- a/remoting/host/setup/host_starter.h +++ b/remoting/host/setup/host_starter.h @@ -9,7 +9,7 @@ #include "base/callback.h" #include "google_apis/gaia/gaia_oauth_client.h" -#include "remoting/host/host_key_pair.h" +#include "remoting/base/rsa_key_pair.h" #include "remoting/host/service_client.h" #include "remoting/host/setup/daemon_controller.h" #include "remoting/host/url_request_context.h" @@ -85,7 +85,7 @@ class HostStarter : public gaia::GaiaOAuthClient::Delegate, std::string refresh_token_; std::string access_token_; std::string user_email_; - remoting::HostKeyPair key_pair_; + scoped_refptr<remoting::RsaKeyPair> key_pair_; std::string host_id_; base::WeakPtrFactory<HostStarter> weak_ptr_factory_; diff --git a/remoting/protocol/authenticator_test_base.cc b/remoting/protocol/authenticator_test_base.cc index d79c227..5e2dac2 100644 --- a/remoting/protocol/authenticator_test_base.cc +++ b/remoting/protocol/authenticator_test_base.cc @@ -4,13 +4,14 @@ #include "remoting/protocol/authenticator_test_base.h" +#include "base/base64.h" #include "base/file_util.h" #include "base/files/file_path.h" #include "base/path_service.h" #include "base/test/test_timeouts.h" #include "base/timer.h" -#include "crypto/rsa_private_key.h" #include "net/base/test_data_directory.h" +#include "remoting/base/rsa_key_pair.h" #include "remoting/protocol/authenticator.h" #include "remoting/protocol/channel_authenticator.h" #include "remoting/protocol/fake_session.h" @@ -51,12 +52,10 @@ void AuthenticatorTestBase::SetUp() { base::FilePath key_path = certs_dir.AppendASCII("unittest.key.bin"); std::string key_string; ASSERT_TRUE(file_util::ReadFileToString(key_path, &key_string)); - std::vector<uint8> key_vector( - reinterpret_cast<const uint8*>(key_string.data()), - reinterpret_cast<const uint8*>(key_string.data() + - key_string.length())); - private_key_.reset( - crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_vector)); + std::string key_base64; + ASSERT_TRUE(base::Base64Encode(key_string, &key_base64)); + key_pair_ = RsaKeyPair::FromString(key_base64); + ASSERT_TRUE(key_pair_); } void AuthenticatorTestBase::RunAuthExchange() { diff --git a/remoting/protocol/authenticator_test_base.h b/remoting/protocol/authenticator_test_base.h index 4a43347..2fb4e75 100644 --- a/remoting/protocol/authenticator_test_base.h +++ b/remoting/protocol/authenticator_test_base.h @@ -7,20 +7,20 @@ #include <string> +#include "base/memory/ref_counted.h" #include "base/message_loop.h" #include "net/base/net_errors.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -namespace crypto { -class RSAPrivateKey; -} // namespace crypto - namespace net { class StreamSocket; } // namespace net namespace remoting { + +class RsaKeyPair; + namespace protocol { class Authenticator; @@ -53,7 +53,7 @@ class AuthenticatorTestBase : public testing::Test { MessageLoop message_loop_; - scoped_ptr<crypto::RSAPrivateKey> private_key_; + scoped_refptr<RsaKeyPair> key_pair_; std::string host_cert_; scoped_ptr<Authenticator> host_; scoped_ptr<Authenticator> client_; diff --git a/remoting/protocol/it2me_host_authenticator_factory.cc b/remoting/protocol/it2me_host_authenticator_factory.cc index cc8a0b5..83fa6b6 100644 --- a/remoting/protocol/it2me_host_authenticator_factory.cc +++ b/remoting/protocol/it2me_host_authenticator_factory.cc @@ -5,7 +5,7 @@ #include "remoting/protocol/it2me_host_authenticator_factory.h" #include "base/logging.h" -#include "crypto/rsa_private_key.h" +#include "remoting/base/rsa_key_pair.h" #include "remoting/protocol/negotiating_authenticator.h" namespace remoting { @@ -13,10 +13,10 @@ namespace protocol { It2MeHostAuthenticatorFactory::It2MeHostAuthenticatorFactory( const std::string& local_cert, - const crypto::RSAPrivateKey& local_private_key, + scoped_refptr<RsaKeyPair> key_pair, const std::string& shared_secret) : local_cert_(local_cert), - local_private_key_(local_private_key.Copy()), + key_pair_(key_pair), shared_secret_(shared_secret) { } @@ -28,7 +28,7 @@ scoped_ptr<Authenticator> It2MeHostAuthenticatorFactory::CreateAuthenticator( const std::string& remote_jid, const buzz::XmlElement* first_message) { return NegotiatingAuthenticator::CreateForHost( - local_cert_, *local_private_key_, shared_secret_, + local_cert_, key_pair_, shared_secret_, AuthenticationMethod::NONE); } diff --git a/remoting/protocol/it2me_host_authenticator_factory.h b/remoting/protocol/it2me_host_authenticator_factory.h index c526cbf..6683e33 100644 --- a/remoting/protocol/it2me_host_authenticator_factory.h +++ b/remoting/protocol/it2me_host_authenticator_factory.h @@ -9,14 +9,14 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "remoting/protocol/authenticator.h" -namespace crypto { -class RSAPrivateKey; -} // namespace crypto - namespace remoting { + +class RsaKeyPair; + namespace protocol { // It2MeHostAuthenticatorFactory implements AuthenticatorFactory and @@ -25,7 +25,7 @@ class It2MeHostAuthenticatorFactory : public AuthenticatorFactory { public: It2MeHostAuthenticatorFactory( const std::string& local_cert, - const crypto::RSAPrivateKey& local_private_key, + scoped_refptr<RsaKeyPair> key_pair, const std::string& shared_secret); virtual ~It2MeHostAuthenticatorFactory(); @@ -37,7 +37,7 @@ class It2MeHostAuthenticatorFactory : public AuthenticatorFactory { private: std::string local_cert_; - scoped_ptr<crypto::RSAPrivateKey> local_private_key_; + scoped_refptr<RsaKeyPair> key_pair_; std::string shared_secret_; DISALLOW_COPY_AND_ASSIGN(It2MeHostAuthenticatorFactory); diff --git a/remoting/protocol/me2me_host_authenticator_factory.cc b/remoting/protocol/me2me_host_authenticator_factory.cc index c871b6c..9a04d89 100644 --- a/remoting/protocol/me2me_host_authenticator_factory.cc +++ b/remoting/protocol/me2me_host_authenticator_factory.cc @@ -6,7 +6,7 @@ #include "base/base64.h" #include "base/string_util.h" -#include "crypto/rsa_private_key.h" +#include "remoting/base/rsa_key_pair.h" #include "remoting/protocol/channel_authenticator.h" #include "remoting/protocol/negotiating_authenticator.h" #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" @@ -60,10 +60,10 @@ class RejectingAuthenticator : public Authenticator { Me2MeHostAuthenticatorFactory::Me2MeHostAuthenticatorFactory( const std::string& local_cert, - const crypto::RSAPrivateKey& local_private_key, + scoped_refptr<RsaKeyPair> key_pair, const SharedSecretHash& shared_secret_hash) : local_cert_(local_cert), - local_private_key_(local_private_key.Copy()), + key_pair_(key_pair), shared_secret_hash_(shared_secret_hash) { } @@ -92,7 +92,7 @@ scoped_ptr<Authenticator> Me2MeHostAuthenticatorFactory::CreateAuthenticator( } return NegotiatingAuthenticator::CreateForHost( - local_cert_, *local_private_key_, shared_secret_hash_.value, + local_cert_, key_pair_, shared_secret_hash_.value, shared_secret_hash_.hash_function); } diff --git a/remoting/protocol/me2me_host_authenticator_factory.h b/remoting/protocol/me2me_host_authenticator_factory.h index 1a5acb1..e6375a2 100644 --- a/remoting/protocol/me2me_host_authenticator_factory.h +++ b/remoting/protocol/me2me_host_authenticator_factory.h @@ -9,23 +9,22 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "remoting/protocol/authentication_method.h" #include "remoting/protocol/authenticator.h" -namespace crypto { -class RSAPrivateKey; -} // namespace crypto - namespace remoting { + +class RsaKeyPair; + namespace protocol { class Me2MeHostAuthenticatorFactory : public AuthenticatorFactory { public: - // Doesn't take ownership of |local_private_key|. Me2MeHostAuthenticatorFactory( const std::string& local_cert, - const crypto::RSAPrivateKey& local_private_key, + scoped_refptr<RsaKeyPair> key_pair, const SharedSecretHash& shared_secret_hash); virtual ~Me2MeHostAuthenticatorFactory(); @@ -38,7 +37,7 @@ class Me2MeHostAuthenticatorFactory : public AuthenticatorFactory { private: std::string local_jid_prefix_; std::string local_cert_; - scoped_ptr<crypto::RSAPrivateKey> local_private_key_; + scoped_refptr<RsaKeyPair> key_pair_; SharedSecretHash shared_secret_hash_; DISALLOW_COPY_AND_ASSIGN(Me2MeHostAuthenticatorFactory); diff --git a/remoting/protocol/negotiating_authenticator.cc b/remoting/protocol/negotiating_authenticator.cc index ea4b4bc..7b794d2 100644 --- a/remoting/protocol/negotiating_authenticator.cc +++ b/remoting/protocol/negotiating_authenticator.cc @@ -8,9 +8,10 @@ #include <sstream> #include "base/bind.h" +#include "base/callback.h" #include "base/logging.h" #include "base/strings/string_split.h" -#include "crypto/rsa_private_key.h" +#include "remoting/base/rsa_key_pair.h" #include "remoting/protocol/channel_authenticator.h" #include "remoting/protocol/v2_authenticator.h" #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" @@ -56,13 +57,13 @@ scoped_ptr<Authenticator> NegotiatingAuthenticator::CreateForClient( // static scoped_ptr<Authenticator> NegotiatingAuthenticator::CreateForHost( const std::string& local_cert, - const crypto::RSAPrivateKey& local_private_key, + scoped_refptr<RsaKeyPair> key_pair, const std::string& shared_secret_hash, AuthenticationMethod::HashFunction hash_function) { scoped_ptr<NegotiatingAuthenticator> result( new NegotiatingAuthenticator(WAITING_MESSAGE)); result->local_cert_ = local_cert; - result->local_private_key_.reset(local_private_key.Copy()); + result->local_key_pair_ = key_pair; result->shared_secret_hash_ = shared_secret_hash; result->AddMethod(AuthenticationMethod::Spake2(hash_function)); @@ -70,11 +71,9 @@ scoped_ptr<Authenticator> NegotiatingAuthenticator::CreateForHost( return scoped_ptr<Authenticator>(result.Pass()); } - NegotiatingAuthenticator::NegotiatingAuthenticator( Authenticator::State initial_state) - : certificate_sent_(false), - current_method_(AuthenticationMethod::Invalid()), + : current_method_(AuthenticationMethod::Invalid()), state_(initial_state), rejection_reason_(INVALID_CREDENTIALS) { } @@ -226,20 +225,18 @@ NegotiatingAuthenticator::CreateChannelAuthenticator() const { } bool NegotiatingAuthenticator::is_host_side() const { - return local_private_key_.get() != NULL; + return local_key_pair_.get() != NULL; } void NegotiatingAuthenticator::CreateAuthenticator(State initial_state) { if (is_host_side()) { current_authenticator_ = V2Authenticator::CreateForHost( - local_cert_, *local_private_key_.get(), - shared_secret_hash_, initial_state); + local_cert_, local_key_pair_, shared_secret_hash_, initial_state); } else { current_authenticator_ = V2Authenticator::CreateForClient( AuthenticationMethod::ApplyHashFunction( current_method_.hash_function(), - authentication_tag_, shared_secret_), - initial_state); + authentication_tag_, shared_secret_), initial_state); } } diff --git a/remoting/protocol/negotiating_authenticator.h b/remoting/protocol/negotiating_authenticator.h index 61b471b..a87d543e 100644 --- a/remoting/protocol/negotiating_authenticator.h +++ b/remoting/protocol/negotiating_authenticator.h @@ -9,15 +9,15 @@ #include <vector> #include "base/basictypes.h" +#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "remoting/protocol/authenticator.h" #include "remoting/protocol/authentication_method.h" -namespace crypto { -class RSAPrivateKey; -} // namespace crypto - namespace remoting { + +class RsaKeyPair; + namespace protocol { class NegotiatingAuthenticator : public Authenticator { @@ -26,14 +26,16 @@ class NegotiatingAuthenticator : public Authenticator { static bool IsNegotiableMessage(const buzz::XmlElement* message); + // Creates a client authenticator for the given methods. static scoped_ptr<Authenticator> CreateForClient( const std::string& authentication_tag, const std::string& shared_secret, const std::vector<AuthenticationMethod>& methods); + // Creates a host authenticator, using a fixed shared secret/PIN hash. static scoped_ptr<Authenticator> CreateForHost( const std::string& local_cert, - const crypto::RSAPrivateKey& local_private_key, + scoped_refptr<RsaKeyPair> key_pair, const std::string& shared_secret_hash, AuthenticationMethod::HashFunction hash_function); @@ -57,12 +59,10 @@ class NegotiatingAuthenticator : public Authenticator { // Used only for host authenticators. std::string local_cert_; - scoped_ptr<crypto::RSAPrivateKey> local_private_key_; - bool certificate_sent_; + scoped_refptr<RsaKeyPair> local_key_pair_; std::string shared_secret_hash_; // Used only for client authenticators. - std::string remote_cert_; std::string authentication_tag_; std::string shared_secret_; diff --git a/remoting/protocol/negotiating_authenticator_unittest.cc b/remoting/protocol/negotiating_authenticator_unittest.cc index e62a8e3..73daf83 100644 --- a/remoting/protocol/negotiating_authenticator_unittest.cc +++ b/remoting/protocol/negotiating_authenticator_unittest.cc @@ -6,6 +6,7 @@ #include "base/bind.h" #include "net/base/net_errors.h" +#include "remoting/base/rsa_key_pair.h" #include "remoting/protocol/authenticator_test_base.h" #include "remoting/protocol/channel_authenticator.h" #include "remoting/protocol/connection_tester.h" @@ -48,7 +49,7 @@ class NegotiatingAuthenticatorTest : public AuthenticatorTestBase { std::string host_secret_hash = AuthenticationMethod::ApplyHashFunction( hash_function, kTestHostId, host_secret); host_ = NegotiatingAuthenticator::CreateForHost( - host_cert_, *private_key_, host_secret_hash, hash_function); + host_cert_, key_pair_, host_secret_hash, hash_function); std::vector<AuthenticationMethod> methods; methods.push_back(AuthenticationMethod::Spake2( diff --git a/remoting/protocol/ssl_hmac_channel_authenticator.cc b/remoting/protocol/ssl_hmac_channel_authenticator.cc index 2cfb3b4..6285d57 100644 --- a/remoting/protocol/ssl_hmac_channel_authenticator.cc +++ b/remoting/protocol/ssl_hmac_channel_authenticator.cc @@ -16,6 +16,7 @@ #include "net/socket/client_socket_factory.h" #include "net/socket/ssl_client_socket.h" #include "net/socket/ssl_server_socket.h" +#include "remoting/base/rsa_key_pair.h" #include "remoting/protocol/auth_util.h" namespace remoting { @@ -35,19 +36,18 @@ SslHmacChannelAuthenticator::CreateForClient( scoped_ptr<SslHmacChannelAuthenticator> SslHmacChannelAuthenticator::CreateForHost( const std::string& local_cert, - crypto::RSAPrivateKey* local_private_key, + scoped_refptr<RsaKeyPair> key_pair, const std::string& auth_key) { scoped_ptr<SslHmacChannelAuthenticator> result( new SslHmacChannelAuthenticator(auth_key)); result->local_cert_ = local_cert; - result->local_private_key_ = local_private_key; + result->local_key_pair_ = key_pair; return result.Pass(); } SslHmacChannelAuthenticator::SslHmacChannelAuthenticator( const std::string& auth_key) - : auth_key_(auth_key), - local_private_key_(NULL) { + : auth_key_(auth_key) { } SslHmacChannelAuthenticator::~SslHmacChannelAuthenticator() { @@ -73,7 +73,7 @@ void SslHmacChannelAuthenticator::SecureAndAuthenticate( net::SSLConfig ssl_config; net::SSLServerSocket* server_socket = net::CreateSSLServerSocket( - socket.release(), cert, local_private_key_, ssl_config); + socket.release(), cert, local_key_pair_->private_key(), ssl_config); socket_.reset(server_socket); result = server_socket->Handshake(base::Bind( @@ -113,7 +113,7 @@ void SslHmacChannelAuthenticator::SecureAndAuthenticate( } bool SslHmacChannelAuthenticator::is_ssl_server() { - return local_private_key_ != NULL; + return local_key_pair_.get() != NULL; } void SslHmacChannelAuthenticator::OnConnected(int result) { diff --git a/remoting/protocol/ssl_hmac_channel_authenticator.h b/remoting/protocol/ssl_hmac_channel_authenticator.h index 3ba6492..6f7440c 100644 --- a/remoting/protocol/ssl_hmac_channel_authenticator.h +++ b/remoting/protocol/ssl_hmac_channel_authenticator.h @@ -13,10 +13,6 @@ #include "base/threading/non_thread_safe.h" #include "remoting/protocol/channel_authenticator.h" -namespace crypto { -class RSAPrivateKey; -} // namespace crypto - namespace net { class CertVerifier; class DrainableIOBuffer; @@ -25,6 +21,9 @@ class SSLSocket; } // namespace net namespace remoting { + +class RsaKeyPair; + namespace protocol { // SslHmacChannelAuthenticator implements ChannelAuthenticator that @@ -51,7 +50,7 @@ class SslHmacChannelAuthenticator : public ChannelAuthenticator, static scoped_ptr<SslHmacChannelAuthenticator> CreateForHost( const std::string& local_cert, - crypto::RSAPrivateKey* local_private_key, + scoped_refptr<RsaKeyPair> key_pair, const std::string& auth_key); virtual ~SslHmacChannelAuthenticator(); @@ -85,7 +84,7 @@ class SslHmacChannelAuthenticator : public ChannelAuthenticator, // Used in the SERVER mode only. std::string local_cert_; - crypto::RSAPrivateKey* local_private_key_; + scoped_refptr<RsaKeyPair> local_key_pair_; // Used in the CLIENT mode only. std::string remote_cert_; diff --git a/remoting/protocol/ssl_hmac_channel_authenticator_unittest.cc b/remoting/protocol/ssl_hmac_channel_authenticator_unittest.cc index eb3d6ce..33e51fe 100644 --- a/remoting/protocol/ssl_hmac_channel_authenticator_unittest.cc +++ b/remoting/protocol/ssl_hmac_channel_authenticator_unittest.cc @@ -4,6 +4,7 @@ #include "remoting/protocol/ssl_hmac_channel_authenticator.h" +#include "base/base64.h" #include "base/bind.h" #include "base/file_util.h" #include "base/files/file_path.h" @@ -14,6 +15,7 @@ #include "crypto/rsa_private_key.h" #include "net/base/net_errors.h" #include "net/base/test_data_directory.h" +#include "remoting/base/rsa_key_pair.h" #include "remoting/protocol/connection_tester.h" #include "remoting/protocol/fake_session.h" #include "testing/gmock/include/gmock/gmock.h" @@ -61,12 +63,10 @@ class SslHmacChannelAuthenticatorTest : public testing::Test { base::FilePath key_path = certs_dir.AppendASCII("unittest.key.bin"); std::string key_string; ASSERT_TRUE(file_util::ReadFileToString(key_path, &key_string)); - std::vector<uint8> key_vector( - reinterpret_cast<const uint8*>(key_string.data()), - reinterpret_cast<const uint8*>(key_string.data() + - key_string.length())); - private_key_.reset( - crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_vector)); + std::string key_base64; + base::Base64Encode(key_string, &key_base64); + key_pair_ = RsaKeyPair::FromString(key_base64); + ASSERT_TRUE(key_pair_); } void RunChannelAuth(bool expected_fail) { @@ -122,7 +122,7 @@ class SslHmacChannelAuthenticatorTest : public testing::Test { MessageLoop message_loop_; - scoped_ptr<crypto::RSAPrivateKey> private_key_; + scoped_refptr<RsaKeyPair> key_pair_; std::string host_cert_; scoped_ptr<FakeSocket> client_fake_socket_; scoped_ptr<FakeSocket> host_fake_socket_; @@ -141,7 +141,7 @@ TEST_F(SslHmacChannelAuthenticatorTest, SuccessfulAuth) { client_auth_ = SslHmacChannelAuthenticator::CreateForClient( host_cert_, kTestSharedSecret); host_auth_ = SslHmacChannelAuthenticator::CreateForHost( - host_cert_, private_key_.get(), kTestSharedSecret); + host_cert_, key_pair_, kTestSharedSecret); RunChannelAuth(false); @@ -161,7 +161,7 @@ TEST_F(SslHmacChannelAuthenticatorTest, InvalidChannelSecret) { client_auth_ = SslHmacChannelAuthenticator::CreateForClient( host_cert_, kTestSharedSecretBad); host_auth_ = SslHmacChannelAuthenticator::CreateForHost( - host_cert_, private_key_.get(), kTestSharedSecret); + host_cert_, key_pair_, kTestSharedSecret); RunChannelAuth(true); diff --git a/remoting/protocol/v2_authenticator.cc b/remoting/protocol/v2_authenticator.cc index 3728a6a..80f7af3 100644 --- a/remoting/protocol/v2_authenticator.cc +++ b/remoting/protocol/v2_authenticator.cc @@ -6,8 +6,8 @@ #include "base/base64.h" #include "base/logging.h" -#include "crypto/rsa_private_key.h" #include "remoting/base/constants.h" +#include "remoting/base/rsa_key_pair.h" #include "remoting/protocol/ssl_hmac_channel_authenticator.h" #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" @@ -45,13 +45,13 @@ scoped_ptr<Authenticator> V2Authenticator::CreateForClient( // static scoped_ptr<Authenticator> V2Authenticator::CreateForHost( const std::string& local_cert, - const crypto::RSAPrivateKey& local_private_key, + scoped_refptr<RsaKeyPair> key_pair, const std::string& shared_secret, Authenticator::State initial_state) { scoped_ptr<V2Authenticator> result(new V2Authenticator( P224EncryptedKeyExchange::kPeerTypeServer, shared_secret, initial_state)); result->local_cert_ = local_cert; - result->local_private_key_.reset(local_private_key.Copy()); + result->local_key_pair_ = key_pair; return scoped_ptr<Authenticator>(result.Pass()); } @@ -193,7 +193,7 @@ V2Authenticator::CreateChannelAuthenticator() const { if (is_host_side()) { return scoped_ptr<ChannelAuthenticator>( SslHmacChannelAuthenticator::CreateForHost( - local_cert_, local_private_key_.get(), auth_key_).Pass()); + local_cert_, local_key_pair_, auth_key_).Pass()); } else { return scoped_ptr<ChannelAuthenticator>( SslHmacChannelAuthenticator::CreateForClient( @@ -202,7 +202,7 @@ V2Authenticator::CreateChannelAuthenticator() const { } bool V2Authenticator::is_host_side() const { - return local_private_key_.get() != NULL; + return local_key_pair_.get() != NULL; } } // namespace protocol diff --git a/remoting/protocol/v2_authenticator.h b/remoting/protocol/v2_authenticator.h index fdc86be..0675cb2 100644 --- a/remoting/protocol/v2_authenticator.h +++ b/remoting/protocol/v2_authenticator.h @@ -14,11 +14,10 @@ #include "crypto/p224_spake.h" #include "remoting/protocol/authenticator.h" -namespace crypto { -class RSAPrivateKey; -} // namespace crypto - namespace remoting { + +class RsaKeyPair; + namespace protocol { class V2Authenticator : public Authenticator { @@ -31,7 +30,7 @@ class V2Authenticator : public Authenticator { static scoped_ptr<Authenticator> CreateForHost( const std::string& local_cert, - const crypto::RSAPrivateKey& local_private_key, + scoped_refptr<RsaKeyPair> key_pair, const std::string& shared_secret, State initial_state); @@ -59,7 +58,7 @@ class V2Authenticator : public Authenticator { // Used only for host authenticators. std::string local_cert_; - scoped_ptr<crypto::RSAPrivateKey> local_private_key_; + scoped_refptr<RsaKeyPair> local_key_pair_; bool certificate_sent_; // Used only for client authenticators. diff --git a/remoting/protocol/v2_authenticator_unittest.cc b/remoting/protocol/v2_authenticator_unittest.cc index da3512e..9af517b 100644 --- a/remoting/protocol/v2_authenticator_unittest.cc +++ b/remoting/protocol/v2_authenticator_unittest.cc @@ -6,6 +6,7 @@ #include "base/bind.h" #include "net/base/net_errors.h" +#include "remoting/base/rsa_key_pair.h" #include "remoting/protocol/authenticator_test_base.h" #include "remoting/protocol/channel_authenticator.h" #include "remoting/protocol/connection_tester.h" @@ -41,7 +42,8 @@ class V2AuthenticatorTest : public AuthenticatorTestBase { void InitAuthenticators(const std::string& client_secret, const std::string& host_secret) { host_ = V2Authenticator::CreateForHost( - host_cert_, *private_key_, host_secret, Authenticator::WAITING_MESSAGE); + host_cert_, key_pair_, host_secret, + Authenticator::WAITING_MESSAGE); client_ = V2Authenticator::CreateForClient( client_secret, Authenticator::MESSAGE_READY); } diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index d0009f6..e1bad8f 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -360,8 +360,6 @@ 'host/host_config.cc', 'host/host_config.h', 'host/host_exit_codes.h', - 'host/host_key_pair.cc', - 'host/host_key_pair.h', 'host/host_port_allocator.cc', 'host/host_port_allocator.h', 'host/host_secret.cc', @@ -2226,6 +2224,8 @@ 'base/rate_counter.h', 'base/resources.cc', 'base/resources.h', + 'base/rsa_key_pair.cc', + 'base/rsa_key_pair.h', 'base/running_average.cc', 'base/running_average.h', 'base/socket_reader.cc', @@ -2492,6 +2492,8 @@ 'base/breakpad_win_unittest.cc', 'base/compound_buffer_unittest.cc', 'base/resources_unittest.cc', + 'base/rsa_key_pair_unittest.cc', + 'base/test_rsa_key_pair.h', 'base/typed_buffer_unittest.cc', 'base/util_unittest.cc', 'client/audio_player_unittest.cc', @@ -2524,7 +2526,6 @@ 'host/desktop_session_agent_win.cc', 'host/heartbeat_sender_unittest.cc', 'host/host_change_notification_listener_unittest.cc', - 'host/host_key_pair_unittest.cc', 'host/host_mock_objects.cc', 'host/host_mock_objects.h', 'host/host_status_monitor_fake.h', @@ -2545,7 +2546,6 @@ 'host/server_log_entry_unittest.cc', 'host/setup/oauth_helper_unittest.cc', 'host/setup/pin_validator_unittest.cc', - 'host/test_key_pair.h', 'host/video_scheduler_unittest.cc', 'host/win/rdp_client_unittest.cc', 'host/win/worker_process_launcher.cc', |