crypto_provider.cc revision a0ddf46e466bd4ba3d20952f0a6988c680c1af14
192e6561671667edc1cfa2517ece57f9f38a51fe5Darin Petkov// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
286964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov// Use of this source code is governed by a BSD-style license that can be
386964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov// found in the LICENSE file.
486964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov
586964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov#include "shill/crypto_provider.h"
686964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov
786964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov#include <base/memory/scoped_ptr.h>
8a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan#include <base/strings/string_util.h>
986964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov
1086964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov#include "shill/crypto_des_cbc.h"
1186964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov#include "shill/crypto_rot47.h"
12b691efd71561246065eae3cdd73a96ca1b8a528dChristopher Wiley#include "shill/logging.h"
1386964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov
1486964e0bae1a38c6817243959026603b4b8c69b7Darin Petkovusing std::string;
1586964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov
1686964e0bae1a38c6817243959026603b4b8c69b7Darin Petkovnamespace shill {
1786964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov
1886964e0bae1a38c6817243959026603b4b8c69b7Darin Petkovconst char CryptoProvider::kKeyMatterFile[] = "/var/lib/whitelist/owner.key";
1986964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov
2086964e0bae1a38c6817243959026603b4b8c69b7Darin PetkovCryptoProvider::CryptoProvider(GLib *glib)
2186964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov    : glib_(glib),
2286964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov      key_matter_file_(kKeyMatterFile) {}
2386964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov
2486964e0bae1a38c6817243959026603b4b8c69b7Darin Petkovvoid CryptoProvider::Init() {
255ad1606ad8b3f74b2b7960a3003a2d1ca75d52b8Paul Stewart  cryptos_.clear();
2686964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov
2786964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov  // Register the crypto modules in priority order -- highest priority first.
2886964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov  scoped_ptr<CryptoDESCBC> des_cbc(new CryptoDESCBC(glib_));
2986964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov  if (des_cbc->LoadKeyMatter(key_matter_file_)) {
3086964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov    cryptos_.push_back(des_cbc.release());
3186964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov  }
3286964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov  cryptos_.push_back(new CryptoROT47());
3386964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov}
3486964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov
3586964e0bae1a38c6817243959026603b4b8c69b7Darin Petkovstring CryptoProvider::Encrypt(const string &plaintext) {
3686964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov  for (Cryptos::iterator it = cryptos_.begin(); it != cryptos_.end(); ++it) {
3786964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov    CryptoInterface *crypto = *it;
3886964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov    string ciphertext;
3986964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov    if (crypto->Encrypt(plaintext, &ciphertext)) {
4086964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov      const string prefix = crypto->GetID() + ":";
4186964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov      return prefix + ciphertext;
4286964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov    }
4386964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov  }
4486964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov  LOG(WARNING) << "Unable to encrypt text, returning as is.";
4586964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov  return plaintext;
4686964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov}
4786964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov
4886964e0bae1a38c6817243959026603b4b8c69b7Darin Petkovstring CryptoProvider::Decrypt(const string &ciphertext) {
4986964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov  for (Cryptos::iterator it = cryptos_.begin(); it != cryptos_.end(); ++it) {
5086964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov    CryptoInterface *crypto = *it;
5186964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov    const string prefix = crypto->GetID() + ":";
5286964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov    if (StartsWithASCII(ciphertext, prefix, true)) {
5386964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov      string to_decrypt = ciphertext;
5486964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov      to_decrypt.erase(0, prefix.size());
5586964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov      string plaintext;
5692e6561671667edc1cfa2517ece57f9f38a51fe5Darin Petkov      if (!crypto->Decrypt(to_decrypt, &plaintext)) {
5792e6561671667edc1cfa2517ece57f9f38a51fe5Darin Petkov        LOG(WARNING) << "Crypto module " << crypto->GetID()
5892e6561671667edc1cfa2517ece57f9f38a51fe5Darin Petkov                     << " failed to decrypt.";
5992e6561671667edc1cfa2517ece57f9f38a51fe5Darin Petkov      }
6086964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov      return plaintext;
6186964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov    }
6286964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov  }
6386964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov  LOG(WARNING) << "Unable to decrypt text, returning as is.";
6486964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov  return ciphertext;
6586964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov}
6686964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov
6786964e0bae1a38c6817243959026603b4b8c69b7Darin Petkov}  // namespace shill
68