shill: Infrastucture for encrypting/decrypting/scrambling store values.

This adds a CryptoProvider that registers and provides access to different
prioritized crypto modules (currently DES-CBC and ROT47). Use the provider in
KeyFileStore to provide an API for getting and setting crypted string values.

BUG=chromium-os:16963
TEST=unit tests

Change-Id: I492516890eb3f527758d354cd8890088cb99dea4
Reviewed-on: http://gerrit.chromium.org/gerrit/3395
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: Chris Masone <cmasone@chromium.org>
diff --git a/key_file_store_unittest.cc b/key_file_store_unittest.cc
index 9e52558..a206060 100644
--- a/key_file_store_unittest.cc
+++ b/key_file_store_unittest.cc
@@ -16,6 +16,11 @@
 
 namespace shill {
 
+namespace {
+const char kPlainText[] = "This is a test!";
+const char kROT47Text[] = "rot47:%9:D :D 2 E6DEP";
+}  // namespace {}
+
 class KeyFileStoreTest : public Test {
  public:
   KeyFileStoreTest() : store_(&glib_) {}
@@ -55,6 +60,7 @@
 
   ASSERT_TRUE(store_.Open());
   EXPECT_TRUE(store_.key_file_);
+  EXPECT_EQ(1, store_.crypto_.cryptos_.size());
   ASSERT_TRUE(store_.Close());
   EXPECT_FALSE(store_.key_file_);
 
@@ -288,6 +294,35 @@
             ReadKeyFile());
 }
 
+TEST_F(KeyFileStoreTest, GetCryptedString) {
+  static const char kGroup[] = "crypto-group";
+  static const char kKey[] = "secret";
+  WriteKeyFile(base::StringPrintf("[%s]\n"
+                                  "%s=%s\n",
+                                  kGroup, kKey, kROT47Text));
+  ASSERT_TRUE(store_.Open());
+  string value;
+  EXPECT_TRUE(store_.GetCryptedString(kGroup, kKey, &value));
+  EXPECT_EQ(kPlainText, value);
+  EXPECT_FALSE(store_.GetCryptedString("something-else", kKey, &value));
+  EXPECT_FALSE(store_.GetCryptedString(kGroup, "non-secret", &value));
+  EXPECT_TRUE(store_.GetCryptedString(kGroup, kKey, NULL));
+  ASSERT_TRUE(store_.Close());
+}
+
+TEST_F(KeyFileStoreTest, SetCryptedString) {
+  static const char kGroup[] = "crypted-string-group";
+  static const char kKey[] = "test-string";
+  ASSERT_TRUE(store_.Open());
+  ASSERT_TRUE(store_.SetCryptedString(kGroup, kKey, kPlainText));
+  ASSERT_TRUE(store_.Close());
+  EXPECT_EQ(base::StringPrintf("\n"
+                               "[%s]\n"
+                               "%s=%s\n",
+                               kGroup, kKey, kROT47Text),
+            ReadKeyFile());
+}
+
 TEST_F(KeyFileStoreTest, Combo) {
   static const char kGroupA[] = "square";
   static const char kGroupB[] = "circle";