Home | History | Annotate | Download | only in login
      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 "chrome/browser/chromeos/login/owner_key_utils.h"
      6 
      7 #include <limits>
      8 
      9 #include "base/file_path.h"
     10 #include "base/file_util.h"
     11 #include "base/logging.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/string_util.h"
     14 #include "crypto/rsa_private_key.h"
     15 #include "crypto/signature_creator.h"
     16 #include "crypto/signature_verifier.h"
     17 #include "chrome/browser/chromeos/cros/cros_library.h"
     18 #include "chrome/browser/chromeos/cros/login_library.h"
     19 #include "chrome/common/extensions/extension_constants.h"
     20 
     21 using extension_misc::kSignatureAlgorithm;
     22 
     23 namespace chromeos {
     24 
     25 ///////////////////////////////////////////////////////////////////////////
     26 // OwnerKeyUtils
     27 
     28 // static
     29 OwnerKeyUtils::Factory* OwnerKeyUtils::factory_ = NULL;
     30 
     31 OwnerKeyUtils::OwnerKeyUtils() {}
     32 
     33 OwnerKeyUtils::~OwnerKeyUtils() {}
     34 
     35 ///////////////////////////////////////////////////////////////////////////
     36 // OwnerKeyUtilsImpl
     37 
     38 class OwnerKeyUtilsImpl : public OwnerKeyUtils {
     39  public:
     40   OwnerKeyUtilsImpl();
     41 
     42   bool ImportPublicKey(const FilePath& key_file,
     43                        std::vector<uint8>* output);
     44 
     45   bool Verify(const std::string& data,
     46               const std::vector<uint8> signature,
     47               const std::vector<uint8> public_key);
     48 
     49   bool Sign(const std::string& data,
     50             std::vector<uint8>* OUT_signature,
     51             crypto::RSAPrivateKey* key);
     52 
     53   crypto::RSAPrivateKey* FindPrivateKey(const std::vector<uint8>& key);
     54 
     55   FilePath GetOwnerKeyFilePath();
     56 
     57  protected:
     58   virtual ~OwnerKeyUtilsImpl();
     59 
     60   bool ExportPublicKeyToFile(crypto::RSAPrivateKey* pair,
     61                              const FilePath& key_file);
     62 
     63  private:
     64   // The file outside the owner's encrypted home directory where her
     65   // key will live.
     66   static const char kOwnerKeyFile[];
     67 
     68   DISALLOW_COPY_AND_ASSIGN(OwnerKeyUtilsImpl);
     69 };
     70 
     71 // Defined here, instead of up above, because we need OwnerKeyUtilsImpl.
     72 OwnerKeyUtils* OwnerKeyUtils::Create() {
     73   if (!factory_)
     74     return new OwnerKeyUtilsImpl();
     75   else
     76     return factory_->CreateOwnerKeyUtils();
     77 }
     78 
     79 // static
     80 const char OwnerKeyUtilsImpl::kOwnerKeyFile[] = "/var/lib/whitelist/owner.key";
     81 
     82 OwnerKeyUtilsImpl::OwnerKeyUtilsImpl() {}
     83 
     84 OwnerKeyUtilsImpl::~OwnerKeyUtilsImpl() {}
     85 
     86 bool OwnerKeyUtilsImpl::ExportPublicKeyToFile(crypto::RSAPrivateKey* pair,
     87                                               const FilePath& key_file) {
     88   DCHECK(pair);
     89   bool ok = false;
     90   int safe_file_size = 0;
     91 
     92   std::vector<uint8> to_export;
     93   if (!pair->ExportPublicKey(&to_export)) {
     94     LOG(ERROR) << "Formatting key for export failed!";
     95     return false;
     96   }
     97 
     98   if (to_export.size() > static_cast<uint>(INT_MAX)) {
     99     LOG(ERROR) << "key is too big! " << to_export.size();
    100   } else {
    101     safe_file_size = static_cast<int>(to_export.size());
    102 
    103     ok = (safe_file_size ==
    104           file_util::WriteFile(key_file,
    105                                reinterpret_cast<char*>(&to_export.front()),
    106                                safe_file_size));
    107   }
    108   return ok;
    109 }
    110 
    111 bool OwnerKeyUtilsImpl::ImportPublicKey(const FilePath& key_file,
    112                                         std::vector<uint8>* output) {
    113   // Get the file size (must fit in a 32 bit int for NSS).
    114   int64 file_size;
    115   if (!file_util::GetFileSize(key_file, &file_size)) {
    116     LOG(ERROR) << "Could not get size of " << key_file.value();
    117     return false;
    118   }
    119   if (file_size > static_cast<int64>(std::numeric_limits<int>::max())) {
    120     LOG(ERROR) << key_file.value() << "is "
    121                << file_size << "bytes!!!  Too big!";
    122     return false;
    123   }
    124   int32 safe_file_size = static_cast<int32>(file_size);
    125 
    126   output->resize(safe_file_size);
    127   // Get the key data off of disk
    128   int data_read = file_util::ReadFile(key_file,
    129                                       reinterpret_cast<char*>(&(output->at(0))),
    130                                       safe_file_size);
    131   return data_read == safe_file_size;
    132 }
    133 
    134 bool OwnerKeyUtilsImpl::Verify(const std::string& data,
    135                                const std::vector<uint8> signature,
    136                                const std::vector<uint8> public_key) {
    137   crypto::SignatureVerifier verifier;
    138   if (!verifier.VerifyInit(kSignatureAlgorithm, sizeof(kSignatureAlgorithm),
    139                            &signature[0], signature.size(),
    140                            &public_key[0], public_key.size())) {
    141     return false;
    142   }
    143 
    144   verifier.VerifyUpdate(reinterpret_cast<const uint8*>(data.c_str()),
    145                         data.length());
    146   return (verifier.VerifyFinal());
    147 }
    148 
    149 bool OwnerKeyUtilsImpl::Sign(const std::string& data,
    150                              std::vector<uint8>* OUT_signature,
    151                              crypto::RSAPrivateKey* key) {
    152   scoped_ptr<crypto::SignatureCreator> signer(
    153       crypto::SignatureCreator::Create(key));
    154   if (!signer->Update(reinterpret_cast<const uint8*>(data.c_str()),
    155                       data.length())) {
    156     return false;
    157   }
    158   return signer->Final(OUT_signature);
    159 }
    160 
    161 crypto::RSAPrivateKey* OwnerKeyUtilsImpl::FindPrivateKey(
    162     const std::vector<uint8>& key) {
    163   return crypto::RSAPrivateKey::FindFromPublicKeyInfo(key);
    164 }
    165 
    166 FilePath OwnerKeyUtilsImpl::GetOwnerKeyFilePath() {
    167   return FilePath(OwnerKeyUtilsImpl::kOwnerKeyFile);
    168 }
    169 
    170 }  // namespace chromeos
    171