Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(311)

Side by Side Diff: chrome/browser/chromeos/login/owner_key_utils.cc

Issue 3017020: Refactoring key generation and export util code to make mocking possible. (Closed)
Patch Set: address comments per davemoore Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/login/owner_manager.h" 5 #include "chrome/browser/chromeos/login/owner_key_utils.h"
6 6
7 #include <keyhi.h> // SECKEY_CreateSubjectPublicKeyInfo() 7 #include <keyhi.h> // SECKEY_CreateSubjectPublicKeyInfo()
8 #include <pk11pub.h> 8 #include <pk11pub.h>
9 #include <prerror.h> // PR_GetError() 9 #include <prerror.h> // PR_GetError()
10 #include <secder.h> // DER_Encode() 10 #include <secder.h> // DER_Encode()
11 #include <secmod.h> 11 #include <secmod.h>
12 12
13 #include <limits> 13 #include <limits>
14 14
15 #include "base/file_path.h" 15 #include "base/file_path.h"
16 #include "base/file_util.h" 16 #include "base/file_util.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/nss_util_internal.h" 18 #include "base/nss_util_internal.h"
19 #include "base/nss_util.h" 19 #include "base/nss_util.h"
20 #include "base/scoped_ptr.h" 20 #include "base/scoped_ptr.h"
21 #include "base/string_util.h" 21 #include "base/string_util.h"
22 22
23 // static 23 // static
24 const char OwnerManager::kOwnerKeyFile[] = "/var/lib/whitelist/owner.key"; 24 OwnerKeyUtils::Factory* OwnerKeyUtils::factory_ = NULL;
25
26 class OwnerKeyUtilsImpl : public OwnerKeyUtils {
27 public:
28 OwnerKeyUtilsImpl();
29 virtual ~OwnerKeyUtilsImpl();
30
31 bool GenerateKeyPair(SECKEYPrivateKey** private_key_out,
32 SECKEYPublicKey** public_key_out);
33
34 bool ExportPublicKey(SECKEYPublicKey* key, const FilePath& key_file);
35
36 SECKEYPublicKey* ImportPublicKey(const FilePath& key_file);
37
38 private:
39 // Fills in fields of |key_der| with DER encoded data from a file at
40 // |key_file|. The caller must pass in a pointer to an actual SECItem
41 // struct for |key_der|. |key_der->data| should be initialized to NULL
42 // and |key_der->len| should be set to 0.
43 //
44 // Upon success, data is stored in key_der->data, and the caller takes
45 // ownership. Returns false on error.
46 //
47 // To free the data, call
48 // SECITEM_FreeItem(key_der, PR_FALSE);
49 static bool ReadDERFromFile(const FilePath& key_file, SECItem* key_der);
50
51 // The place outside the owner's encrypted home directory where her
52 // key will live.
53 static const char kOwnerKeyFile[];
54
55 // Key generation parameters.
56 static const uint32 kKeyGenMechanism; // used by PK11_GenerateKeyPair()
57 static const unsigned long kExponent;
58 static const int kKeySizeInBits;
59
60 DISALLOW_COPY_AND_ASSIGN(OwnerKeyUtilsImpl);
61 };
62
63 OwnerKeyUtils::OwnerKeyUtils() {}
64
65 OwnerKeyUtils::~OwnerKeyUtils() {}
66
67 OwnerKeyUtils* OwnerKeyUtils::Create() {
68 if (!factory_)
69 return new OwnerKeyUtilsImpl();
70 else
71 return factory_->CreateOwnerKeyUtils();
72 }
73
74 // static
75 const char OwnerKeyUtilsImpl::kOwnerKeyFile[] = "/var/lib/whitelist/owner.key";
25 76
26 // We're generating and using 2048-bit RSA keys. 77 // We're generating and using 2048-bit RSA keys.
27 // static 78 // static
28 const uint32 OwnerManager::kKeyGenMechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; 79 const uint32 OwnerKeyUtilsImpl::kKeyGenMechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
29 // static 80 // static
30 const unsigned long OwnerManager::kExponent = 65537UL; 81 const unsigned long OwnerKeyUtilsImpl::kExponent = 65537UL;
31 // static 82 // static
32 const int OwnerManager::kKeySizeInBits = 2048; 83 const int OwnerKeyUtilsImpl::kKeySizeInBits = 2048;
33 84
34 // static 85 OwnerKeyUtilsImpl::OwnerKeyUtilsImpl(){}
35 bool OwnerManager::GenerateKeyPair(SECKEYPrivateKey** private_key_out, 86
36 SECKEYPublicKey** public_key_out) { 87 OwnerKeyUtilsImpl::~OwnerKeyUtilsImpl() {}
88
89 bool OwnerKeyUtilsImpl::GenerateKeyPair(SECKEYPrivateKey** private_key_out,
90 SECKEYPublicKey** public_key_out) {
37 DCHECK(private_key_out); 91 DCHECK(private_key_out);
38 DCHECK(public_key_out); 92 DCHECK(public_key_out);
39 93
40 *private_key_out = NULL; 94 *private_key_out = NULL;
41 *public_key_out = NULL; 95 *public_key_out = NULL;
42 96
43 // Temporary structures used for generating the result 97 // Temporary structures used for generating the result
44 // in the right format. 98 // in the right format.
45 PK11SlotInfo* slot = NULL; 99 PK11SlotInfo* slot = NULL;
46 PK11RSAGenParams rsa_key_gen_params; 100 PK11RSAGenParams rsa_key_gen_params;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 } else { 162 } else {
109 LOG(INFO) << "Owner key generation succeeded!"; 163 LOG(INFO) << "Owner key generation succeeded!";
110 } 164 }
111 if (slot != NULL) { 165 if (slot != NULL) {
112 PK11_FreeSlot(slot); 166 PK11_FreeSlot(slot);
113 } 167 }
114 168
115 return is_success; 169 return is_success;
116 } 170 }
117 171
118 // static 172 bool OwnerKeyUtilsImpl::ExportPublicKey(SECKEYPublicKey* key,
119 bool OwnerManager::ExportPublicKey(SECKEYPublicKey* key, 173 const FilePath& key_file) {
120 const FilePath& key_file) {
121 DCHECK(key); 174 DCHECK(key);
122 SECItem* der; 175 SECItem* der;
123 bool ok = false; 176 bool ok = false;
124 int safe_file_size = 0; 177 int safe_file_size = 0;
125 178
126 // Instead of exporting/importing the key directly, I'm actually 179 // Instead of exporting/importing the key directly, I'm actually
127 // going to use a SubjectPublicKeyInfo. The reason is because NSS 180 // going to use a SubjectPublicKeyInfo. The reason is because NSS
128 // exports functions that encode/decode these kinds of structures, while 181 // exports functions that encode/decode these kinds of structures, while
129 // it does not export the ones that deal directly with public keys. 182 // it does not export the ones that deal directly with public keys.
130 der = SECKEY_EncodeDERSubjectPublicKeyInfo(key); 183 der = SECKEY_EncodeDERSubjectPublicKeyInfo(key);
131 if (!der) { 184 if (!der) {
132 LOG(ERROR) << "Could not encode public key for export!"; 185 LOG(ERROR) << "Could not encode public key for export!";
133 return false; 186 return false;
134 } 187 }
135 188
136 if (der->len > static_cast<uint>(INT_MAX)) { 189 if (der->len > static_cast<uint>(INT_MAX)) {
137 LOG(ERROR) << "key is too big! " << der->len; 190 LOG(ERROR) << "key is too big! " << der->len;
138 } else { 191 } else {
139 safe_file_size = static_cast<int>(der->len); 192 safe_file_size = static_cast<int>(der->len);
140 193
141 ok = (safe_file_size == 194 ok = (safe_file_size ==
142 file_util::WriteFile(key_file, 195 file_util::WriteFile(key_file,
143 reinterpret_cast<char*>(der->data), 196 reinterpret_cast<char*>(der->data),
144 der->len)); 197 der->len));
145 } 198 }
146 SECITEM_FreeItem(der, PR_TRUE); 199 SECITEM_FreeItem(der, PR_TRUE);
147 return ok; 200 return ok;
148 } 201 }
149 202
150 // static 203 SECKEYPublicKey* OwnerKeyUtilsImpl::ImportPublicKey(const FilePath& key_file) {
151 SECKEYPublicKey* OwnerManager::ImportPublicKey(const FilePath& key_file) {
152 SECItem key_der; 204 SECItem key_der;
153 205
154 if (!ReadDERFromFile(key_file, &key_der)) { 206 if (!ReadDERFromFile(key_file, &key_der)) {
155 PLOG(ERROR) << "Could not read in key from " << key_file.value() << ":"; 207 PLOG(ERROR) << "Could not read in key from " << key_file.value() << ":";
156 return NULL; 208 return NULL;
157 } 209 }
158 210
159 // See the comment in ExportPublicKey() for why I wrote a 211 // See the comment in ExportPublicKey() for why I wrote a
160 // SubjectPublicKeyInfo to disk instead of a key. 212 // SubjectPublicKeyInfo to disk instead of a key.
161 CERTSubjectPublicKeyInfo* spki = 213 CERTSubjectPublicKeyInfo* spki =
162 SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der); 214 SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der);
163 if (!spki) { 215 if (!spki) {
164 LOG(ERROR) << "Could not decode key info: " << PR_GetError(); 216 LOG(ERROR) << "Could not decode key info: " << PR_GetError();
217 SECITEM_FreeItem(&key_der, PR_FALSE);
165 return NULL; 218 return NULL;
166 } 219 }
167 220
168 SECKEYPublicKey *public_key = SECKEY_ExtractPublicKey(spki); 221 SECKEYPublicKey *public_key = SECKEY_ExtractPublicKey(spki);
169 SECKEY_DestroySubjectPublicKeyInfo(spki); 222 SECKEY_DestroySubjectPublicKeyInfo(spki);
223 SECITEM_FreeItem(&key_der, PR_FALSE);
170 return public_key; 224 return public_key;
171 } 225 }
172 226
173 // static 227 // static
174 bool OwnerManager::ReadDERFromFile(const FilePath& key_file, 228 bool OwnerKeyUtilsImpl::ReadDERFromFile(const FilePath& key_file,
175 SECItem* key_der) { 229 SECItem* key_der) {
176 // I'd use NSS' SECU_ReadDERFromFile() here, but the SECU_* functions are 230 // I'd use NSS' SECU_ReadDERFromFile() here, but the SECU_* functions are
177 // considered internal to the NSS command line utils. 231 // considered internal to the NSS command line utils.
178 // This code is lifted, in spirit, from the implementation of that function. 232 // This code is lifted, in spirit, from the implementation of that function.
179 DCHECK(key_der) << "Don't pass NULL for |key_der|"; 233 DCHECK(key_der) << "Don't pass NULL for |key_der|";
180 234
181 // Get the file size (must fit in a 32 bit int for NSS). 235 // Get the file size (must fit in a 32 bit int for NSS).
182 int64 file_size; 236 int64 file_size;
183 if (!file_util::GetFileSize(key_file, &file_size)) { 237 if (!file_util::GetFileSize(key_file, &file_size)) {
184 LOG(ERROR) << "Could not get size of " << key_file.value(); 238 LOG(ERROR) << "Could not get size of " << key_file.value();
185 return false; 239 return false;
(...skipping 18 matching lines...) Expand all
204 safe_file_size); 258 safe_file_size);
205 259
206 if (data_read != safe_file_size) { 260 if (data_read != safe_file_size) {
207 LOG(ERROR) << "Read the wrong amount of data from the DER encoded key! " 261 LOG(ERROR) << "Read the wrong amount of data from the DER encoded key! "
208 << data_read; 262 << data_read;
209 SECITEM_FreeItem(key_der, PR_FALSE); 263 SECITEM_FreeItem(key_der, PR_FALSE);
210 return false; 264 return false;
211 } 265 }
212 return true; 266 return true;
213 } 267 }
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/login/owner_key_utils.h ('k') | chrome/browser/chromeos/login/owner_key_utils_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698