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