• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
OwnerKeyUtils()31 OwnerKeyUtils::OwnerKeyUtils() {}
32 
~OwnerKeyUtils()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.
Create()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 
OwnerKeyUtilsImpl()82 OwnerKeyUtilsImpl::OwnerKeyUtilsImpl() {}
83 
~OwnerKeyUtilsImpl()84 OwnerKeyUtilsImpl::~OwnerKeyUtilsImpl() {}
85 
ExportPublicKeyToFile(crypto::RSAPrivateKey * pair,const FilePath & key_file)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 
ImportPublicKey(const FilePath & key_file,std::vector<uint8> * output)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 
Verify(const std::string & data,const std::vector<uint8> signature,const std::vector<uint8> public_key)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 
Sign(const std::string & data,std::vector<uint8> * OUT_signature,crypto::RSAPrivateKey * key)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 
FindPrivateKey(const std::vector<uint8> & key)161 crypto::RSAPrivateKey* OwnerKeyUtilsImpl::FindPrivateKey(
162     const std::vector<uint8>& key) {
163   return crypto::RSAPrivateKey::FindFromPublicKeyInfo(key);
164 }
165 
GetOwnerKeyFilePath()166 FilePath OwnerKeyUtilsImpl::GetOwnerKeyFilePath() {
167   return FilePath(OwnerKeyUtilsImpl::kOwnerKeyFile);
168 }
169 
170 }  // namespace chromeos
171